!function(g,I){if("object"==typeof exports&&"object"==typeof module)module.exports=I();else if("function"==typeof define&&define.amd)define([],I);else{var n=I();for(var t in n)("object"==typeof exports?exports:g)[t]=n[t]}}(window,(function(){return function(g){var I={};function n(t){if(I[t])return I[t].exports;var e=I[t]={i:t,l:!1,exports:{}};return g[t].call(e.exports,e,e.exports,n),e.l=!0,e.exports}return n.m=g,n.c=I,n.d=function(g,I,t){n.o(g,I)||Object.defineProperty(g,I,{enumerable:!0,get:t})},n.r=function(g){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(g,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(g,"__esModule",{value:!0})},n.t=function(g,I){if(1&I&&(g=n(g)),8&I)return g;if(4&I&&"object"==typeof g&&g&&g.__esModule)return g;var t=Object.create(null);if(n.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:g}),2&I&&"string"!=typeof g)for(var e in g)n.d(t,e,function(I){return g[I]}.bind(null,e));return t},n.n=function(g){var I=g&&g.__esModule?function(){return g.default}:function(){return g};return n.d(I,"a",I),I},n.o=function(g,I){return Object.prototype.hasOwnProperty.call(g,I)},n.p="",n(n.s=96)}([function(module,__webpack_exports__,__webpack_require__){"use strict";eval('// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, "contains", function() { return /* reexport */ esm_contains; });\n__webpack_require__.d(__webpack_exports__, "includes", function() { return /* reexport */ esm_contains; });\n__webpack_require__.d(__webpack_exports__, "difference", function() { return /* reexport */ esm_difference; });\n__webpack_require__.d(__webpack_exports__, "find", function() { return /* reexport */ esm_find; });\n__webpack_require__.d(__webpack_exports__, "findIndex", function() { return /* reexport */ find_index; });\n__webpack_require__.d(__webpack_exports__, "firstValue", function() { return /* reexport */ first_value; });\n__webpack_require__.d(__webpack_exports__, "flatten", function() { return /* reexport */ esm_flatten; });\n__webpack_require__.d(__webpack_exports__, "flattenDeep", function() { return /* reexport */ flatten_deep; });\n__webpack_require__.d(__webpack_exports__, "getRange", function() { return /* reexport */ get_range; });\n__webpack_require__.d(__webpack_exports__, "pull", function() { return /* reexport */ esm_pull; });\n__webpack_require__.d(__webpack_exports__, "pullAt", function() { return /* reexport */ pull_at; });\n__webpack_require__.d(__webpack_exports__, "reduce", function() { return /* reexport */ esm_reduce; });\n__webpack_require__.d(__webpack_exports__, "remove", function() { return /* reexport */ esm_remove; });\n__webpack_require__.d(__webpack_exports__, "sortBy", function() { return /* reexport */ sort_by; });\n__webpack_require__.d(__webpack_exports__, "union", function() { return /* reexport */ esm_union; });\n__webpack_require__.d(__webpack_exports__, "uniq", function() { return /* reexport */ uniq; });\n__webpack_require__.d(__webpack_exports__, "valuesOfKey", function() { return /* reexport */ values_of_key; });\n__webpack_require__.d(__webpack_exports__, "head", function() { return /* reexport */ head; });\n__webpack_require__.d(__webpack_exports__, "last", function() { return /* reexport */ last_last; });\n__webpack_require__.d(__webpack_exports__, "startsWith", function() { return /* reexport */ starts_with; });\n__webpack_require__.d(__webpack_exports__, "endsWith", function() { return /* reexport */ ends_with; });\n__webpack_require__.d(__webpack_exports__, "filter", function() { return /* reexport */ esm_filter; });\n__webpack_require__.d(__webpack_exports__, "every", function() { return /* reexport */ esm_every; });\n__webpack_require__.d(__webpack_exports__, "some", function() { return /* reexport */ esm_some; });\n__webpack_require__.d(__webpack_exports__, "group", function() { return /* reexport */ group; });\n__webpack_require__.d(__webpack_exports__, "groupBy", function() { return /* reexport */ group_by; });\n__webpack_require__.d(__webpack_exports__, "groupToMap", function() { return /* reexport */ groupToMap; });\n__webpack_require__.d(__webpack_exports__, "getWrapBehavior", function() { return /* reexport */ get_wrap_behavior; });\n__webpack_require__.d(__webpack_exports__, "wrapBehavior", function() { return /* reexport */ wrap_behavior; });\n__webpack_require__.d(__webpack_exports__, "number2color", function() { return /* reexport */ number2color; });\n__webpack_require__.d(__webpack_exports__, "parseRadius", function() { return /* reexport */ parse_radius; });\n__webpack_require__.d(__webpack_exports__, "clamp", function() { return /* reexport */ esm_clamp; });\n__webpack_require__.d(__webpack_exports__, "fixedBase", function() { return /* reexport */ fixed_base; });\n__webpack_require__.d(__webpack_exports__, "isDecimal", function() { return /* reexport */ is_decimal; });\n__webpack_require__.d(__webpack_exports__, "isEven", function() { return /* reexport */ is_even; });\n__webpack_require__.d(__webpack_exports__, "isInteger", function() { return /* reexport */ is_integer; });\n__webpack_require__.d(__webpack_exports__, "isNegative", function() { return /* reexport */ is_negative; });\n__webpack_require__.d(__webpack_exports__, "isNumberEqual", function() { return /* reexport */ isNumberEqual; });\n__webpack_require__.d(__webpack_exports__, "isOdd", function() { return /* reexport */ is_odd; });\n__webpack_require__.d(__webpack_exports__, "isPositive", function() { return /* reexport */ is_positive; });\n__webpack_require__.d(__webpack_exports__, "max", function() { return /* reexport */ esm_max; });\n__webpack_require__.d(__webpack_exports__, "maxBy", function() { return /* reexport */ max_by; });\n__webpack_require__.d(__webpack_exports__, "min", function() { return /* reexport */ esm_min; });\n__webpack_require__.d(__webpack_exports__, "minBy", function() { return /* reexport */ min_by; });\n__webpack_require__.d(__webpack_exports__, "mod", function() { return /* reexport */ esm_mod; });\n__webpack_require__.d(__webpack_exports__, "toDegree", function() { return /* reexport */ to_degree; });\n__webpack_require__.d(__webpack_exports__, "toInteger", function() { return /* reexport */ to_integer; });\n__webpack_require__.d(__webpack_exports__, "toRadian", function() { return /* reexport */ to_radian; });\n__webpack_require__.d(__webpack_exports__, "forIn", function() { return /* reexport */ for_in; });\n__webpack_require__.d(__webpack_exports__, "has", function() { return /* reexport */ has; });\n__webpack_require__.d(__webpack_exports__, "hasKey", function() { return /* reexport */ has_key; });\n__webpack_require__.d(__webpack_exports__, "hasValue", function() { return /* reexport */ has_value; });\n__webpack_require__.d(__webpack_exports__, "keys", function() { return /* reexport */ esm_keys; });\n__webpack_require__.d(__webpack_exports__, "isMatch", function() { return /* reexport */ is_match; });\n__webpack_require__.d(__webpack_exports__, "values", function() { return /* reexport */ esm_values; });\n__webpack_require__.d(__webpack_exports__, "lowerCase", function() { return /* reexport */ lower_case; });\n__webpack_require__.d(__webpack_exports__, "lowerFirst", function() { return /* reexport */ lower_first; });\n__webpack_require__.d(__webpack_exports__, "substitute", function() { return /* reexport */ esm_substitute; });\n__webpack_require__.d(__webpack_exports__, "upperCase", function() { return /* reexport */ upper_case; });\n__webpack_require__.d(__webpack_exports__, "upperFirst", function() { return /* reexport */ upper_first; });\n__webpack_require__.d(__webpack_exports__, "getType", function() { return /* reexport */ get_type; });\n__webpack_require__.d(__webpack_exports__, "isArguments", function() { return /* reexport */ is_arguments; });\n__webpack_require__.d(__webpack_exports__, "isArray", function() { return /* reexport */ is_array; });\n__webpack_require__.d(__webpack_exports__, "isArrayLike", function() { return /* reexport */ is_array_like; });\n__webpack_require__.d(__webpack_exports__, "isBoolean", function() { return /* reexport */ is_boolean; });\n__webpack_require__.d(__webpack_exports__, "isDate", function() { return /* reexport */ is_date; });\n__webpack_require__.d(__webpack_exports__, "isError", function() { return /* reexport */ is_error; });\n__webpack_require__.d(__webpack_exports__, "isFunction", function() { return /* reexport */ is_function; });\n__webpack_require__.d(__webpack_exports__, "isFinite", function() { return /* reexport */ is_finite; });\n__webpack_require__.d(__webpack_exports__, "isNil", function() { return /* reexport */ is_nil; });\n__webpack_require__.d(__webpack_exports__, "isNull", function() { return /* reexport */ is_null; });\n__webpack_require__.d(__webpack_exports__, "isNumber", function() { return /* reexport */ is_number; });\n__webpack_require__.d(__webpack_exports__, "isObject", function() { return /* reexport */ is_object; });\n__webpack_require__.d(__webpack_exports__, "isObjectLike", function() { return /* reexport */ is_object_like; });\n__webpack_require__.d(__webpack_exports__, "isPlainObject", function() { return /* reexport */ is_plain_object; });\n__webpack_require__.d(__webpack_exports__, "isPrototype", function() { return /* reexport */ is_prototype; });\n__webpack_require__.d(__webpack_exports__, "isRegExp", function() { return /* reexport */ is_reg_exp; });\n__webpack_require__.d(__webpack_exports__, "isString", function() { return /* reexport */ is_string; });\n__webpack_require__.d(__webpack_exports__, "isType", function() { return /* reexport */ is_type; });\n__webpack_require__.d(__webpack_exports__, "isUndefined", function() { return /* reexport */ is_undefined; });\n__webpack_require__.d(__webpack_exports__, "isElement", function() { return /* reexport */ is_element; });\n__webpack_require__.d(__webpack_exports__, "requestAnimationFrame", function() { return /* reexport */ requestAnimationFrame; });\n__webpack_require__.d(__webpack_exports__, "clearAnimationFrame", function() { return /* reexport */ cancelAnimationFrame; });\n__webpack_require__.d(__webpack_exports__, "augment", function() { return /* reexport */ esm_augment; });\n__webpack_require__.d(__webpack_exports__, "clone", function() { return /* reexport */ esm_clone; });\n__webpack_require__.d(__webpack_exports__, "debounce", function() { return /* reexport */ esm_debounce; });\n__webpack_require__.d(__webpack_exports__, "memoize", function() { return /* reexport */ memoize; });\n__webpack_require__.d(__webpack_exports__, "deepMix", function() { return /* reexport */ deep_mix; });\n__webpack_require__.d(__webpack_exports__, "each", function() { return /* reexport */ esm_each; });\n__webpack_require__.d(__webpack_exports__, "extend", function() { return /* reexport */ esm_extend; });\n__webpack_require__.d(__webpack_exports__, "indexOf", function() { return /* reexport */ index_of; });\n__webpack_require__.d(__webpack_exports__, "isEmpty", function() { return /* reexport */ is_empty; });\n__webpack_require__.d(__webpack_exports__, "isEqual", function() { return /* reexport */ is_equal; });\n__webpack_require__.d(__webpack_exports__, "isEqualWith", function() { return /* reexport */ is_equal_with; });\n__webpack_require__.d(__webpack_exports__, "map", function() { return /* reexport */ esm_map; });\n__webpack_require__.d(__webpack_exports__, "mapValues", function() { return /* reexport */ map_values; });\n__webpack_require__.d(__webpack_exports__, "mix", function() { return /* reexport */ mix; });\n__webpack_require__.d(__webpack_exports__, "assign", function() { return /* reexport */ mix; });\n__webpack_require__.d(__webpack_exports__, "get", function() { return /* reexport */ get; });\n__webpack_require__.d(__webpack_exports__, "set", function() { return /* reexport */ set; });\n__webpack_require__.d(__webpack_exports__, "pick", function() { return /* reexport */ pick; });\n__webpack_require__.d(__webpack_exports__, "omit", function() { return /* reexport */ omit; });\n__webpack_require__.d(__webpack_exports__, "throttle", function() { return /* reexport */ throttle; });\n__webpack_require__.d(__webpack_exports__, "toArray", function() { return /* reexport */ to_array; });\n__webpack_require__.d(__webpack_exports__, "toString", function() { return /* reexport */ to_string; });\n__webpack_require__.d(__webpack_exports__, "uniqueId", function() { return /* reexport */ unique_id; });\n__webpack_require__.d(__webpack_exports__, "noop", function() { return /* reexport */ noop; });\n__webpack_require__.d(__webpack_exports__, "identity", function() { return /* reexport */ esm_identity; });\n__webpack_require__.d(__webpack_exports__, "size", function() { return /* reexport */ size; });\n__webpack_require__.d(__webpack_exports__, "measureTextWidth", function() { return /* reexport */ measure_text_width; });\n__webpack_require__.d(__webpack_exports__, "getEllipsisText", function() { return /* reexport */ get_ellipsis_text; });\n__webpack_require__.d(__webpack_exports__, "Cache", function() { return /* reexport */ cache; });\n\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-array-like.js\nvar isArrayLike = function (value) {\n /**\n * isArrayLike([1, 2, 3]) => true\n * isArrayLike(document.body.children) => true\n * isArrayLike(\'abc\') => true\n * isArrayLike(Function) => false\n */\n return value !== null && typeof value !== \'function\' && isFinite(value.length);\n};\n/* harmony default export */ var is_array_like = (isArrayLike);\n//# sourceMappingURL=is-array-like.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/contains.js\n\nvar contains = function (arr, value) {\n if (!is_array_like(arr)) {\n return false;\n }\n return arr.indexOf(value) > -1;\n};\n/* harmony default export */ var esm_contains = (contains);\n//# sourceMappingURL=contains.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/filter.js\n\nvar filter = function (arr, func) {\n if (!is_array_like(arr)) {\n return arr;\n }\n var result = [];\n for (var index = 0; index < arr.length; index++) {\n var value = arr[index];\n if (func(value, index)) {\n result.push(value);\n }\n }\n return result;\n};\n/* harmony default export */ var esm_filter = (filter);\n//# sourceMappingURL=filter.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/difference.js\n\n\n/**\n * Flattens `array` a single level deep.\n *\n * @param {Array} arr The array to inspect.\n * @param {Array} values The values to exclude.\n * @return {Array} Returns the new array of filtered values.\n * @example\n * difference([2, 1], [2, 3]); // => [1]\n */\nvar difference = function (arr, values) {\n if (values === void 0) { values = []; }\n return esm_filter(arr, function (value) { return !esm_contains(values, value); });\n};\n/* harmony default export */ var esm_difference = (difference);\n//# sourceMappingURL=difference.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-type.js\nvar is_type_toString = {}.toString;\nvar isType = function (value, type) { return is_type_toString.call(value) === \'[object \' + type + \']\'; };\n/* harmony default export */ var is_type = (isType);\n//# sourceMappingURL=is-type.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-function.js\n/**\n * 是否为函数\n * @param {*} fn 对象\n * @return {Boolean} 是否函数\n */\n\n/* harmony default export */ var is_function = (function (value) {\n return is_type(value, \'Function\');\n});\n//# sourceMappingURL=is-function.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-nil.js\n// isFinite,\nvar isNil = function (value) {\n /**\n * isNil(null) => true\n * isNil() => true\n */\n return value === null || value === undefined;\n};\n/* harmony default export */ var is_nil = (isNil);\n//# sourceMappingURL=is-nil.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-array.js\n\n/* harmony default export */ var is_array = (function (value) {\n return Array.isArray ?\n Array.isArray(value) :\n is_type(value, \'Array\');\n});\n//# sourceMappingURL=is-array.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-object.js\n/* harmony default export */ var is_object = (function (value) {\n /**\n * isObject({}) => true\n * isObject([1, 2, 3]) => true\n * isObject(Function) => true\n * isObject(null) => false\n */\n var type = typeof value;\n return value !== null && type === \'object\' || type === \'function\';\n});\n//# sourceMappingURL=is-object.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/each.js\n\n\nfunction each(elements, func) {\n if (!elements) {\n return;\n }\n var rst;\n if (is_array(elements)) {\n for (var i = 0, len = elements.length; i < len; i++) {\n rst = func(elements[i], i);\n if (rst === false) {\n break;\n }\n }\n }\n else if (is_object(elements)) {\n for (var k in elements) {\n if (elements.hasOwnProperty(k)) {\n rst = func(elements[k], k);\n if (rst === false) {\n break;\n }\n }\n }\n }\n}\n/* harmony default export */ var esm_each = (each);\n//# sourceMappingURL=each.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/keys.js\n\n\nvar keys_keys = Object.keys ? function (obj) { return Object.keys(obj); } : function (obj) {\n var result = [];\n esm_each(obj, function (value, key) {\n if (!(is_function(obj) && key === \'prototype\')) {\n result.push(key);\n }\n });\n return result;\n};\n/* harmony default export */ var esm_keys = (keys_keys);\n//# sourceMappingURL=keys.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-match.js\n\n\nfunction isMatch(obj, attrs) {\n var _keys = esm_keys(attrs);\n var length = _keys.length;\n if (is_nil(obj))\n return !length;\n for (var i = 0; i < length; i += 1) {\n var key = _keys[i];\n if (attrs[key] !== obj[key] || !(key in obj)) {\n return false;\n }\n }\n return true;\n}\n/* harmony default export */ var is_match = (isMatch);\n//# sourceMappingURL=is-match.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-object-like.js\nvar isObjectLike = function (value) {\n /**\n * isObjectLike({}) => true\n * isObjectLike([1, 2, 3]) => true\n * isObjectLike(Function) => false\n * isObjectLike(null) => false\n */\n return typeof value === \'object\' && value !== null;\n};\n/* harmony default export */ var is_object_like = (isObjectLike);\n//# sourceMappingURL=is-object-like.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-plain-object.js\n\n\nvar isPlainObject = function (value) {\n /**\n * isObjectLike(new Foo) => false\n * isObjectLike([1, 2, 3]) => false\n * isObjectLike({ x: 0, y: 0 }) => true\n * isObjectLike(Object.create(null)) => true\n */\n if (!is_object_like(value) || !is_type(value, \'Object\')) {\n return false;\n }\n if (Object.getPrototypeOf(value) === null) {\n return true;\n }\n var proto = value;\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n return Object.getPrototypeOf(value) === proto;\n};\n/* harmony default export */ var is_plain_object = (isPlainObject);\n//# sourceMappingURL=is-plain-object.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/find.js\n\n\n\n\nfunction find(arr, predicate) {\n if (!is_array(arr))\n return null;\n var _predicate;\n if (is_function(predicate)) {\n _predicate = predicate;\n }\n if (is_plain_object(predicate)) {\n _predicate = function (a) { return is_match(a, predicate); };\n }\n if (_predicate) {\n for (var i = 0; i < arr.length; i += 1) {\n if (_predicate(arr[i])) {\n return arr[i];\n }\n }\n }\n return null;\n}\n/* harmony default export */ var esm_find = (find);\n//# sourceMappingURL=find.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/find-index.js\nfunction findIndex(arr, predicate, fromIndex) {\n if (fromIndex === void 0) { fromIndex = 0; }\n for (var i = fromIndex; i < arr.length; i++) {\n if (predicate(arr[i], i)) {\n // 找到终止循环\n return i;\n }\n }\n return -1;\n}\n/* harmony default export */ var find_index = (findIndex);\n//# sourceMappingURL=find-index.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/first-value.js\n\n\nvar firstValue = function (data, name) {\n var rst = null;\n for (var i = 0; i < data.length; i++) {\n var obj = data[i];\n var value = obj[name];\n if (!is_nil(value)) {\n if (is_array(value)) {\n rst = value[0]; // todo 这里是否应该使用递归,调用 firstValue @绝云\n }\n else {\n rst = value;\n }\n break;\n }\n }\n return rst;\n};\n/* harmony default export */ var first_value = (firstValue);\n//# sourceMappingURL=first-value.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/flatten.js\n\n/**\n * Flattens `array` a single level deep.\n *\n * @param {Array} arr The array to flatten.\n * @return {Array} Returns the new flattened array.\n * @example\n *\n * flatten([1, [2, [3, [4]], 5]]); // => [1, 2, [3, [4]], 5]\n */\nvar flatten = function (arr) {\n if (!is_array(arr)) {\n return [];\n }\n var rst = [];\n for (var i = 0; i < arr.length; i++) {\n rst = rst.concat(arr[i]);\n }\n return rst;\n};\n/* harmony default export */ var esm_flatten = (flatten);\n//# sourceMappingURL=flatten.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/flatten-deep.js\n\n/**\n * Flattens `array` a single level deep.\n *\n * @param {Array} arr The array to flatten.\n * @param {Array} result The array to return.\n * @return {Array} Returns the new flattened array.\n * @example\n *\n * flattenDeep([1, [2, [3, [4]], 5]]); // => [1, 2, 3, 4, 5]\n */\nvar flattenDeep = function (arr, result) {\n if (result === void 0) { result = []; }\n if (!is_array(arr)) {\n result.push(arr);\n }\n else {\n for (var i = 0; i < arr.length; i += 1) {\n flattenDeep(arr[i], result);\n }\n }\n return result;\n};\n/* harmony default export */ var flatten_deep = (flattenDeep);\n//# sourceMappingURL=flatten-deep.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/max.js\n\n/**\n * @param {Array} arr The array to iterate over.\n * @return {*} Returns the maximum value.\n * @example\n *\n * max([1, 2]);\n * // => 2\n *\n * max([]);\n * // => undefined\n *\n * const data = new Array(1250010).fill(1).map((d,idx) => idx);\n *\n * max(data);\n * // => 1250010\n * // Math.max(...data) will encounter "Maximum call stack size exceeded" error\n */\n/* harmony default export */ var esm_max = (function (arr) {\n if (!is_array(arr)) {\n return undefined;\n }\n return arr.reduce(function (prev, curr) {\n return Math.max(prev, curr);\n }, arr[0]);\n});\n//# sourceMappingURL=max.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/min.js\n\n/**\n * @param {Array} arr The array to iterate over.\n * @return {*} Returns the minimum value.\n * @example\n *\n * min([1, 2]);\n * // => 1\n *\n * min([]);\n * // => undefined\n *\n * const data = new Array(1250010).fill(1).map((d,idx) => idx);\n *\n * min(data);\n * // => 1250010\n * // Math.min(...data) will encounter "Maximum call stack size exceeded" error\n */\n/* harmony default export */ var esm_min = (function (arr) {\n if (!is_array(arr)) {\n return undefined;\n }\n return arr.reduce(function (prev, curr) {\n return Math.min(prev, curr);\n }, arr[0]);\n});\n//# sourceMappingURL=min.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/get-range.js\n\n\n\nvar getRange = function (values) {\n // 存在 NaN 时,min,max 判定会出问题\n var filterValues = values.filter(function (v) { return !isNaN(v); });\n if (!filterValues.length) {\n // 如果没有数值则直接返回0\n return {\n min: 0,\n max: 0,\n };\n }\n if (is_array(values[0])) {\n var tmp = [];\n for (var i = 0; i < values.length; i++) {\n tmp = tmp.concat(values[i]);\n }\n filterValues = tmp;\n }\n var max = esm_max(filterValues);\n var min = esm_min(filterValues);\n return {\n min: min,\n max: max,\n };\n};\n/* harmony default export */ var get_range = (getRange);\n//# sourceMappingURL=get-range.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/pull.js\nvar arrPrototype = Array.prototype;\nvar splice = arrPrototype.splice;\nvar indexOf = arrPrototype.indexOf;\nvar pull = function (arr) {\n var values = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n values[_i - 1] = arguments[_i];\n }\n for (var i = 0; i < values.length; i++) {\n var value = values[i];\n var fromIndex = -1;\n while ((fromIndex = indexOf.call(arr, value)) > -1) {\n splice.call(arr, fromIndex, 1);\n }\n }\n return arr;\n};\n/* harmony default export */ var esm_pull = (pull);\n//# sourceMappingURL=pull.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/pull-at.js\n\nvar pull_at_splice = Array.prototype.splice;\nvar pull_at_pullAt = function pullAt(arr, indexes) {\n if (!is_array_like(arr)) {\n return [];\n }\n var length = arr ? indexes.length : 0;\n var last = length - 1;\n while (length--) {\n var previous = void 0;\n var index = indexes[length];\n if (length === last || index !== previous) {\n previous = index;\n pull_at_splice.call(arr, index, 1);\n }\n }\n return arr;\n};\n/* harmony default export */ var pull_at = (pull_at_pullAt);\n//# sourceMappingURL=pull-at.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/reduce.js\n\n\n\nvar reduce = function (arr, fn, init) {\n if (!is_array(arr) && !is_plain_object(arr)) {\n return arr;\n }\n var result = init;\n esm_each(arr, function (data, i) {\n result = fn(result, data, i);\n });\n return result;\n};\n/* harmony default export */ var esm_reduce = (reduce);\n//# sourceMappingURL=reduce.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/remove.js\n\n\nvar remove = function (arr, predicate) {\n /**\n * const arr = [1, 2, 3, 4]\n * const evens = remove(arr, n => n % 2 == 0)\n * console.log(arr) // => [1, 3]\n * console.log(evens) // => [2, 4]\n */\n var result = [];\n if (!is_array_like(arr)) {\n return result;\n }\n var i = -1;\n var indexes = [];\n var length = arr.length;\n while (++i < length) {\n var value = arr[i];\n if (predicate(value, i, arr)) {\n result.push(value);\n indexes.push(i);\n }\n }\n pull_at(arr, indexes);\n return result;\n};\n/* harmony default export */ var esm_remove = (remove);\n//# sourceMappingURL=remove.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-string.js\n\n/* harmony default export */ var is_string = (function (str) {\n return is_type(str, \'String\');\n});\n//# sourceMappingURL=is-string.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/sort-by.js\n\n\n\nfunction sortBy(arr, key) {\n var comparer;\n if (is_function(key)) {\n comparer = function (a, b) { return key(a) - key(b); };\n }\n else {\n var keys_1 = [];\n if (is_string(key)) {\n keys_1.push(key);\n }\n else if (is_array(key)) {\n keys_1 = key;\n }\n comparer = function (a, b) {\n for (var i = 0; i < keys_1.length; i += 1) {\n var prop = keys_1[i];\n if (a[prop] > b[prop]) {\n return 1;\n }\n if (a[prop] < b[prop]) {\n return -1;\n }\n }\n return 0;\n };\n }\n arr.sort(comparer);\n return arr;\n}\n/* harmony default export */ var sort_by = (sortBy);\n//# sourceMappingURL=sort-by.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/uniq.js\nfunction uniq(arr, cache) {\n if (cache === void 0) { cache = new Map(); }\n var r = [];\n if (Array.isArray(arr)) {\n for (var i = 0, len = arr.length; i < len; i++) {\n var item = arr[i];\n // 加一个 cache,提升性能\n if (!cache.has(item)) {\n r.push(item);\n cache.set(item, true);\n }\n }\n }\n return r;\n}\n//# sourceMappingURL=uniq.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/union.js\n\nvar union = function () {\n var sources = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n sources[_i] = arguments[_i];\n }\n return uniq([].concat.apply([], sources));\n};\n/* harmony default export */ var esm_union = (union);\n//# sourceMappingURL=union.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/values-of-key.js\n\n\n/* harmony default export */ var values_of_key = (function (data, name) {\n var rst = [];\n var tmpMap = {};\n for (var i = 0; i < data.length; i++) {\n var obj = data[i];\n var value = obj[name];\n if (!is_nil(value)) {\n // flatten\n if (!is_array(value)) {\n value = [value];\n }\n for (var j = 0; j < value.length; j++) {\n var val = value[j];\n // unique\n if (!tmpMap[val]) {\n rst.push(val);\n tmpMap[val] = true;\n }\n }\n }\n }\n return rst;\n});\n//# sourceMappingURL=values-of-key.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/head.js\n\nfunction head(o) {\n if (is_array_like(o)) {\n return o[0];\n }\n return undefined;\n}\n//# sourceMappingURL=head.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/last.js\n\nfunction last_last(o) {\n if (is_array_like(o)) {\n var arr = o;\n return arr[arr.length - 1];\n }\n return undefined;\n}\n//# sourceMappingURL=last.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/starts-with.js\n\n\nfunction startsWith(arr, e) {\n return (is_array(arr) || is_string(arr)) ? arr[0] === e : false;\n}\n/* harmony default export */ var starts_with = (startsWith);\n//# sourceMappingURL=starts-with.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/ends-with.js\n\n\nfunction endsWith(arr, e) {\n return (is_array(arr) || is_string(arr)) ? arr[arr.length - 1] === e : false;\n}\n/* harmony default export */ var ends_with = (endsWith);\n//# sourceMappingURL=ends-with.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/every.js\n/**\n * 只要有一个不满足条件就返回 false\n * @param arr\n * @param func\n */\nvar every = function (arr, func) {\n for (var i = 0; i < arr.length; i++) {\n if (!func(arr[i], i))\n return false;\n }\n return true;\n};\n/* harmony default export */ var esm_every = (every);\n//# sourceMappingURL=every.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/some.js\n/**\n * 只要有一个满足条件就返回 true\n * @param arr\n * @param func\n */\nvar some = function (arr, func) {\n for (var i = 0; i < arr.length; i++) {\n if (func(arr[i], i))\n return true;\n }\n return false;\n};\n/* harmony default export */ var esm_some = (some);\n//# sourceMappingURL=some.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/group-by.js\n\n\nvar group_by_hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction groupBy(data, condition) {\n if (!condition || !is_array(data)) {\n return {};\n }\n var result = {};\n // 兼容方法和 字符串的写法\n var predicate = is_function(condition) ? condition : function (item) { return item[condition]; };\n var key;\n for (var i = 0; i < data.length; i++) {\n var item = data[i];\n key = predicate(item);\n if (group_by_hasOwnProperty.call(result, key)) {\n result[key].push(item);\n }\n else {\n result[key] = [item];\n }\n }\n return result;\n}\n/* harmony default export */ var group_by = (groupBy);\n//# sourceMappingURL=group-by.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/group-to-map.js\n\n\n\n/**\n * 将数据分组成 map\n * @param data\n * @param condition\n */\nfunction groupToMap(data, condition) {\n if (!condition) {\n return {\n 0: data,\n };\n }\n if (!is_function(condition)) {\n // 如果是字符串,则按照 a*b 风格成数组\n var paramscondition_1 = is_array(condition) ? condition : condition.replace(/\\s+/g, \'\').split(\'*\');\n condition = function (row) {\n var unique = \'_\'; // 避免出现数字作为Key的情况,会进行按照数字的排序\n // 根据字段列表的值,拼接成 key\n for (var i = 0, l = paramscondition_1.length; i < l; i++) {\n unique += row[paramscondition_1[i]] && row[paramscondition_1[i]].toString();\n }\n return unique;\n };\n }\n return group_by(data, condition);\n}\n//# sourceMappingURL=group-to-map.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/group.js\n\n/* harmony default export */ var group = (function (data, condition) {\n if (!condition) {\n // 没有条件,则自身改成数组\n return [data];\n }\n var groups = groupToMap(data, condition);\n var array = [];\n for (var i in groups) {\n array.push(groups[i]);\n }\n return array;\n});\n//# sourceMappingURL=group.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/get-wrap-behavior.js\n/**\n * 获取封装的事件\n * @protected\n * @param {Object} obj 对象\n * @param {String} action 事件名称\n * @return {Function} 返回事件处理函数\n */\nfunction getWrapBehavior(obj, action) {\n return obj[\'_wrap_\' + action];\n}\n/* harmony default export */ var get_wrap_behavior = (getWrapBehavior);\n//# sourceMappingURL=get-wrap-behavior.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/wrap-behavior.js\n/**\n * 封装事件,便于使用上下文this,和便于解除事件时使用\n * @protected\n * @param {Object} obj 对象\n * @param {String} action 事件名称\n * @return {Function} 返回事件处理函数\n */\nfunction wrapBehavior(obj, action) {\n if (obj[\'_wrap_\' + action]) {\n return obj[\'_wrap_\' + action];\n }\n var method = function (e) {\n obj[action](e);\n };\n obj[\'_wrap_\' + action] = method;\n return method;\n}\n/* harmony default export */ var wrap_behavior = (wrapBehavior);\n//# sourceMappingURL=wrap-behavior.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/number2color.js\nvar numColorCache = {};\nfunction numberToColor(num) {\n // 增加缓存\n var color = numColorCache[num];\n if (!color) {\n var str = num.toString(16);\n for (var i = str.length; i < 6; i++) {\n str = \'0\' + str;\n }\n color = \'#\' + str;\n numColorCache[num] = color;\n }\n return color;\n}\n/* harmony default export */ var number2color = (numberToColor);\n//# sourceMappingURL=number2color.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/parse-radius.js\n\nfunction parseRadius(radius) {\n var r1 = 0, r2 = 0, r3 = 0, r4 = 0;\n if (is_array(radius)) {\n if (radius.length === 1) {\n r1 = r2 = r3 = r4 = radius[0];\n }\n else if (radius.length === 2) {\n r1 = r3 = radius[0];\n r2 = r4 = radius[1];\n }\n else if (radius.length === 3) {\n r1 = radius[0];\n r2 = r4 = radius[1];\n r3 = radius[2];\n }\n else {\n r1 = radius[0];\n r2 = radius[1];\n r3 = radius[2];\n r4 = radius[3];\n }\n }\n else {\n r1 = r2 = r3 = r4 = radius;\n }\n return {\n r1: r1,\n r2: r2,\n r3: r3,\n r4: r4\n };\n}\n/* harmony default export */ var parse_radius = (parseRadius);\n//# sourceMappingURL=parse-radius.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/clamp.js\nvar clamp = function (a, min, max) {\n if (a < min) {\n return min;\n }\n else if (a > max) {\n return max;\n }\n return a;\n};\n/* harmony default export */ var esm_clamp = (clamp);\n//# sourceMappingURL=clamp.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/fixed-base.js\nvar fixedBase = function (v, base) {\n var str = base.toString();\n var index = str.indexOf(\'.\');\n if (index === -1) {\n return Math.round(v);\n }\n var length = str.substr(index + 1).length;\n if (length > 20) {\n length = 20;\n }\n return parseFloat(v.toFixed(length));\n};\n/* harmony default export */ var fixed_base = (fixedBase);\n//# sourceMappingURL=fixed-base.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-number.js\n/**\n * 判断是否数字\n * @return {Boolean} 是否数字\n */\n\nvar isNumber = function (value) {\n return is_type(value, \'Number\');\n};\n/* harmony default export */ var is_number = (isNumber);\n//# sourceMappingURL=is-number.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-decimal.js\n\nvar isDecimal = function (num) {\n return is_number(num) && num % 1 !== 0;\n};\n/* harmony default export */ var is_decimal = (isDecimal);\n//# sourceMappingURL=is-decimal.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-even.js\n\nvar isEven = function (num) {\n return is_number(num) && num % 2 === 0;\n};\n/* harmony default export */ var is_even = (isEven);\n//# sourceMappingURL=is-even.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-integer.js\n\nvar isInteger = Number.isInteger ? Number.isInteger : function (num) {\n return is_number(num) && num % 1 === 0;\n};\n/* harmony default export */ var is_integer = (isInteger);\n//# sourceMappingURL=is-integer.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-negative.js\n\nvar isNegative = function (num) {\n return is_number(num) && num < 0;\n};\n/* harmony default export */ var is_negative = (isNegative);\n//# sourceMappingURL=is-negative.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-number-equal.js\nvar PRECISION = 0.00001; // numbers less than this is considered as 0\nfunction isNumberEqual(a, b, precision) {\n if (precision === void 0) { precision = PRECISION; }\n return Math.abs((a - b)) < precision;\n}\n;\n//# sourceMappingURL=is-number-equal.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-odd.js\n\nvar isOdd = function (num) {\n return is_number(num) && num % 2 !== 0;\n};\n/* harmony default export */ var is_odd = (isOdd);\n//# sourceMappingURL=is-odd.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-positive.js\n\nvar isPositive = function (num) {\n return is_number(num) && num > 0;\n};\n/* harmony default export */ var is_positive = (isPositive);\n//# sourceMappingURL=is-positive.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/max-by.js\n\n\n/**\n * @param {Array} arr The array to iterate over.\n * @param {Function} [fn] The iteratee invoked per element.\n * @return {*} Returns the maximum value.\n * @example\n *\n * var objects = [{ \'n\': 1 }, { \'n\': 2 }];\n *\n * maxBy(objects, function(o) { return o.n; });\n * // => { \'n\': 2 }\n *\n * maxBy(objects, \'n\');\n * // => { \'n\': 2 }\n */\n/* harmony default export */ var max_by = (function (arr, fn) {\n if (!is_array(arr)) {\n return undefined;\n }\n var maxItem;\n var max = -Infinity;\n for (var i = 0; i < arr.length; i++) {\n var item = arr[i];\n var v = is_function(fn) ? fn(item) : item[fn];\n if (v > max) {\n maxItem = item;\n max = v;\n }\n }\n return maxItem;\n});\n//# sourceMappingURL=max-by.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/min-by.js\n\n\n/**\n * @param {Array} arr The array to iterate over.\n * @param {Function} [fn] The iteratee invoked per element.\n * @return {*} Returns the minimum value.\n * @example\n *\n * var objects = [{ \'n\': 1 }, { \'n\': 2 }];\n *\n * minBy(objects, function(o) { return o.n; });\n * // => { \'n\': 1 }\n *\n * minBy(objects, \'n\');\n * // => { \'n\': 1 }\n */\n/* harmony default export */ var min_by = (function (arr, fn) {\n if (!is_array(arr)) {\n return undefined;\n }\n var minItem;\n var min = Infinity;\n for (var i = 0; i < arr.length; i++) {\n var item = arr[i];\n var v = is_function(fn) ? fn(item) : item[fn];\n if (v < min) {\n minItem = item;\n min = v;\n }\n }\n return minItem;\n});\n//# sourceMappingURL=min-by.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/mod.js\nvar mod = function (n, m) {\n return ((n % m) + m) % m;\n};\n/* harmony default export */ var esm_mod = (mod);\n//# sourceMappingURL=mod.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/to-degree.js\nvar DEGREE = 180 / Math.PI;\nvar toDegree = function (radian) {\n return DEGREE * radian;\n};\n/* harmony default export */ var to_degree = (toDegree);\n//# sourceMappingURL=to-degree.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/to-integer.js\n/* harmony default export */ var to_integer = (parseInt);\n//# sourceMappingURL=to-integer.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/to-radian.js\nvar RADIAN = Math.PI / 180;\nvar toRadian = function (degree) {\n return RADIAN * degree;\n};\n/* harmony default export */ var to_radian = (toRadian);\n//# sourceMappingURL=to-radian.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/for-in.js\n\n/* harmony default export */ var for_in = (esm_each);\n//# sourceMappingURL=for-in.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/has.js\n/* harmony default export */ var has = (function (obj, key) { return obj.hasOwnProperty(key); });\n//# sourceMappingURL=has.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/has-key.js\n\n/* harmony default export */ var has_key = (has);\n//# sourceMappingURL=has-key.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/values.js\n\n\n// @ts-ignore\nvar values_values = Object.values ? function (obj) { return Object.values(obj); } : function (obj) {\n var result = [];\n esm_each(obj, function (value, key) {\n if (!(is_function(obj) && key === \'prototype\')) {\n result.push(value);\n }\n });\n return result;\n};\n/* harmony default export */ var esm_values = (values_values);\n//# sourceMappingURL=values.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/has-value.js\n\n\n/* harmony default export */ var has_value = (function (obj, value) { return esm_contains(esm_values(obj), value); });\n//# sourceMappingURL=has-value.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/to-string.js\n\n/* harmony default export */ var to_string = (function (value) {\n if (is_nil(value))\n return \'\';\n return value.toString();\n});\n//# sourceMappingURL=to-string.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/lower-case.js\n\nvar lowerCase = function (str) {\n return to_string(str).toLowerCase();\n};\n/* harmony default export */ var lower_case = (lowerCase);\n//# sourceMappingURL=lower-case.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/lower-first.js\n\nvar lowerFirst = function (value) {\n var str = to_string(value);\n return str.charAt(0).toLowerCase() + str.substring(1);\n};\n/* harmony default export */ var lower_first = (lowerFirst);\n//# sourceMappingURL=lower-first.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/substitute.js\nfunction substitute(str, o) {\n if (!str || !o) {\n return str;\n }\n return str.replace(/\\\\?\\{([^{}]+)\\}/g, function (match, name) {\n if (match.charAt(0) === \'\\\\\') {\n return match.slice(1);\n }\n return (o[name] === undefined) ? \'\' : o[name];\n });\n}\n/* harmony default export */ var esm_substitute = (substitute);\n//# sourceMappingURL=substitute.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/upper-case.js\n\nvar upperCase = function (str) {\n return to_string(str).toUpperCase();\n};\n/* harmony default export */ var upper_case = (upperCase);\n//# sourceMappingURL=upper-case.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/upper-first.js\n\nvar upperFirst = function (value) {\n var str = to_string(value);\n return str.charAt(0).toUpperCase() + str.substring(1);\n};\n/* harmony default export */ var upper_first = (upperFirst);\n//# sourceMappingURL=upper-first.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/get-type.js\nvar get_type_toString = {}.toString;\nvar getType = function (value) {\n return get_type_toString.call(value).replace(/^\\[object /, \'\').replace(/]$/, \'\');\n};\n/* harmony default export */ var get_type = (getType);\n//# sourceMappingURL=get-type.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-arguments.js\n/**\n * 是否是参数类型\n *\n * @param {Object} value 测试的值\n * @return {Boolean}\n */\n\nvar isArguments = function (value) {\n return is_type(value, \'Arguments\');\n};\n/* harmony default export */ var is_arguments = (isArguments);\n//# sourceMappingURL=is-arguments.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-boolean.js\n/**\n * 是否是布尔类型\n *\n * @param {Object} value 测试的值\n * @return {Boolean}\n */\n\nvar isBoolean = function (value) {\n return is_type(value, \'Boolean\');\n};\n/* harmony default export */ var is_boolean = (isBoolean);\n//# sourceMappingURL=is-boolean.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-date.js\n\nvar isDate = function (value) {\n return is_type(value, \'Date\');\n};\n/* harmony default export */ var is_date = (isDate);\n//# sourceMappingURL=is-date.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-error.js\n/**\n * 是否是参数类型\n *\n * @param {Object} value 测试的值\n * @return {Boolean}\n */\n\nvar isError = function (value) {\n return is_type(value, \'Error\');\n};\n/* harmony default export */ var is_error = (isError);\n//# sourceMappingURL=is-error.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-finite.js\n/**\n * 判断是否为有限数\n * @return {Boolean}\n */\n\n/* harmony default export */ var is_finite = (function (value) {\n return is_number(value) && isFinite(value);\n});\n//# sourceMappingURL=is-finite.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-null.js\nvar isNull = function (value) {\n return value === null;\n};\n/* harmony default export */ var is_null = (isNull);\n//# sourceMappingURL=is-null.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-prototype.js\nvar objectProto = Object.prototype;\nvar isPrototype = function (value) {\n var Ctor = value && value.constructor;\n var proto = (typeof Ctor === \'function\' && Ctor.prototype) || objectProto;\n return value === proto;\n};\n/* harmony default export */ var is_prototype = (isPrototype);\n//# sourceMappingURL=is-prototype.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-reg-exp.js\n\nvar isRegExp = function (str) {\n return is_type(str, \'RegExp\');\n};\n/* harmony default export */ var is_reg_exp = (isRegExp);\n//# sourceMappingURL=is-reg-exp.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-undefined.js\nvar isUndefined = function (value) {\n return value === undefined;\n};\n/* harmony default export */ var is_undefined = (isUndefined);\n//# sourceMappingURL=is-undefined.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-element.js\n/**\n * 判断是否HTML元素\n * @return {Boolean} 是否HTML元素\n */\nvar isElement = function (o) {\n return o instanceof Element || o instanceof HTMLDocument;\n};\n/* harmony default export */ var is_element = (isElement);\n//# sourceMappingURL=is-element.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/request-animation-frame.js\nfunction requestAnimationFrame(fn) {\n var method = window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n // @ts-ignore\n window.mozRequestAnimationFrame ||\n // @ts-ignore\n window.msRequestAnimationFrame ||\n function (f) {\n return setTimeout(f, 16);\n };\n return method(fn);\n}\n;\n//# sourceMappingURL=request-animation-frame.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/clear-animation-frame.js\nfunction cancelAnimationFrame(handler) {\n var method = window.cancelAnimationFrame ||\n window.webkitCancelAnimationFrame ||\n // @ts-ignore\n window.mozCancelAnimationFrame ||\n // @ts-ignore\n window.msCancelAnimationFrame ||\n clearTimeout;\n method(handler);\n}\n;\n//# sourceMappingURL=clear-animation-frame.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/mix.js\n// FIXME: Mutable param should be forbidden in static lang.\nfunction _mix(dist, obj) {\n for (var key in obj) {\n if (obj.hasOwnProperty(key) && key !== \'constructor\' && obj[key] !== undefined) {\n dist[key] = obj[key];\n }\n }\n}\nfunction mix(dist, src1, src2, src3) {\n if (src1)\n _mix(dist, src1);\n if (src2)\n _mix(dist, src2);\n if (src3)\n _mix(dist, src3);\n return dist;\n}\n//# sourceMappingURL=mix.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/augment.js\n\n\nvar augment = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var c = args[0];\n for (var i = 1; i < args.length; i++) {\n var obj = args[i];\n if (is_function(obj)) {\n obj = obj.prototype;\n }\n mix(c.prototype, obj);\n }\n};\n/* harmony default export */ var esm_augment = (augment);\n//# sourceMappingURL=augment.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/clone.js\n\nvar clone = function (obj) {\n if (typeof obj !== \'object\' || obj === null) {\n return obj;\n }\n var rst;\n if (is_array(obj)) {\n rst = [];\n for (var i = 0, l = obj.length; i < l; i++) {\n if (typeof obj[i] === \'object\' && obj[i] != null) {\n rst[i] = clone(obj[i]);\n }\n else {\n rst[i] = obj[i];\n }\n }\n }\n else {\n rst = {};\n for (var k in obj) {\n if (typeof obj[k] === \'object\' && obj[k] != null) {\n rst[k] = clone(obj[k]);\n }\n else {\n rst[k] = obj[k];\n }\n }\n }\n return rst;\n};\n/* harmony default export */ var esm_clone = (clone);\n//# sourceMappingURL=clone.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/debounce.js\nfunction debounce(func, wait, immediate) {\n var timeout;\n return function () {\n var context = this, args = arguments;\n var later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n var callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n}\n/* harmony default export */ var esm_debounce = (debounce);\n//# sourceMappingURL=debounce.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/memoize.js\n\n/**\n * _.memoize(calColor);\n * _.memoize(calColor, (...args) => args[0]);\n * @param f\n * @param resolver\n */\n/* harmony default export */ var memoize = (function (f, resolver) {\n if (!is_function(f)) {\n throw new TypeError(\'Expected a function\');\n }\n var memoized = function () {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n // 使用方法构造 key,如果不存在 resolver,则直接取第一个参数作为 key\n var key = resolver ? resolver.apply(this, args) : args[0];\n var cache = memoized.cache;\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = f.apply(this, args);\n // 缓存起来\n cache.set(key, result);\n return result;\n };\n memoized.cache = new Map();\n return memoized;\n});\n//# sourceMappingURL=memoize.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/deep-mix.js\n\n\nvar MAX_MIX_LEVEL = 5;\nfunction _deepMix(dist, src, level, maxLevel) {\n level = level || 0;\n maxLevel = maxLevel || MAX_MIX_LEVEL;\n for (var key in src) {\n if (src.hasOwnProperty(key)) {\n var value = src[key];\n if (value !== null && is_plain_object(value)) {\n if (!is_plain_object(dist[key])) {\n dist[key] = {};\n }\n if (level < maxLevel) {\n _deepMix(dist[key], value, level + 1, maxLevel);\n }\n else {\n dist[key] = src[key];\n }\n }\n else if (is_array(value)) {\n dist[key] = [];\n dist[key] = dist[key].concat(value);\n }\n else if (value !== undefined) {\n dist[key] = value;\n }\n }\n }\n}\n// todo 重写\nvar deepMix = function (rst) {\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n for (var i = 0; i < args.length; i += 1) {\n _deepMix(rst, args[i]);\n }\n return rst;\n};\n/* harmony default export */ var deep_mix = (deepMix);\n//# sourceMappingURL=deep-mix.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/extend.js\n\n\nvar extend = function (subclass, superclass, overrides, staticOverrides) {\n // 如果只提供父类构造函数,则自动生成子类构造函数\n if (!is_function(superclass)) {\n overrides = superclass;\n superclass = subclass;\n subclass = function () { };\n }\n var create = Object.create ?\n function (proto, c) {\n return Object.create(proto, {\n constructor: {\n value: c\n }\n });\n } :\n function (proto, c) {\n function Tmp() { }\n Tmp.prototype = proto;\n var o = new Tmp();\n o.constructor = c;\n return o;\n };\n var superObj = create(superclass.prototype, subclass); // new superclass(),//实例化父类作为子类的prototype\n subclass.prototype = mix(superObj, subclass.prototype); // 指定子类的prototype\n subclass.superclass = create(superclass.prototype, superclass);\n mix(superObj, overrides);\n mix(subclass, staticOverrides);\n return subclass;\n};\n/* harmony default export */ var esm_extend = (extend);\n//# sourceMappingURL=extend.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/index-of.js\n\nvar index_of_indexOf = function (arr, obj) {\n if (!is_array_like(arr)) {\n return -1;\n }\n var m = Array.prototype.indexOf;\n if (m) {\n return m.call(arr, obj);\n }\n var index = -1;\n for (var i = 0; i < arr.length; i++) {\n if (arr[i] === obj) {\n index = i;\n break;\n }\n }\n return index;\n};\n/* harmony default export */ var index_of = (index_of_indexOf);\n//# sourceMappingURL=index-of.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-empty.js\n\n\n\n\nvar is_empty_hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction isEmpty(value) {\n /**\n * isEmpty(null) => true\n * isEmpty() => true\n * isEmpty(true) => true\n * isEmpty(1) => true\n * isEmpty([1, 2, 3]) => false\n * isEmpty(\'abc\') => false\n * isEmpty({ a: 1 }) => false\n */\n if (is_nil(value)) {\n return true;\n }\n if (is_array_like(value)) {\n return !value.length;\n }\n var type = get_type(value);\n if (type === \'Map\' || type === \'Set\') {\n return !value.size;\n }\n if (is_prototype(value)) {\n return !Object.keys(value).length;\n }\n for (var key in value) {\n if (is_empty_hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n return true;\n}\n/* harmony default export */ var is_empty = (isEmpty);\n//# sourceMappingURL=is-empty.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-equal.js\n\n\n\nvar isEqual = function (value, other) {\n if (value === other) {\n return true;\n }\n if (!value || !other) {\n return false;\n }\n if (is_string(value) || is_string(other)) {\n return false;\n }\n if (is_array_like(value) || is_array_like(other)) {\n if (value.length !== other.length) {\n return false;\n }\n var rst = true;\n for (var i = 0; i < value.length; i++) {\n rst = isEqual(value[i], other[i]);\n if (!rst) {\n break;\n }\n }\n return rst;\n }\n if (is_object_like(value) || is_object_like(other)) {\n var valueKeys = Object.keys(value);\n var otherKeys = Object.keys(other);\n if (valueKeys.length !== otherKeys.length) {\n return false;\n }\n var rst = true;\n for (var i = 0; i < valueKeys.length; i++) {\n rst = isEqual(value[valueKeys[i]], other[valueKeys[i]]);\n if (!rst) {\n break;\n }\n }\n return rst;\n }\n return false;\n};\n/* harmony default export */ var is_equal = (isEqual);\n//# sourceMappingURL=is-equal.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/is-equal-with.js\n\n\n/**\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [fn] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n * if (isGreeting(objValue) && isGreeting(othValue)) {\n * return true;\n * }\n * }\n *\n * var array = [\'hello\', \'goodbye\'];\n * var other = [\'hi\', \'goodbye\'];\n *\n * isEqualWith(array, other, customizer); // => true\n */\n/* harmony default export */ var is_equal_with = (function (value, other, fn) {\n if (!is_function(fn)) {\n return is_equal(value, other);\n }\n return !!fn(value, other);\n});\n//# sourceMappingURL=is-equal-with.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/map.js\n\nvar map = function (arr, func) {\n if (!is_array_like(arr)) {\n // @ts-ignore\n return arr;\n }\n var result = [];\n for (var index = 0; index < arr.length; index++) {\n var value = arr[index];\n result.push(func(value, index));\n }\n return result;\n};\n/* harmony default export */ var esm_map = (map);\n//# sourceMappingURL=map.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/map-values.js\n\n\nvar identity = function (v) { return v; };\n/* harmony default export */ var map_values = (function (object, func) {\n if (func === void 0) { func = identity; }\n var r = {};\n if (is_object(object) && !is_nil(object)) {\n Object.keys(object).forEach(function (key) {\n // @ts-ignore\n r[key] = func(object[key], key);\n });\n }\n return r;\n});\n//# sourceMappingURL=map-values.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/get.js\n\n/**\n * https://github.com/developit/dlv/blob/master/index.js\n * @param obj\n * @param key\n * @param defaultValue\n */\n/* harmony default export */ var get = (function (obj, key, defaultValue) {\n var p = 0;\n var keyArr = is_string(key) ? key.split(\'.\') : key;\n while (obj && p < keyArr.length) {\n obj = obj[keyArr[p++]];\n }\n return (obj === undefined || p < keyArr.length) ? defaultValue : obj;\n});\n//# sourceMappingURL=get.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/set.js\n\n\n\n/**\n * https://github.com/developit/dlv/blob/master/index.js\n * @param obj\n * @param path\n * @param value\n */\n/* harmony default export */ var set = (function (obj, path, value) {\n var o = obj;\n var keyArr = is_string(path) ? path.split(\'.\') : path;\n keyArr.forEach(function (key, idx) {\n // 不是最后一个\n if (idx < keyArr.length - 1) {\n if (!is_object(o[key])) {\n o[key] = is_number(keyArr[idx + 1]) ? [] : {};\n }\n o = o[key];\n }\n else {\n o[key] = value;\n }\n });\n return obj;\n});\n//# sourceMappingURL=set.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/pick.js\n\n\nvar pick_hasOwnProperty = Object.prototype.hasOwnProperty;\n/* harmony default export */ var pick = (function (object, keys) {\n if (object === null || !is_plain_object(object)) {\n return {};\n }\n var result = {};\n esm_each(keys, function (key) {\n if (pick_hasOwnProperty.call(object, key)) {\n result[key] = object[key];\n }\n });\n return result;\n});\n//# sourceMappingURL=pick.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/omit.js\n\n/* harmony default export */ var omit = (function (obj, keys) {\n return esm_reduce(obj, function (r, curr, key) {\n if (!keys.includes(key)) {\n r[key] = curr;\n }\n return r;\n }, {});\n});\n//# sourceMappingURL=omit.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/throttle.js\n/* harmony default export */ var throttle = (function (func, wait, options) {\n var timeout, context, args, result;\n var previous = 0;\n if (!options)\n options = {};\n var later = function () {\n previous = options.leading === false ? 0 : Date.now();\n timeout = null;\n result = func.apply(context, args);\n if (!timeout)\n context = args = null;\n };\n var throttled = function () {\n var now = Date.now();\n if (!previous && options.leading === false)\n previous = now;\n var remaining = wait - (now - previous);\n context = this;\n args = arguments;\n if (remaining <= 0 || remaining > wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n result = func.apply(context, args);\n if (!timeout)\n context = args = null;\n }\n else if (!timeout && options.trailing !== false) {\n timeout = setTimeout(later, remaining);\n }\n return result;\n };\n throttled.cancel = function () {\n clearTimeout(timeout);\n previous = 0;\n timeout = context = args = null;\n };\n return throttled;\n});\n//# sourceMappingURL=throttle.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/to-array.js\n\n/* harmony default export */ var to_array = (function (value) {\n return is_array_like(value) ? Array.prototype.slice.call(value) : [];\n});\n//# sourceMappingURL=to-array.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/unique-id.js\nvar unique_id_map = {};\n/* harmony default export */ var unique_id = (function (prefix) {\n prefix = prefix || \'g\';\n if (!unique_id_map[prefix]) {\n unique_id_map[prefix] = 1;\n }\n else {\n unique_id_map[prefix] += 1;\n }\n return prefix + unique_id_map[prefix];\n});\n//# sourceMappingURL=unique-id.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/noop.js\n/* harmony default export */ var noop = (function () { });\n//# sourceMappingURL=noop.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/identity.js\n/* harmony default export */ var esm_identity = (function (v) { return v; });\n//# sourceMappingURL=identity.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/size.js\n\n\nfunction size(o) {\n if (is_nil(o)) {\n return 0;\n }\n if (is_array_like(o)) {\n return o.length;\n }\n return Object.keys(o).length;\n}\n//# sourceMappingURL=size.js.map\n// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js\nvar tslib_es6 = __webpack_require__(1);\n\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/measure-text-width.js\n\n\n\n\nvar ctx;\n/**\n * 计算文本的宽度\n */\n/* harmony default export */ var measure_text_width = (memoize(function (text, font) {\n if (font === void 0) { font = {}; }\n var fontSize = font.fontSize, fontFamily = font.fontFamily, fontWeight = font.fontWeight, fontStyle = font.fontStyle, fontVariant = font.fontVariant;\n if (!ctx) {\n ctx = document.createElement(\'canvas\').getContext(\'2d\');\n }\n ctx.font = [fontStyle, fontVariant, fontWeight, fontSize + "px", fontFamily].join(\' \');\n return ctx.measureText(is_string(text) ? text : \'\').width;\n}, function (text, font) {\n if (font === void 0) { font = {}; }\n return Object(tslib_es6["__spreadArrays"])([text], esm_values(font)).join(\'\');\n}));\n//# sourceMappingURL=measure-text-width.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/get-ellipsis-text.js\n\n\n\n/**\n * 获取文本的 ... 文本。\n * 算法(减少每次 measureText 的长度,measureText 的性能跟字符串时间相关):\n * 1. 先通过 STEP 逐步计算,找到最后一个小于 maxWidth 的字符串\n * 2. 然后对最后这个字符串二分计算\n * @param text 需要计算的文本, 由于历史原因 除了支持string,还支持空值,number和数组等\n * @param maxWidth 最大宽度\n * @param font 字体\n * @param str 要替换的文本\n */\n/* harmony default export */ var get_ellipsis_text = (function (text, maxWidth, font, str) {\n if (str === void 0) { str = \'...\'; }\n var STEP = 16; // 每次 16,调参工程师\n var PLACEHOLDER_WIDTH = measure_text_width(str, font);\n var leftText = !is_string(text) ? to_string(text) : text;\n var leftWidth = maxWidth;\n var r = []; // 最终的分段字符串\n var currentText;\n var currentWidth;\n if (measure_text_width(text, font) <= maxWidth) {\n return text;\n }\n // 首先通过 step 计算,找出最大的未超出长度的\n // eslint-disable-next-line no-constant-condition\n while (true) {\n // 更新字符串\n currentText = leftText.substr(0, STEP);\n // 计算宽度\n currentWidth = measure_text_width(currentText, font);\n // 超出剩余宽度,则停止\n if (currentWidth + PLACEHOLDER_WIDTH > leftWidth) {\n if (currentWidth > leftWidth) {\n break;\n }\n }\n r.push(currentText);\n // 没有超出,则计算剩余宽度\n leftWidth -= currentWidth;\n leftText = leftText.substr(STEP);\n // 字符串整体没有超出\n if (!leftText) {\n return r.join(\'\');\n }\n }\n // 最下的最后一个 STEP,使用 1 递增(用二分效果更高)\n // eslint-disable-next-line no-constant-condition\n while (true) {\n // 更新字符串\n currentText = leftText.substr(0, 1);\n // 计算宽度\n currentWidth = measure_text_width(currentText, font);\n // 超出剩余宽度,则停止\n if (currentWidth + PLACEHOLDER_WIDTH > leftWidth) {\n break;\n }\n r.push(currentText);\n // 没有超出,则计算剩余宽度\n leftWidth -= currentWidth;\n leftText = leftText.substr(1);\n if (!leftText) {\n return r.join(\'\');\n }\n }\n return "" + r.join(\'\') + str;\n});\n//# sourceMappingURL=get-ellipsis-text.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/cache.js\n/**\n * k-v 存储\n */\nvar default_1 = /** @class */ (function () {\n function default_1() {\n this.map = {};\n }\n default_1.prototype.has = function (key) {\n return this.map[key] !== undefined;\n };\n default_1.prototype.get = function (key, def) {\n var v = this.map[key];\n return v === undefined ? def : v;\n };\n default_1.prototype.set = function (key, value) {\n this.map[key] = value;\n };\n default_1.prototype.clear = function () {\n this.map = {};\n };\n default_1.prototype.delete = function (key) {\n delete this.map[key];\n };\n default_1.prototype.size = function () {\n return Object.keys(this.map).length;\n };\n return default_1;\n}());\n/* harmony default export */ var cache = (default_1);\n//# sourceMappingURL=cache.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/util/esm/index.js\n// array\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// event\n\n\n// format\n\n\n// math\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// object\n\n\n\n\n\n\n\n// string\n\n\n\n\n\n// type\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// other\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// text\n\n\n// 不知道为什么,需要把这个 export,不然 ts 会报类型错误\n\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaXMtYXJyYXktbGlrZS5qcz9lN2NkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9jb250YWlucy5qcz84YmM4Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9maWx0ZXIuanM/N2ZlMSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZGlmZmVyZW5jZS5qcz8zYTQwIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy10eXBlLmpzPzYwNDciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLWZ1bmN0aW9uLmpzPzEwODYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLW5pbC5qcz8xMmE2Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1hcnJheS5qcz8yN2EwIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1vYmplY3QuanM/ZDdhNSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZWFjaC5qcz9iNDE3Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9rZXlzLmpzP2U4N2EiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLW1hdGNoLmpzP2NjNTUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLW9iamVjdC1saWtlLmpzP2Y4MGQiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLXBsYWluLW9iamVjdC5qcz82MTEzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9maW5kLmpzP2ZmZDYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2ZpbmQtaW5kZXguanM/YzQ5ZiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZmlyc3QtdmFsdWUuanM/NjExYyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZmxhdHRlbi5qcz9hZGI3Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9mbGF0dGVuLWRlZXAuanM/MzM4MSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vbWF4LmpzPzgyMDkiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL21pbi5qcz81YzExIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9nZXQtcmFuZ2UuanM/YjVkOCIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vcHVsbC5qcz84ZDJkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9wdWxsLWF0LmpzPzY1N2EiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3JlZHVjZS5qcz85Mzk2Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9yZW1vdmUuanM/MzFjZSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaXMtc3RyaW5nLmpzPzE3M2MiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3NvcnQtYnkuanM/MDc0NiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vdW5pcS5qcz8zODdiIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS91bmlvbi5qcz9kODJlIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS92YWx1ZXMtb2Yta2V5LmpzPzQ1NjkiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2hlYWQuanM/ZTUxYyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vbGFzdC5qcz9hNWZkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9zdGFydHMtd2l0aC5qcz85NGZjIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9lbmRzLXdpdGguanM/Yjg1NiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZXZlcnkuanM/NDE0YiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vc29tZS5qcz83YjMwIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9ncm91cC1ieS5qcz84NjZlIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9ncm91cC10by1tYXAuanM/YmRlNiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZ3JvdXAuanM/NjQyMSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vZ2V0LXdyYXAtYmVoYXZpb3IuanM/NzA4MSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vd3JhcC1iZWhhdmlvci5qcz8wYTQxIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9udW1iZXIyY29sb3IuanM/NjkzZSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vcGFyc2UtcmFkaXVzLmpzPzNkNTAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2NsYW1wLmpzPzk4NTMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2ZpeGVkLWJhc2UuanM/MWIzZiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaXMtbnVtYmVyLmpzPzcwNTgiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLWRlY2ltYWwuanM/MTEwZSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaXMtZXZlbi5qcz8xNjliIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1pbnRlZ2VyLmpzP2RhZTQiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLW5lZ2F0aXZlLmpzPzJhODAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLW51bWJlci1lcXVhbC5qcz83ZTQ4Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1vZGQuanM/MzEyZSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaXMtcG9zaXRpdmUuanM/MjJlZiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vbWF4LWJ5LmpzPzI1YzIiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL21pbi1ieS5qcz8xNjk0Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9tb2QuanM/MDkzMiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vdG8tZGVncmVlLmpzPzk5NTgiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3RvLWludGVnZXIuanM/NDMwYSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vdG8tcmFkaWFuLmpzP2UxNzciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2Zvci1pbi5qcz83OGU3Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9oYXMuanM/NDY5NSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaGFzLWtleS5qcz9lMTZkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS92YWx1ZXMuanM/NmQ5MiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaGFzLXZhbHVlLmpzPzJhYWUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3RvLXN0cmluZy5qcz8xYjczIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9sb3dlci1jYXNlLmpzP2Q3YjciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2xvd2VyLWZpcnN0LmpzP2M2MDgiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3N1YnN0aXR1dGUuanM/MDI5ZiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vdXBwZXItY2FzZS5qcz9mNjE2Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS91cHBlci1maXJzdC5qcz9kNjRiIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9nZXQtdHlwZS5qcz9hMmVmIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1hcmd1bWVudHMuanM/MjA1OCIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vaXMtYm9vbGVhbi5qcz9mMjliIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1kYXRlLmpzP2RjYzMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLWVycm9yLmpzPzExODYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLWZpbml0ZS5qcz84MmE4Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1udWxsLmpzP2RkYzEiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLXByb3RvdHlwZS5qcz9jNzAyIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1yZWctZXhwLmpzPzJmNjAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lzLXVuZGVmaW5lZC5qcz9jYTNlIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1lbGVtZW50LmpzP2IwZWIiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3JlcXVlc3QtYW5pbWF0aW9uLWZyYW1lLmpzPzNlNjMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2NsZWFyLWFuaW1hdGlvbi1mcmFtZS5qcz81YjA0Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9taXguanM/NzU4MyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vYXVnbWVudC5qcz9lNmQ5Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9jbG9uZS5qcz9iMDEzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9kZWJvdW5jZS5qcz85ZDc1Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9tZW1vaXplLmpzPzlhZTMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2RlZXAtbWl4LmpzP2U0MzUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2V4dGVuZC5qcz8yYmQ3Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pbmRleC1vZi5qcz83YWJiIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1lbXB0eS5qcz8zNzlmIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1lcXVhbC5qcz9kMzVmIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9pcy1lcXVhbC13aXRoLmpzPzE5MDYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL21hcC5qcz9hNmY5Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9tYXAtdmFsdWVzLmpzP2M3NmEiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2dldC5qcz80MzE3Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9zZXQuanM/ZjY2NSIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vcGljay5qcz85MTAwIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9vbWl0LmpzPzA3ZGYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3Rocm90dGxlLmpzP2YzNzYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3RvLWFycmF5LmpzPzJmMjciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3VuaXF1ZS1pZC5qcz85MWI1Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di91dGlsL2VzbS9ub29wLmpzPzRhM2QiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2lkZW50aXR5LmpzPzI5ZDciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL3NpemUuanM/ODFkZiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvdXRpbC9lc20vbWVhc3VyZS10ZXh0LXdpZHRoLmpzPzk0Y2EiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2dldC1lbGxpcHNpcy10ZXh0LmpzP2M2NjciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2NhY2hlLmpzP2YwNDEiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3V0aWwvZXNtL2luZGV4LmpzPzg5MzciXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLDZEQUFXLEVBQUM7QUFDM0IseUM7O0FDVjBDO0FBQzFDO0FBQ0EsU0FBUyxhQUFXO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ2UseURBQVEsRUFBQztBQUN4QixvQzs7QUNSMEM7QUFDMUM7QUFDQSxTQUFTLGFBQVc7QUFDcEI7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLG9CQUFvQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLHFEQUFNLEVBQUM7QUFDdEIsa0M7O0FDZjhCO0FBQ0k7QUFDbEM7QUFDQTtBQUNBO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFdBQVcsTUFBTTtBQUNqQixZQUFZLE1BQU07QUFDbEI7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBLDRCQUE0QixhQUFhO0FBQ3pDLFdBQVcsVUFBTSx3QkFBd0IsU0FBUyxZQUFRLGdCQUFnQixFQUFFO0FBQzVFO0FBQ2UsNkRBQVUsRUFBQztBQUMxQixzQzs7QUNoQkEsSUFBSSxnQkFBUSxLQUFLO0FBQ2pCLHFDQUFxQyxRQUFRLGdCQUFRLHlDQUF5QztBQUMvRSxrREFBTSxFQUFDO0FBQ3RCLG1DOztBQ0hBO0FBQ0E7QUFDQSxZQUFZLEVBQUU7QUFDZCxZQUFZLFFBQVE7QUFDcEI7QUFDK0I7QUFDZjtBQUNoQixXQUFXLE9BQU07QUFDakIsQ0FBQyxFQUFFO0FBQ0gsdUM7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLGdEQUFLLEVBQUM7QUFDckIsa0M7O0FDVCtCO0FBQ2Y7QUFDaEI7QUFDQTtBQUNBLFFBQVEsT0FBTTtBQUNkLENBQUMsRUFBRTtBQUNILG9DOztBQ05nQjtBQUNoQjtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUU7QUFDSCxxQzs7QUNWaUM7QUFDRTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxRQUFPO0FBQ2YsOENBQThDLFNBQVM7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsaURBQUksRUFBQztBQUNwQixnQzs7QUMzQjBCO0FBQ2E7QUFDdkMsSUFBSSxTQUFJLGlDQUFpQyx5QkFBeUIsRUFBRTtBQUNwRTtBQUNBLElBQUksUUFBSTtBQUNSLGNBQWMsV0FBVTtBQUN4QjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDZSxzREFBSSxFQUFDO0FBQ3BCLGdDOztBQ1o2QjtBQUNIO0FBQzFCO0FBQ0EsZ0JBQWdCLFFBQUk7QUFDcEI7QUFDQSxRQUFRLE1BQUs7QUFDYjtBQUNBLG1CQUFtQixZQUFZO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2Usb0RBQU8sRUFBQztBQUN2QixvQzs7QUNoQkE7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSwrREFBWSxFQUFDO0FBQzVCLDBDOztBQ1Y0QztBQUNiO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBLFNBQVMsY0FBWSxZQUFZLE9BQU07QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLGlFQUFhLEVBQUM7QUFDN0IsMkM7O0FDdEJ1QztBQUNOO0FBQ0E7QUFDYTtBQUM5QztBQUNBLFNBQVMsUUFBTztBQUNoQjtBQUNBO0FBQ0EsUUFBUSxXQUFVO0FBQ2xCO0FBQ0E7QUFDQSxRQUFRLGVBQWE7QUFDckIsbUNBQW1DLFFBQVEsUUFBTyxlQUFlO0FBQ2pFO0FBQ0E7QUFDQSx1QkFBdUIsZ0JBQWdCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsaURBQUksRUFBQztBQUNwQixnQzs7QUN4QkE7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QywyQkFBMkIsZ0JBQWdCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2Usd0RBQVMsRUFBQztBQUN6QixzQzs7QUNYNkI7QUFDSTtBQUNqQztBQUNBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0EsYUFBYSxNQUFLO0FBQ2xCLGdCQUFnQixRQUFPO0FBQ3ZCLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSwwREFBVSxFQUFDO0FBQzFCLHVDOztBQ3BCaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFlBQVksTUFBTTtBQUNsQjtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQSxTQUFTLFFBQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNlLHVEQUFPLEVBQUM7QUFDdkIsbUM7O0FDckJpQztBQUNqQztBQUNBO0FBQ0E7QUFDQSxXQUFXLE1BQU07QUFDakIsV0FBVyxNQUFNO0FBQ2pCLFlBQVksTUFBTTtBQUNsQjtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQSw0QkFBNEIsYUFBYTtBQUN6QyxTQUFTLFFBQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGdCQUFnQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsNERBQVcsRUFBQztBQUMzQix3Qzs7QUN4QmlDO0FBQ2pDO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFlBQVksRUFBRTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZ0I7QUFDaEIsU0FBUyxRQUFPO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLENBQUMsRUFBRTtBQUNILCtCOztBQzFCaUM7QUFDakM7QUFDQSxXQUFXLE1BQU07QUFDakIsWUFBWSxFQUFFO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNnQjtBQUNoQixTQUFTLFFBQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsQ0FBQyxFQUFFO0FBQ0gsK0I7O0FDMUJpQztBQUNTO0FBQ0E7QUFDMUM7QUFDQTtBQUNBLG1EQUFtRCxrQkFBa0IsRUFBRTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsUUFBTztBQUNmO0FBQ0EsdUJBQXVCLG1CQUFtQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsT0FBTTtBQUNwQixjQUFjLE9BQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLHNEQUFRLEVBQUM7QUFDeEIscUM7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsdUJBQXVCO0FBQzNDO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSxpREFBSSxFQUFDO0FBQ3BCLGdDOztBQ2xCMEM7QUFDMUMsSUFBSSxjQUFNO0FBQ1YsSUFBSSxjQUFNO0FBQ1YsU0FBUyxhQUFXO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksY0FBTTtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNlLDBEQUFNLEVBQUM7QUFDdEIsbUM7O0FDbkIwQjtBQUNPO0FBQ2E7QUFDOUM7QUFDQSxTQUFTLFFBQU8sVUFBVSxlQUFhO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBLElBQUksUUFBSTtBQUNSO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDZSxxREFBTSxFQUFDO0FBQ3RCLGtDOztBQ2QwQztBQUNYO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLGFBQVc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxPQUFNO0FBQ1Y7QUFDQTtBQUNlLHFEQUFNLEVBQUM7QUFDdEIsa0M7O0FDM0IrQjtBQUNmO0FBQ2hCLFdBQVcsT0FBTTtBQUNqQixDQUFDLEVBQUU7QUFDSCxxQzs7QUNKaUM7QUFDRTtBQUNJO0FBQ3ZDO0FBQ0E7QUFDQSxRQUFRLFdBQVU7QUFDbEIsb0NBQW9DLHdCQUF3QjtBQUM1RDtBQUNBO0FBQ0E7QUFDQSxZQUFZLFNBQVE7QUFDcEI7QUFDQTtBQUNBLGlCQUFpQixRQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixtQkFBbUI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLGtEQUFNLEVBQUM7QUFDdEIsbUM7O0FDakNlO0FBQ2YsMkJBQTJCLG1CQUFtQjtBQUM5QztBQUNBO0FBQ0EseUNBQXlDLFNBQVM7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNmMEI7QUFDMUI7QUFDQTtBQUNBLG9CQUFvQix1QkFBdUI7QUFDM0M7QUFDQTtBQUNBLFdBQVcsSUFBSTtBQUNmO0FBQ2UsbURBQUssRUFBQztBQUNyQixpQzs7QUNUaUM7QUFDSjtBQUNiO0FBQ2hCO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQSxhQUFhLE1BQUs7QUFDbEI7QUFDQSxpQkFBaUIsUUFBTztBQUN4QjtBQUNBO0FBQ0EsMkJBQTJCLGtCQUFrQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsRUFBRTtBQUNILHlDOztBQ3pCMEM7QUFDM0I7QUFDZixRQUFRLGFBQVc7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNQMEM7QUFDM0IsU0FBUyxTQUFJO0FBQzVCLFFBQVEsYUFBVztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0M7O0FDUmlDO0FBQ0U7QUFDbkM7QUFDQSxZQUFZLFFBQU8sU0FBUyxTQUFRO0FBQ3BDO0FBQ2UsMERBQVUsRUFBQztBQUMxQix1Qzs7QUNOaUM7QUFDRTtBQUNuQztBQUNBLFlBQVksUUFBTyxTQUFTLFNBQVE7QUFDcEM7QUFDZSxzREFBUSxFQUFDO0FBQ3hCLHFDOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixnQkFBZ0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLG1EQUFLLEVBQUM7QUFDckIsaUM7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsaURBQUksRUFBQztBQUNwQixnQzs7QUNiaUM7QUFDTTtBQUN2QyxJQUFJLHVCQUFjO0FBQ2xCO0FBQ0EsdUJBQXVCLFFBQU87QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsV0FBVSwyQ0FBMkMsd0JBQXdCO0FBQ2pHO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQztBQUNBO0FBQ0EsWUFBWSx1QkFBYztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2Usb0RBQU8sRUFBQztBQUN2QixvQzs7QUN4QmlDO0FBQ007QUFDTjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2U7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxXQUFVO0FBQ25CO0FBQ0EsZ0NBQWdDLFFBQU87QUFDdkM7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQSx5REFBeUQsT0FBTztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFPO0FBQ2xCO0FBQ0Esd0M7O0FDNUJ3QztBQUN4QjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUU7QUFDSCxpQzs7QUNiQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkIsWUFBWSxPQUFPO0FBQ25CLFlBQVksU0FBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNlLHFFQUFlLEVBQUM7QUFDL0IsNkM7O0FDWEE7QUFDQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFlBQVksT0FBTztBQUNuQixZQUFZLFNBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLDhEQUFZLEVBQUM7QUFDNUIseUM7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxPQUFPO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsOERBQWEsRUFBQztBQUM3Qix3Qzs7QUNmaUM7QUFDakM7QUFDQTtBQUNBLFFBQVEsUUFBTztBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSw0REFBVyxFQUFDO0FBQzNCLHdDOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSxtREFBSyxFQUFDO0FBQ3JCLGlDOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLHdEQUFTLEVBQUM7QUFDekIsc0M7O0FDYkE7QUFDQTtBQUNBLFlBQVksUUFBUTtBQUNwQjtBQUMrQjtBQUMvQjtBQUNBLFdBQVcsT0FBTTtBQUNqQjtBQUNlLHNEQUFRLEVBQUM7QUFDeEIscUM7O0FDVG1DO0FBQ25DO0FBQ0EsV0FBVyxTQUFRO0FBQ25CO0FBQ2Usd0RBQVMsRUFBQztBQUN6QixzQzs7QUNMbUM7QUFDbkM7QUFDQSxXQUFXLFNBQVE7QUFDbkI7QUFDZSxrREFBTSxFQUFDO0FBQ3RCLG1DOztBQ0xtQztBQUNuQztBQUNBLFdBQVcsU0FBUTtBQUNuQjtBQUNlLHdEQUFTLEVBQUM7QUFDekIsc0M7O0FDTG1DO0FBQ25DO0FBQ0EsV0FBVyxTQUFRO0FBQ25CO0FBQ2UsMERBQVUsRUFBQztBQUMxQix1Qzs7QUNMQSx3QkFBd0I7QUFDVDtBQUNmLCtCQUErQix1QkFBdUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0EsMkM7O0FDTm1DO0FBQ25DO0FBQ0EsV0FBVyxTQUFRO0FBQ25CO0FBQ2UsZ0RBQUssRUFBQztBQUNyQixrQzs7QUNMbUM7QUFDbkM7QUFDQSxXQUFXLFNBQVE7QUFDbkI7QUFDZSwwREFBVSxFQUFDO0FBQzFCLHVDOztBQ0xpQztBQUNNO0FBQ3ZDO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFdBQVcsU0FBUztBQUNwQixZQUFZLEVBQUU7QUFDZDtBQUNBO0FBQ0EsbUJBQW1CLFNBQVMsR0FBRyxTQUFTO0FBQ3hDO0FBQ0EsK0JBQStCLFlBQVksRUFBRTtBQUM3QyxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNnQjtBQUNoQixTQUFTLFFBQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0EsZ0JBQWdCLFdBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxFQUFFO0FBQ0gsa0M7O0FDaENpQztBQUNNO0FBQ3ZDO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFdBQVcsU0FBUztBQUNwQixZQUFZLEVBQUU7QUFDZDtBQUNBO0FBQ0EsbUJBQW1CLFNBQVMsR0FBRyxTQUFTO0FBQ3hDO0FBQ0EsK0JBQStCLFlBQVksRUFBRTtBQUM3QyxVQUFVO0FBQ1Y7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNnQjtBQUNoQixTQUFTLFFBQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0EsZ0JBQWdCLFdBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxFQUFFO0FBQ0gsa0M7O0FDaENBO0FBQ0E7QUFDQTtBQUNlLCtDQUFHLEVBQUM7QUFDbkIsK0I7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDZSxzREFBUSxFQUFDO0FBQ3hCLHFDOztBQ0xlLHVEQUFRLEVBQUM7QUFDeEIsc0M7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDZSxzREFBUSxFQUFDO0FBQ3hCLHFDOztBQ0wwQjtBQUNYLG1EQUFJLEVBQUM7QUFDcEIsa0M7O0FDRmdCLDZEQUFxQixnQ0FBZ0MsRUFBRSxFQUFFO0FBQ3pFLCtCOztBQ0R3QjtBQUNULCtDQUFHLEVBQUM7QUFDbkIsbUM7O0FDRjBCO0FBQ2E7QUFDdkM7QUFDQSxJQUFJLGFBQU0sbUNBQW1DLDJCQUEyQixFQUFFO0FBQzFFO0FBQ0EsSUFBSSxRQUFJO0FBQ1IsY0FBYyxXQUFVO0FBQ3hCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNlLDREQUFNLEVBQUM7QUFDdEIsa0M7O0FDYmtDO0FBQ0o7QUFDZCxxRUFBdUIsUUFBUSxZQUFRLENBQUMsVUFBTSxjQUFjLEVBQUUsRUFBRTtBQUNoRixxQzs7QUNINkI7QUFDYjtBQUNoQixRQUFRLE1BQUs7QUFDYjtBQUNBO0FBQ0EsQ0FBQyxFQUFFO0FBQ0gscUM7O0FDTm1DO0FBQ25DO0FBQ0EsV0FBVyxTQUFRO0FBQ25CO0FBQ2Usd0RBQVMsRUFBQztBQUN6QixzQzs7QUNMbUM7QUFDbkM7QUFDQSxjQUFjLFNBQVE7QUFDdEI7QUFDQTtBQUNlLDBEQUFVLEVBQUM7QUFDMUIsdUM7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsS0FBSyxLQUFLO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ2UsNkRBQVUsRUFBQztBQUMxQixzQzs7QUNabUM7QUFDbkM7QUFDQSxXQUFXLFNBQVE7QUFDbkI7QUFDZSx3REFBUyxFQUFDO0FBQ3pCLHNDOztBQ0xtQztBQUNuQztBQUNBLGNBQWMsU0FBUTtBQUN0QjtBQUNBO0FBQ2UsMERBQVUsRUFBQztBQUMxQix1Qzs7QUNOQSxJQUFJLGlCQUFRLEtBQUs7QUFDakI7QUFDQSxXQUFXLGlCQUFRO0FBQ25CO0FBQ2Usb0RBQU8sRUFBQztBQUN2QixvQzs7QUNMQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsWUFBWTtBQUNaO0FBQytCO0FBQy9CO0FBQ0EsV0FBVyxPQUFNO0FBQ2pCO0FBQ2UsNERBQVcsRUFBQztBQUMzQix3Qzs7QUNYQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsWUFBWTtBQUNaO0FBQytCO0FBQy9CO0FBQ0EsV0FBVyxPQUFNO0FBQ2pCO0FBQ2Usd0RBQVMsRUFBQztBQUN6QixzQzs7QUNYK0I7QUFDL0I7QUFDQSxXQUFXLE9BQU07QUFDakI7QUFDZSxrREFBTSxFQUFDO0FBQ3RCLG1DOztBQ0xBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixZQUFZO0FBQ1o7QUFDK0I7QUFDL0I7QUFDQSxXQUFXLE9BQU07QUFDakI7QUFDZSxvREFBTyxFQUFDO0FBQ3ZCLG9DOztBQ1hBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDbUM7QUFDcEI7QUFDZixXQUFXLFNBQVE7QUFDbkIsQ0FBQztBQUNELHFDOztBQ1JBO0FBQ0E7QUFDQTtBQUNlLGtEQUFNLEVBQUM7QUFDdEIsbUM7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsNERBQVcsRUFBQztBQUMzQix3Qzs7QUNQK0I7QUFDL0I7QUFDQSxXQUFXLE9BQU07QUFDakI7QUFDZSx1REFBUSxFQUFDO0FBQ3hCLHNDOztBQ0xBO0FBQ0E7QUFDQTtBQUNlLDREQUFXLEVBQUM7QUFDM0Isd0M7O0FDSkE7QUFDQTtBQUNBLFlBQVksUUFBUTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNlLHdEQUFTLEVBQUM7QUFDekIsc0M7O0FDUmU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRDs7QUNiZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUQ7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCOztBQ2pCd0I7QUFDZTtBQUN2QztBQUNBO0FBQ0Esb0JBQW9CLHVCQUF1QjtBQUMzQztBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0EsWUFBWSxXQUFVO0FBQ3RCO0FBQ0E7QUFDQSxRQUFRLEdBQUc7QUFDWDtBQUNBO0FBQ2UsdURBQU8sRUFBQztBQUN2QixtQzs7QUNqQmlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFFBQU87QUFDZjtBQUNBLHVDQUF1QyxPQUFPO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLG1EQUFLLEVBQUM7QUFDckIsaUM7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLHlEQUFRLEVBQUM7QUFDeEIsb0M7O0FDbkJ1QztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZ0I7QUFDaEIsU0FBUyxXQUFVO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHVCQUF1QjtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLEVBQUU7QUFDSCxtQzs7QUM5QmlDO0FBQ2E7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsZUFBYTtBQUMvQyxxQkFBcUIsZUFBYTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsUUFBTztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsdUJBQXVCO0FBQzNDO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ2Usb0RBQU8sRUFBQztBQUN2QixvQzs7QUMxQ3dCO0FBQ2U7QUFDdkM7QUFDQTtBQUNBLFNBQVMsV0FBVTtBQUNuQjtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEO0FBQzFELHlCQUF5QixHQUFHLCtCQUErQjtBQUMzRDtBQUNBLElBQUksR0FBRztBQUNQLElBQUksR0FBRztBQUNQO0FBQ0E7QUFDZSxxREFBTSxFQUFDO0FBQ3RCLGtDOztBQ2hDMEM7QUFDMUMsSUFBSSxnQkFBTztBQUNYLFNBQVMsYUFBVztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixnQkFBZ0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSw2REFBTyxFQUFDO0FBQ3ZCLG9DOztBQ25CNkI7QUFDYTtBQUNUO0FBQ1E7QUFDekMsSUFBSSx1QkFBYztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQSxRQUFRLE1BQUs7QUFDYjtBQUNBO0FBQ0EsUUFBUSxhQUFXO0FBQ25CO0FBQ0E7QUFDQSxlQUFlLFFBQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFXO0FBQ25CO0FBQ0E7QUFDQTtBQUNBLFlBQVksdUJBQWM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLG9EQUFPLEVBQUM7QUFDdkIsb0M7O0FDcEM0QztBQUNGO0FBQ1A7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFNBQVEsV0FBVyxTQUFRO0FBQ25DO0FBQ0E7QUFDQSxRQUFRLGFBQVcsV0FBVyxhQUFXO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGtCQUFrQjtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsY0FBWSxXQUFXLGNBQVk7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSxvREFBTyxFQUFDO0FBQ3ZCLG9DOztBQzVDdUM7QUFDTjtBQUNqQztBQUNBLFdBQVcsRUFBRTtBQUNiLFdBQVcsRUFBRTtBQUNiLFdBQVcsU0FBUztBQUNwQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ2dCO0FBQ2hCLFNBQVMsV0FBVTtBQUNuQixlQUFlLFFBQU87QUFDdEI7QUFDQTtBQUNBLENBQUMsRUFBRTtBQUNILHlDOztBQzlCMEM7QUFDMUM7QUFDQSxTQUFTLGFBQVc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsb0JBQW9CO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSwrQ0FBRyxFQUFDO0FBQ25CLCtCOztBQ2Q2QjtBQUNNO0FBQ25DLDZCQUE2QixVQUFVO0FBQ3ZCO0FBQ2hCLDBCQUEwQixpQkFBaUI7QUFDM0M7QUFDQSxRQUFRLFNBQVEsYUFBYSxNQUFLO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsQ0FBQyxFQUFFO0FBQ0gsc0M7O0FDZG1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNnQjtBQUNoQjtBQUNBLGlCQUFpQixTQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxFQUFFO0FBQ0gsK0I7O0FDZm1DO0FBQ0E7QUFDQTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZ0I7QUFDaEI7QUFDQSxpQkFBaUIsU0FBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUTtBQUN6Qix5QkFBeUIsU0FBUTtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDLEVBQUU7QUFDSCwrQjs7QUMxQjBCO0FBQ29CO0FBQzlDLElBQUksbUJBQWM7QUFDRjtBQUNoQiw0QkFBNEIsZUFBYTtBQUN6QztBQUNBO0FBQ0E7QUFDQSxJQUFJLFFBQUk7QUFDUixZQUFZLG1CQUFjO0FBQzFCO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDLEVBQUU7QUFDSCxnQzs7QUNmOEI7QUFDZDtBQUNoQixXQUFXLFVBQU07QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLLElBQUk7QUFDVCxDQUFDLEVBQUU7QUFDSCxnQzs7QUNUZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxFQUFFO0FBQ0gsb0M7O0FDekMwQztBQUMxQjtBQUNoQixXQUFXLGFBQVc7QUFDdEIsQ0FBQyxFQUFFO0FBQ0gsb0M7O0FDSkEsSUFBSSxhQUFHO0FBQ1M7QUFDaEI7QUFDQSxTQUFTLGFBQUc7QUFDWixRQUFRLGFBQUc7QUFDWDtBQUNBO0FBQ0EsUUFBUSxhQUFHO0FBQ1g7QUFDQSxvQkFBb0IsYUFBRztBQUN2QixDQUFDLEVBQUU7QUFDSCxxQzs7QUNYZ0Isc0RBQWEsRUFBRSxFQUFFO0FBQ2pDLGdDOztBQ0RnQiwrREFBYyxVQUFVLEVBQUUsRUFBRTtBQUM1QyxvQzs7QUNENkI7QUFDYTtBQUMzQjtBQUNmLFFBQVEsTUFBSztBQUNiO0FBQ0E7QUFDQSxRQUFRLGFBQVc7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7Ozs7QUNYdUM7QUFDVDtBQUNFO0FBQ0c7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDZSw4REFBTztBQUN0QiwwQkFBMEIsV0FBVztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLFNBQVE7QUFDbkMsQ0FBQztBQUNELDBCQUEwQixXQUFXO0FBQ3JDLFdBQVcsbUNBQWMsU0FBUyxVQUFNO0FBQ3hDLENBQUMsQ0FBQyxFQUFDO0FBQ0gsOEM7O0FDcEJtQztBQUNBO0FBQ2dDO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2dCO0FBQ2hCLHlCQUF5QixhQUFhO0FBQ3RDLGtCQUFrQjtBQUNsQiw0QkFBNEIsa0JBQWdCO0FBQzVDLG9CQUFvQixTQUFRLFNBQVMsU0FBUTtBQUM3QztBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0EsUUFBUSxrQkFBZ0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixrQkFBZ0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGtCQUFnQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsRUFBRTtBQUNILDZDOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ2MsbURBQVMsRUFBQztBQUN6QixpQzs7QUM3QkE7QUFDc0U7QUFDakI7QUFDWjtBQUNXO0FBQ0U7QUFDUDtBQUNTO0FBQ047QUFDVDtBQUNLO0FBQ0Q7QUFDQTtBQUNDO0FBQ0g7QUFDRjtBQUNnQjtBQUNoQjtBQUNBO0FBQ2E7QUFDSjtBQUNMO0FBQ0Y7QUFDRjtBQUNFO0FBQ0s7QUFDTztBQUN2RDtBQUNpRTtBQUNQO0FBQzFEO0FBQ3lEO0FBQ0Q7QUFDeEQ7QUFDMkM7QUFDUztBQUNBO0FBQ047QUFDTTtBQUNFO0FBQ087QUFDakI7QUFDVTtBQUNmO0FBQ0s7QUFDTDtBQUNLO0FBQ0w7QUFDVztBQUNFO0FBQ0Y7QUFDbEQ7QUFDNEM7QUFDTDtBQUNPO0FBQ0k7QUFDVDtBQUNPO0FBQ0g7QUFDN0M7QUFDb0Q7QUFDRTtBQUNEO0FBQ0Q7QUFDRTtBQUN0RDtBQUNnRDtBQUNRO0FBQ1I7QUFDUztBQUNMO0FBQ047QUFDRTtBQUNNO0FBQ0o7QUFDTjtBQUNFO0FBQ0k7QUFDQTtBQUNTO0FBQ0U7QUFDTDtBQUNMO0FBQ0Q7QUFDSjtBQUNVO0FBQ0o7QUFDeUI7QUFDSjtBQUN6RTtBQUMrQztBQUNKO0FBQ007QUFDRjtBQUNDO0FBQ1A7QUFDSTtBQUNHO0FBQ0E7QUFDQTtBQUNTO0FBQ2xCO0FBQ2E7QUFDTTtBQUNuQjtBQUNBO0FBQ0U7QUFDQTtBQUNRO0FBQ0Q7QUFDRTtBQUNBO0FBQ1Q7QUFDUTtBQUNSO0FBQ3pDO0FBQ21FO0FBQ0Y7QUFDakU7QUFDMkM7QUFDM0MiLCJmaWxlIjoiMC5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBpc0FycmF5TGlrZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8qKlxuICAgICAqIGlzQXJyYXlMaWtlKFsxLCAyLCAzXSkgPT4gdHJ1ZVxuICAgICAqIGlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pID0+IHRydWVcbiAgICAgKiBpc0FycmF5TGlrZSgnYWJjJykgPT4gdHJ1ZVxuICAgICAqIGlzQXJyYXlMaWtlKEZ1bmN0aW9uKSA9PiBmYWxzZVxuICAgICAqL1xuICAgIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgaXNGaW5pdGUodmFsdWUubGVuZ3RoKTtcbn07XG5leHBvcnQgZGVmYXVsdCBpc0FycmF5TGlrZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFycmF5LWxpa2UuanMubWFwIiwiaW1wb3J0IGlzQXJyYXlMaWtlIGZyb20gJy4vaXMtYXJyYXktbGlrZSc7XG52YXIgY29udGFpbnMgPSBmdW5jdGlvbiAoYXJyLCB2YWx1ZSkge1xuICAgIGlmICghaXNBcnJheUxpa2UoYXJyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBhcnIuaW5kZXhPZih2YWx1ZSkgPiAtMTtcbn07XG5leHBvcnQgZGVmYXVsdCBjb250YWlucztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnRhaW5zLmpzLm1hcCIsImltcG9ydCBpc0FycmF5TGlrZSBmcm9tICcuL2lzLWFycmF5LWxpa2UnO1xudmFyIGZpbHRlciA9IGZ1bmN0aW9uIChhcnIsIGZ1bmMpIHtcbiAgICBpZiAoIWlzQXJyYXlMaWtlKGFycikpIHtcbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBhcnIubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycltpbmRleF07XG4gICAgICAgIGlmIChmdW5jKHZhbHVlLCBpbmRleCkpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbmV4cG9ydCBkZWZhdWx0IGZpbHRlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbHRlci5qcy5tYXAiLCJpbXBvcnQgZmlsdGVyIGZyb20gJy4vZmlsdGVyJztcbmltcG9ydCBjb250YWlucyBmcm9tICcuL2NvbnRhaW5zJztcbi8qKlxuICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyciBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gKiBAcmV0dXJuIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAqIEBleGFtcGxlXG4gKiBkaWZmZXJlbmNlKFsyLCAxXSwgWzIsIDNdKTsgIC8vID0+IFsxXVxuICovXG52YXIgZGlmZmVyZW5jZSA9IGZ1bmN0aW9uIChhcnIsIHZhbHVlcykge1xuICAgIGlmICh2YWx1ZXMgPT09IHZvaWQgMCkgeyB2YWx1ZXMgPSBbXTsgfVxuICAgIHJldHVybiBmaWx0ZXIoYXJyLCBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuICFjb250YWlucyh2YWx1ZXMsIHZhbHVlKTsgfSk7XG59O1xuZXhwb3J0IGRlZmF1bHQgZGlmZmVyZW5jZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpZmZlcmVuY2UuanMubWFwIiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG52YXIgaXNUeXBlID0gZnVuY3Rpb24gKHZhbHVlLCB0eXBlKSB7IHJldHVybiB0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgJyArIHR5cGUgKyAnXSc7IH07XG5leHBvcnQgZGVmYXVsdCBpc1R5cGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy10eXBlLmpzLm1hcCIsIi8qKlxuICog5piv5ZCm5Li65Ye95pWwXG4gKiBAcGFyYW0gIHsqfSBmbiDlr7nosaFcbiAqIEByZXR1cm4ge0Jvb2xlYW59ICDmmK/lkKblh73mlbBcbiAqL1xuaW1wb3J0IGlzVHlwZSBmcm9tICcuL2lzLXR5cGUnO1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc1R5cGUodmFsdWUsICdGdW5jdGlvbicpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1mdW5jdGlvbi5qcy5tYXAiLCIvLyBpc0Zpbml0ZSxcbnZhciBpc05pbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8qKlxuICAgICAqIGlzTmlsKG51bGwpID0+IHRydWVcbiAgICAgKiBpc05pbCgpID0+IHRydWVcbiAgICAgKi9cbiAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZDtcbn07XG5leHBvcnQgZGVmYXVsdCBpc05pbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5pbC5qcy5tYXAiLCJpbXBvcnQgaXNUeXBlIGZyb20gJy4vaXMtdHlwZSc7XG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkgP1xuICAgICAgICBBcnJheS5pc0FycmF5KHZhbHVlKSA6XG4gICAgICAgIGlzVHlwZSh2YWx1ZSwgJ0FycmF5Jyk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFycmF5LmpzLm1hcCIsImV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvKipcbiAgICAgKiBpc09iamVjdCh7fSkgPT4gdHJ1ZVxuICAgICAqIGlzT2JqZWN0KFsxLCAyLCAzXSkgPT4gdHJ1ZVxuICAgICAqIGlzT2JqZWN0KEZ1bmN0aW9uKSA9PiB0cnVlXG4gICAgICogaXNPYmplY3QobnVsbCkgPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdHlwZSA9PT0gJ29iamVjdCcgfHwgdHlwZSA9PT0gJ2Z1bmN0aW9uJztcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtb2JqZWN0LmpzLm1hcCIsImltcG9ydCBpc0FycmF5IGZyb20gJy4vaXMtYXJyYXknO1xuaW1wb3J0IGlzT2JqZWN0IGZyb20gJy4vaXMtb2JqZWN0JztcbmZ1bmN0aW9uIGVhY2goZWxlbWVudHMsIGZ1bmMpIHtcbiAgICBpZiAoIWVsZW1lbnRzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHJzdDtcbiAgICBpZiAoaXNBcnJheShlbGVtZW50cykpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGVsZW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICByc3QgPSBmdW5jKGVsZW1lbnRzW2ldLCBpKTtcbiAgICAgICAgICAgIGlmIChyc3QgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAoaXNPYmplY3QoZWxlbWVudHMpKSB7XG4gICAgICAgIGZvciAodmFyIGsgaW4gZWxlbWVudHMpIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50cy5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICAgICAgICAgIHJzdCA9IGZ1bmMoZWxlbWVudHNba10sIGspO1xuICAgICAgICAgICAgICAgIGlmIChyc3QgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IGVhY2g7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lYWNoLmpzLm1hcCIsImltcG9ydCBlYWNoIGZyb20gJy4vZWFjaCc7XG5pbXBvcnQgaXNGdW5jdGlvbiBmcm9tICcuL2lzLWZ1bmN0aW9uJztcbnZhciBrZXlzID0gT2JqZWN0LmtleXMgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBPYmplY3Qua2V5cyhvYmopOyB9IDogZnVuY3Rpb24gKG9iaikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICBlYWNoKG9iaiwgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgaWYgKCEoaXNGdW5jdGlvbihvYmopICYmIGtleSA9PT0gJ3Byb3RvdHlwZScpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5leHBvcnQgZGVmYXVsdCBrZXlzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9a2V5cy5qcy5tYXAiLCJpbXBvcnQgaXNOaWwgZnJvbSAnLi9pcy1uaWwnO1xuaW1wb3J0IGtleXMgZnJvbSAnLi9rZXlzJztcbmZ1bmN0aW9uIGlzTWF0Y2gob2JqLCBhdHRycykge1xuICAgIHZhciBfa2V5cyA9IGtleXMoYXR0cnMpO1xuICAgIHZhciBsZW5ndGggPSBfa2V5cy5sZW5ndGg7XG4gICAgaWYgKGlzTmlsKG9iaikpXG4gICAgICAgIHJldHVybiAhbGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdmFyIGtleSA9IF9rZXlzW2ldO1xuICAgICAgICBpZiAoYXR0cnNba2V5XSAhPT0gb2JqW2tleV0gfHwgIShrZXkgaW4gb2JqKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZXhwb3J0IGRlZmF1bHQgaXNNYXRjaDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW1hdGNoLmpzLm1hcCIsInZhciBpc09iamVjdExpa2UgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvKipcbiAgICAgKiBpc09iamVjdExpa2Uoe30pID0+IHRydWVcbiAgICAgKiBpc09iamVjdExpa2UoWzEsIDIsIDNdKSA9PiB0cnVlXG4gICAgICogaXNPYmplY3RMaWtlKEZ1bmN0aW9uKSA9PiBmYWxzZVxuICAgICAqIGlzT2JqZWN0TGlrZShudWxsKSA9PiBmYWxzZVxuICAgICAqL1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzT2JqZWN0TGlrZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW9iamVjdC1saWtlLmpzLm1hcCIsImltcG9ydCBpc09iamVjdExpa2UgZnJvbSAnLi9pcy1vYmplY3QtbGlrZSc7XG5pbXBvcnQgaXNUeXBlIGZyb20gJy4vaXMtdHlwZSc7XG52YXIgaXNQbGFpbk9iamVjdCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8qKlxuICAgICAqIGlzT2JqZWN0TGlrZShuZXcgRm9vKSA9PiBmYWxzZVxuICAgICAqIGlzT2JqZWN0TGlrZShbMSwgMiwgM10pID0+IGZhbHNlXG4gICAgICogaXNPYmplY3RMaWtlKHsgeDogMCwgeTogMCB9KSA9PiB0cnVlXG4gICAgICogaXNPYmplY3RMaWtlKE9iamVjdC5jcmVhdGUobnVsbCkpID0+IHRydWVcbiAgICAgKi9cbiAgICBpZiAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgfHwgIWlzVHlwZSh2YWx1ZSwgJ09iamVjdCcpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHZhciBwcm90byA9IHZhbHVlO1xuICAgIHdoaWxlIChPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pICE9PSBudWxsKSB7XG4gICAgICAgIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT09IHByb3RvO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzUGxhaW5PYmplY3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wbGFpbi1vYmplY3QuanMubWFwIiwiaW1wb3J0IGlzRnVuY3Rpb24gZnJvbSAnLi9pcy1mdW5jdGlvbic7XG5pbXBvcnQgaXNNYXRjaCBmcm9tICcuL2lzLW1hdGNoJztcbmltcG9ydCBpc0FycmF5IGZyb20gJy4vaXMtYXJyYXknO1xuaW1wb3J0IGlzUGxhaW5PYmplY3QgZnJvbSAnLi9pcy1wbGFpbi1vYmplY3QnO1xuZnVuY3Rpb24gZmluZChhcnIsIHByZWRpY2F0ZSkge1xuICAgIGlmICghaXNBcnJheShhcnIpKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB2YXIgX3ByZWRpY2F0ZTtcbiAgICBpZiAoaXNGdW5jdGlvbihwcmVkaWNhdGUpKSB7XG4gICAgICAgIF9wcmVkaWNhdGUgPSBwcmVkaWNhdGU7XG4gICAgfVxuICAgIGlmIChpc1BsYWluT2JqZWN0KHByZWRpY2F0ZSkpIHtcbiAgICAgICAgX3ByZWRpY2F0ZSA9IGZ1bmN0aW9uIChhKSB7IHJldHVybiBpc01hdGNoKGEsIHByZWRpY2F0ZSk7IH07XG4gICAgfVxuICAgIGlmIChfcHJlZGljYXRlKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAoX3ByZWRpY2F0ZShhcnJbaV0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycltpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmV4cG9ydCBkZWZhdWx0IGZpbmQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maW5kLmpzLm1hcCIsImZ1bmN0aW9uIGZpbmRJbmRleChhcnIsIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgaWYgKGZyb21JbmRleCA9PT0gdm9pZCAwKSB7IGZyb21JbmRleCA9IDA7IH1cbiAgICBmb3IgKHZhciBpID0gZnJvbUluZGV4OyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUoYXJyW2ldLCBpKSkge1xuICAgICAgICAgICAgLy8g5om+5Yiw57uI5q2i5b6q546vXG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG5leHBvcnQgZGVmYXVsdCBmaW5kSW5kZXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maW5kLWluZGV4LmpzLm1hcCIsImltcG9ydCBpc05pbCBmcm9tICcuL2lzLW5pbCc7XG5pbXBvcnQgaXNBcnJheSBmcm9tICcuL2lzLWFycmF5JztcbnZhciBmaXJzdFZhbHVlID0gZnVuY3Rpb24gKGRhdGEsIG5hbWUpIHtcbiAgICB2YXIgcnN0ID0gbnVsbDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIG9iaiA9IGRhdGFbaV07XG4gICAgICAgIHZhciB2YWx1ZSA9IG9ialtuYW1lXTtcbiAgICAgICAgaWYgKCFpc05pbCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHJzdCA9IHZhbHVlWzBdOyAvLyB0b2RvIOi/memHjOaYr+WQpuW6lOivpeS9v+eUqOmAkuW9ku+8jOiwg+eUqCBmaXJzdFZhbHVlIEDnu53kupFcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJzdCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJzdDtcbn07XG5leHBvcnQgZGVmYXVsdCBmaXJzdFZhbHVlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Zmlyc3QtdmFsdWUuanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG4vKipcbiAqIEZsYXR0ZW5zIGBhcnJheWAgYSBzaW5nbGUgbGV2ZWwgZGVlcC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnIgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gKiBAcmV0dXJuIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZmxhdHRlbihbMSwgWzIsIFszLCBbNF1dLCA1XV0pOyAgLy8gPT4gWzEsIDIsIFszLCBbNF1dLCA1XVxuICovXG52YXIgZmxhdHRlbiA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgICBpZiAoIWlzQXJyYXkoYXJyKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHZhciByc3QgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICByc3QgPSByc3QuY29uY2F0KGFycltpXSk7XG4gICAgfVxuICAgIHJldHVybiByc3Q7XG59O1xuZXhwb3J0IGRlZmF1bHQgZmxhdHRlbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZsYXR0ZW4uanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG4vKipcbiAqIEZsYXR0ZW5zIGBhcnJheWAgYSBzaW5nbGUgbGV2ZWwgZGVlcC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnIgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gKiBAcGFyYW0ge0FycmF5fSByZXN1bHQgVGhlIGFycmF5IHRvIHJldHVybi5cbiAqIEByZXR1cm4ge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBmbGF0dGVuRGVlcChbMSwgWzIsIFszLCBbNF1dLCA1XV0pOyAgLy8gPT4gWzEsIDIsIDMsIDQsIDVdXG4gKi9cbnZhciBmbGF0dGVuRGVlcCA9IGZ1bmN0aW9uIChhcnIsIHJlc3VsdCkge1xuICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgeyByZXN1bHQgPSBbXTsgfVxuICAgIGlmICghaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGFycik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgZmxhdHRlbkRlZXAoYXJyW2ldLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuZXhwb3J0IGRlZmF1bHQgZmxhdHRlbkRlZXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mbGF0dGVuLWRlZXAuanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG4vKipcbiAqIEBwYXJhbSB7QXJyYXl9IGFyciBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHJldHVybiB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKlxuICogbWF4KFsxLCAyXSk7XG4gKiAvLyA9PiAyXG4gKlxuICogbWF4KFtdKTtcbiAqIC8vID0+IHVuZGVmaW5lZFxuICpcbiAqIGNvbnN0IGRhdGEgPSBuZXcgQXJyYXkoMTI1MDAxMCkuZmlsbCgxKS5tYXAoKGQsaWR4KSA9PiBpZHgpO1xuICpcbiAqIG1heChkYXRhKTtcbiAqIC8vID0+IDEyNTAwMTBcbiAqIC8vIE1hdGgubWF4KC4uLmRhdGEpIHdpbGwgZW5jb3VudGVyIFwiTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIiBlcnJvclxuICovXG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKGFycikge1xuICAgIGlmICghaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBhcnIucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7XG4gICAgICAgIHJldHVybiBNYXRoLm1heChwcmV2LCBjdXJyKTtcbiAgICB9LCBhcnJbMF0pO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXguanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG4vKipcbiAqIEBwYXJhbSB7QXJyYXl9IGFyciBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHJldHVybiB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKlxuICogbWluKFsxLCAyXSk7XG4gKiAvLyA9PiAxXG4gKlxuICogbWluKFtdKTtcbiAqIC8vID0+IHVuZGVmaW5lZFxuICpcbiAqIGNvbnN0IGRhdGEgPSBuZXcgQXJyYXkoMTI1MDAxMCkuZmlsbCgxKS5tYXAoKGQsaWR4KSA9PiBpZHgpO1xuICpcbiAqIG1pbihkYXRhKTtcbiAqIC8vID0+IDEyNTAwMTBcbiAqIC8vIE1hdGgubWluKC4uLmRhdGEpIHdpbGwgZW5jb3VudGVyIFwiTWF4aW11bSBjYWxsIHN0YWNrIHNpemUgZXhjZWVkZWRcIiBlcnJvclxuICovXG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKGFycikge1xuICAgIGlmICghaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBhcnIucmVkdWNlKGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7XG4gICAgICAgIHJldHVybiBNYXRoLm1pbihwcmV2LCBjdXJyKTtcbiAgICB9LCBhcnJbMF0pO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW4uanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG5pbXBvcnQgeyBkZWZhdWx0IGFzIGdldE1heCB9IGZyb20gJy4vbWF4JztcbmltcG9ydCB7IGRlZmF1bHQgYXMgZ2V0TWluIH0gZnJvbSAnLi9taW4nO1xudmFyIGdldFJhbmdlID0gZnVuY3Rpb24gKHZhbHVlcykge1xuICAgIC8vIOWtmOWcqCBOYU4g5pe277yMbWluLG1heCDliKTlrprkvJrlh7rpl67pophcbiAgICB2YXIgZmlsdGVyVmFsdWVzID0gdmFsdWVzLmZpbHRlcihmdW5jdGlvbiAodikgeyByZXR1cm4gIWlzTmFOKHYpOyB9KTtcbiAgICBpZiAoIWZpbHRlclZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgLy8g5aaC5p6c5rKh5pyJ5pWw5YC85YiZ55u05o6l6L+U5ZueMFxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoaXNBcnJheSh2YWx1ZXNbMF0pKSB7XG4gICAgICAgIHZhciB0bXAgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRtcCA9IHRtcC5jb25jYXQodmFsdWVzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBmaWx0ZXJWYWx1ZXMgPSB0bXA7XG4gICAgfVxuICAgIHZhciBtYXggPSBnZXRNYXgoZmlsdGVyVmFsdWVzKTtcbiAgICB2YXIgbWluID0gZ2V0TWluKGZpbHRlclZhbHVlcyk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluOiBtaW4sXG4gICAgICAgIG1heDogbWF4LFxuICAgIH07XG59O1xuZXhwb3J0IGRlZmF1bHQgZ2V0UmFuZ2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtcmFuZ2UuanMubWFwIiwidmFyIGFyclByb3RvdHlwZSA9IEFycmF5LnByb3RvdHlwZTtcbnZhciBzcGxpY2UgPSBhcnJQcm90b3R5cGUuc3BsaWNlO1xudmFyIGluZGV4T2YgPSBhcnJQcm90b3R5cGUuaW5kZXhPZjtcbnZhciBwdWxsID0gZnVuY3Rpb24gKGFycikge1xuICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YWx1ZXNbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICAgICAgdmFyIGZyb21JbmRleCA9IC0xO1xuICAgICAgICB3aGlsZSAoKGZyb21JbmRleCA9IGluZGV4T2YuY2FsbChhcnIsIHZhbHVlKSkgPiAtMSkge1xuICAgICAgICAgICAgc3BsaWNlLmNhbGwoYXJyLCBmcm9tSW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnI7XG59O1xuZXhwb3J0IGRlZmF1bHQgcHVsbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXB1bGwuanMubWFwIiwiaW1wb3J0IGlzQXJyYXlMaWtlIGZyb20gJy4vaXMtYXJyYXktbGlrZSc7XG52YXIgc3BsaWNlID0gQXJyYXkucHJvdG90eXBlLnNwbGljZTtcbnZhciBwdWxsQXQgPSBmdW5jdGlvbiBwdWxsQXQoYXJyLCBpbmRleGVzKSB7XG4gICAgaWYgKCFpc0FycmF5TGlrZShhcnIpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdmFyIGxlbmd0aCA9IGFyciA/IGluZGV4ZXMubGVuZ3RoIDogMDtcbiAgICB2YXIgbGFzdCA9IGxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBwcmV2aW91cyA9IHZvaWQgMDtcbiAgICAgICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgICAgICBpZiAobGVuZ3RoID09PSBsYXN0IHx8IGluZGV4ICE9PSBwcmV2aW91cykge1xuICAgICAgICAgICAgcHJldmlvdXMgPSBpbmRleDtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKGFyciwgaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnI7XG59O1xuZXhwb3J0IGRlZmF1bHQgcHVsbEF0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cHVsbC1hdC5qcy5tYXAiLCJpbXBvcnQgZWFjaCBmcm9tICcuL2VhY2gnO1xuaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG5pbXBvcnQgaXNQbGFpbk9iamVjdCBmcm9tICcuL2lzLXBsYWluLW9iamVjdCc7XG52YXIgcmVkdWNlID0gZnVuY3Rpb24gKGFyciwgZm4sIGluaXQpIHtcbiAgICBpZiAoIWlzQXJyYXkoYXJyKSAmJiAhaXNQbGFpbk9iamVjdChhcnIpKSB7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSBpbml0O1xuICAgIGVhY2goYXJyLCBmdW5jdGlvbiAoZGF0YSwgaSkge1xuICAgICAgICByZXN1bHQgPSBmbihyZXN1bHQsIGRhdGEsIGkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuZXhwb3J0IGRlZmF1bHQgcmVkdWNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVkdWNlLmpzLm1hcCIsImltcG9ydCBpc0FycmF5TGlrZSBmcm9tICcuL2lzLWFycmF5LWxpa2UnO1xuaW1wb3J0IHB1bGxBdCBmcm9tICcuL3B1bGwtYXQnO1xudmFyIHJlbW92ZSA9IGZ1bmN0aW9uIChhcnIsIHByZWRpY2F0ZSkge1xuICAgIC8qKlxuICAgICAqIGNvbnN0IGFyciA9IFsxLCAyLCAzLCA0XVxuICAgICAqIGNvbnN0IGV2ZW5zID0gcmVtb3ZlKGFyciwgbiA9PiBuICUgMiA9PSAwKVxuICAgICAqIGNvbnNvbGUubG9nKGFycikgLy8gPT4gWzEsIDNdXG4gICAgICogY29uc29sZS5sb2coZXZlbnMpIC8vID0+IFsyLCA0XVxuICAgICAqL1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICBpZiAoIWlzQXJyYXlMaWtlKGFycikpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgdmFyIGkgPSAtMTtcbiAgICB2YXIgaW5kZXhlcyA9IFtdO1xuICAgIHZhciBsZW5ndGggPSBhcnIubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyW2ldO1xuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpLCBhcnIpKSB7XG4gICAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICBpbmRleGVzLnB1c2goaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHVsbEF0KGFyciwgaW5kZXhlcyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5leHBvcnQgZGVmYXVsdCByZW1vdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW1vdmUuanMubWFwIiwiaW1wb3J0IGlzVHlwZSBmcm9tICcuL2lzLXR5cGUnO1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gaXNUeXBlKHN0ciwgJ1N0cmluZycpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1zdHJpbmcuanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG5pbXBvcnQgaXNTdHJpbmcgZnJvbSAnLi9pcy1zdHJpbmcnO1xuaW1wb3J0IGlzRnVuY3Rpb24gZnJvbSAnLi9pcy1mdW5jdGlvbic7XG5mdW5jdGlvbiBzb3J0QnkoYXJyLCBrZXkpIHtcbiAgICB2YXIgY29tcGFyZXI7XG4gICAgaWYgKGlzRnVuY3Rpb24oa2V5KSkge1xuICAgICAgICBjb21wYXJlciA9IGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBrZXkoYSkgLSBrZXkoYik7IH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIga2V5c18xID0gW107XG4gICAgICAgIGlmIChpc1N0cmluZyhrZXkpKSB7XG4gICAgICAgICAgICBrZXlzXzEucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAga2V5c18xID0ga2V5O1xuICAgICAgICB9XG4gICAgICAgIGNvbXBhcmVyID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5c18xLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIHByb3AgPSBrZXlzXzFbaV07XG4gICAgICAgICAgICAgICAgaWYgKGFbcHJvcF0gPiBiW3Byb3BdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYVtwcm9wXSA8IGJbcHJvcF0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBhcnIuc29ydChjb21wYXJlcik7XG4gICAgcmV0dXJuIGFycjtcbn1cbmV4cG9ydCBkZWZhdWx0IHNvcnRCeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNvcnQtYnkuanMubWFwIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdW5pcShhcnIsIGNhY2hlKSB7XG4gICAgaWYgKGNhY2hlID09PSB2b2lkIDApIHsgY2FjaGUgPSBuZXcgTWFwKCk7IH1cbiAgICB2YXIgciA9IFtdO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGFyci5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGl0ZW0gPSBhcnJbaV07XG4gICAgICAgICAgICAvLyDliqDkuIDkuKogY2FjaGXvvIzmj5DljYfmgKfog71cbiAgICAgICAgICAgIGlmICghY2FjaGUuaGFzKGl0ZW0pKSB7XG4gICAgICAgICAgICAgICAgci5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgICAgIGNhY2hlLnNldChpdGVtLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVuaXEuanMubWFwIiwiaW1wb3J0IHVuaXEgZnJvbSAnLi91bmlxJztcbnZhciB1bmlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc291cmNlcyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHNvdXJjZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIHVuaXEoW10uY29uY2F0LmFwcGx5KFtdLCBzb3VyY2VzKSk7XG59O1xuZXhwb3J0IGRlZmF1bHQgdW5pb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD11bmlvbi5qcy5tYXAiLCJpbXBvcnQgaXNBcnJheSBmcm9tICcuL2lzLWFycmF5JztcbmltcG9ydCBpc05pbCBmcm9tICcuL2lzLW5pbCc7XG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKGRhdGEsIG5hbWUpIHtcbiAgICB2YXIgcnN0ID0gW107XG4gICAgdmFyIHRtcE1hcCA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgb2JqID0gZGF0YVtpXTtcbiAgICAgICAgdmFyIHZhbHVlID0gb2JqW25hbWVdO1xuICAgICAgICBpZiAoIWlzTmlsKHZhbHVlKSkge1xuICAgICAgICAgICAgLy8gZmxhdHRlblxuICAgICAgICAgICAgaWYgKCFpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsdWUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsID0gdmFsdWVbal07XG4gICAgICAgICAgICAgICAgLy8gdW5pcXVlXG4gICAgICAgICAgICAgICAgaWYgKCF0bXBNYXBbdmFsXSkge1xuICAgICAgICAgICAgICAgICAgICByc3QucHVzaCh2YWwpO1xuICAgICAgICAgICAgICAgICAgICB0bXBNYXBbdmFsXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByc3Q7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZhbHVlcy1vZi1rZXkuanMubWFwIiwiaW1wb3J0IGlzQXJyYXlMaWtlIGZyb20gJy4vaXMtYXJyYXktbGlrZSc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBoZWFkKG8pIHtcbiAgICBpZiAoaXNBcnJheUxpa2UobykpIHtcbiAgICAgICAgcmV0dXJuIG9bMF07XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1oZWFkLmpzLm1hcCIsImltcG9ydCBpc0FycmF5TGlrZSBmcm9tICcuL2lzLWFycmF5LWxpa2UnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGFzdChvKSB7XG4gICAgaWYgKGlzQXJyYXlMaWtlKG8pKSB7XG4gICAgICAgIHZhciBhcnIgPSBvO1xuICAgICAgICByZXR1cm4gYXJyW2Fyci5sZW5ndGggLSAxXTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWxhc3QuanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG5pbXBvcnQgaXNTdHJpbmcgZnJvbSAnLi9pcy1zdHJpbmcnO1xuZnVuY3Rpb24gc3RhcnRzV2l0aChhcnIsIGUpIHtcbiAgICByZXR1cm4gKGlzQXJyYXkoYXJyKSB8fCBpc1N0cmluZyhhcnIpKSA/IGFyclswXSA9PT0gZSA6IGZhbHNlO1xufVxuZXhwb3J0IGRlZmF1bHQgc3RhcnRzV2l0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXJ0cy13aXRoLmpzLm1hcCIsImltcG9ydCBpc0FycmF5IGZyb20gJy4vaXMtYXJyYXknO1xuaW1wb3J0IGlzU3RyaW5nIGZyb20gJy4vaXMtc3RyaW5nJztcbmZ1bmN0aW9uIGVuZHNXaXRoKGFyciwgZSkge1xuICAgIHJldHVybiAoaXNBcnJheShhcnIpIHx8IGlzU3RyaW5nKGFycikpID8gYXJyW2Fyci5sZW5ndGggLSAxXSA9PT0gZSA6IGZhbHNlO1xufVxuZXhwb3J0IGRlZmF1bHQgZW5kc1dpdGg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbmRzLXdpdGguanMubWFwIiwiLyoqXG4gKiDlj6ropoHmnInkuIDkuKrkuI3mu6HotrPmnaHku7blsLHov5Tlm54gZmFsc2VcbiAqIEBwYXJhbSBhcnJcbiAqIEBwYXJhbSBmdW5jXG4gKi9cbnZhciBldmVyeSA9IGZ1bmN0aW9uIChhcnIsIGZ1bmMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWZ1bmMoYXJyW2ldLCBpKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuZXhwb3J0IGRlZmF1bHQgZXZlcnk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVyeS5qcy5tYXAiLCIvKipcbiAqIOWPquimgeacieS4gOS4qua7oei2s+adoeS7tuWwsei/lOWbniB0cnVlXG4gKiBAcGFyYW0gYXJyXG4gKiBAcGFyYW0gZnVuY1xuICovXG52YXIgc29tZSA9IGZ1bmN0aW9uIChhcnIsIGZ1bmMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZnVuYyhhcnJbaV0sIGkpKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5leHBvcnQgZGVmYXVsdCBzb21lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c29tZS5qcy5tYXAiLCJpbXBvcnQgaXNBcnJheSBmcm9tICcuL2lzLWFycmF5JztcbmltcG9ydCBpc0Z1bmN0aW9uIGZyb20gJy4vaXMtZnVuY3Rpb24nO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbmZ1bmN0aW9uIGdyb3VwQnkoZGF0YSwgY29uZGl0aW9uKSB7XG4gICAgaWYgKCFjb25kaXRpb24gfHwgIWlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgLy8g5YW85a655pa55rOV5ZKMIOWtl+espuS4sueahOWGmeazlVxuICAgIHZhciBwcmVkaWNhdGUgPSBpc0Z1bmN0aW9uKGNvbmRpdGlvbikgPyBjb25kaXRpb24gOiBmdW5jdGlvbiAoaXRlbSkgeyByZXR1cm4gaXRlbVtjb25kaXRpb25dOyB9O1xuICAgIHZhciBrZXk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBpdGVtID0gZGF0YVtpXTtcbiAgICAgICAga2V5ID0gcHJlZGljYXRlKGl0ZW0pO1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgICAgIHJlc3VsdFtrZXldLnB1c2goaXRlbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IFtpdGVtXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZXhwb3J0IGRlZmF1bHQgZ3JvdXBCeTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdyb3VwLWJ5LmpzLm1hcCIsImltcG9ydCBpc0FycmF5IGZyb20gJy4vaXMtYXJyYXknO1xuaW1wb3J0IGlzRnVuY3Rpb24gZnJvbSAnLi9pcy1mdW5jdGlvbic7XG5pbXBvcnQgZ3JvdXBCeSBmcm9tICcuL2dyb3VwLWJ5Jztcbi8qKlxuICog5bCG5pWw5o2u5YiG57uE5oiQIG1hcFxuICogQHBhcmFtIGRhdGFcbiAqIEBwYXJhbSBjb25kaXRpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ3JvdXBUb01hcChkYXRhLCBjb25kaXRpb24pIHtcbiAgICBpZiAoIWNvbmRpdGlvbikge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgMDogZGF0YSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKCFpc0Z1bmN0aW9uKGNvbmRpdGlvbikpIHtcbiAgICAgICAgLy8g5aaC5p6c5piv5a2X56ym5Liy77yM5YiZ5oyJ54WnIGEqYiDpo47moLzmiJDmlbDnu4RcbiAgICAgICAgdmFyIHBhcmFtc2NvbmRpdGlvbl8xID0gaXNBcnJheShjb25kaXRpb24pID8gY29uZGl0aW9uIDogY29uZGl0aW9uLnJlcGxhY2UoL1xccysvZywgJycpLnNwbGl0KCcqJyk7XG4gICAgICAgIGNvbmRpdGlvbiA9IGZ1bmN0aW9uIChyb3cpIHtcbiAgICAgICAgICAgIHZhciB1bmlxdWUgPSAnXyc7IC8vIOmBv+WFjeWHuueOsOaVsOWtl+S9nOS4uktleeeahOaDheWGte+8jOS8mui/m+ihjOaMieeFp+aVsOWtl+eahOaOkuW6j1xuICAgICAgICAgICAgLy8g5qC55o2u5a2X5q615YiX6KGo55qE5YC877yM5ou85o6l5oiQIGtleVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYXJhbXNjb25kaXRpb25fMS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICB1bmlxdWUgKz0gcm93W3BhcmFtc2NvbmRpdGlvbl8xW2ldXSAmJiByb3dbcGFyYW1zY29uZGl0aW9uXzFbaV1dLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdW5pcXVlO1xuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gZ3JvdXBCeShkYXRhLCBjb25kaXRpb24pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z3JvdXAtdG8tbWFwLmpzLm1hcCIsImltcG9ydCBncm91cFRvTWFwIGZyb20gJy4vZ3JvdXAtdG8tbWFwJztcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoZGF0YSwgY29uZGl0aW9uKSB7XG4gICAgaWYgKCFjb25kaXRpb24pIHtcbiAgICAgICAgLy8g5rKh5pyJ5p2h5Lu277yM5YiZ6Ieq6Lqr5pS55oiQ5pWw57uEXG4gICAgICAgIHJldHVybiBbZGF0YV07XG4gICAgfVxuICAgIHZhciBncm91cHMgPSBncm91cFRvTWFwKGRhdGEsIGNvbmRpdGlvbik7XG4gICAgdmFyIGFycmF5ID0gW107XG4gICAgZm9yICh2YXIgaSBpbiBncm91cHMpIHtcbiAgICAgICAgYXJyYXkucHVzaChncm91cHNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdyb3VwLmpzLm1hcCIsIi8qKlxuICog6I635Y+W5bCB6KOF55qE5LqL5Lu2XG4gKiBAcHJvdGVjdGVkXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9iaiAgIOWvueixoVxuICogQHBhcmFtICB7U3RyaW5nfSBhY3Rpb24g5LqL5Lu25ZCN56ewXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gICAgICAgIOi/lOWbnuS6i+S7tuWkhOeQhuWHveaVsFxuICovXG5mdW5jdGlvbiBnZXRXcmFwQmVoYXZpb3Iob2JqLCBhY3Rpb24pIHtcbiAgICByZXR1cm4gb2JqWydfd3JhcF8nICsgYWN0aW9uXTtcbn1cbmV4cG9ydCBkZWZhdWx0IGdldFdyYXBCZWhhdmlvcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC13cmFwLWJlaGF2aW9yLmpzLm1hcCIsIi8qKlxuICog5bCB6KOF5LqL5Lu277yM5L6/5LqO5L2/55So5LiK5LiL5paHdGhpcyzlkozkvr/kuo7op6PpmaTkuovku7bml7bkvb/nlKhcbiAqIEBwcm90ZWN0ZWRcbiAqIEBwYXJhbSAge09iamVjdH0gb2JqICAg5a+56LGhXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGFjdGlvbiDkuovku7blkI3np7BcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSAgICAgICAg6L+U5Zue5LqL5Lu25aSE55CG5Ye95pWwXG4gKi9cbmZ1bmN0aW9uIHdyYXBCZWhhdmlvcihvYmosIGFjdGlvbikge1xuICAgIGlmIChvYmpbJ193cmFwXycgKyBhY3Rpb25dKSB7XG4gICAgICAgIHJldHVybiBvYmpbJ193cmFwXycgKyBhY3Rpb25dO1xuICAgIH1cbiAgICB2YXIgbWV0aG9kID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgb2JqW2FjdGlvbl0oZSk7XG4gICAgfTtcbiAgICBvYmpbJ193cmFwXycgKyBhY3Rpb25dID0gbWV0aG9kO1xuICAgIHJldHVybiBtZXRob2Q7XG59XG5leHBvcnQgZGVmYXVsdCB3cmFwQmVoYXZpb3I7XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWJlaGF2aW9yLmpzLm1hcCIsInZhciBudW1Db2xvckNhY2hlID0ge307XG5mdW5jdGlvbiBudW1iZXJUb0NvbG9yKG51bSkge1xuICAgIC8vIOWinuWKoOe8k+WtmFxuICAgIHZhciBjb2xvciA9IG51bUNvbG9yQ2FjaGVbbnVtXTtcbiAgICBpZiAoIWNvbG9yKSB7XG4gICAgICAgIHZhciBzdHIgPSBudW0udG9TdHJpbmcoMTYpO1xuICAgICAgICBmb3IgKHZhciBpID0gc3RyLmxlbmd0aDsgaSA8IDY7IGkrKykge1xuICAgICAgICAgICAgc3RyID0gJzAnICsgc3RyO1xuICAgICAgICB9XG4gICAgICAgIGNvbG9yID0gJyMnICsgc3RyO1xuICAgICAgICBudW1Db2xvckNhY2hlW251bV0gPSBjb2xvcjtcbiAgICB9XG4gICAgcmV0dXJuIGNvbG9yO1xufVxuZXhwb3J0IGRlZmF1bHQgbnVtYmVyVG9Db2xvcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW51bWJlcjJjb2xvci5qcy5tYXAiLCJpbXBvcnQgaXNBcnJheSBmcm9tICcuL2lzLWFycmF5JztcbmZ1bmN0aW9uIHBhcnNlUmFkaXVzKHJhZGl1cykge1xuICAgIHZhciByMSA9IDAsIHIyID0gMCwgcjMgPSAwLCByNCA9IDA7XG4gICAgaWYgKGlzQXJyYXkocmFkaXVzKSkge1xuICAgICAgICBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcjEgPSByMiA9IHIzID0gcjQgPSByYWRpdXNbMF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgcjEgPSByMyA9IHJhZGl1c1swXTtcbiAgICAgICAgICAgIHIyID0gcjQgPSByYWRpdXNbMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocmFkaXVzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICAgICAgcjEgPSByYWRpdXNbMF07XG4gICAgICAgICAgICByMiA9IHI0ID0gcmFkaXVzWzFdO1xuICAgICAgICAgICAgcjMgPSByYWRpdXNbMl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByMSA9IHJhZGl1c1swXTtcbiAgICAgICAgICAgIHIyID0gcmFkaXVzWzFdO1xuICAgICAgICAgICAgcjMgPSByYWRpdXNbMl07XG4gICAgICAgICAgICByNCA9IHJhZGl1c1szXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcjEgPSByMiA9IHIzID0gcjQgPSByYWRpdXM7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHIxOiByMSxcbiAgICAgICAgcjI6IHIyLFxuICAgICAgICByMzogcjMsXG4gICAgICAgIHI0OiByNFxuICAgIH07XG59XG5leHBvcnQgZGVmYXVsdCBwYXJzZVJhZGl1cztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhcnNlLXJhZGl1cy5qcy5tYXAiLCJ2YXIgY2xhbXAgPSBmdW5jdGlvbiAoYSwgbWluLCBtYXgpIHtcbiAgICBpZiAoYSA8IG1pbikge1xuICAgICAgICByZXR1cm4gbWluO1xuICAgIH1cbiAgICBlbHNlIGlmIChhID4gbWF4KSB7XG4gICAgICAgIHJldHVybiBtYXg7XG4gICAgfVxuICAgIHJldHVybiBhO1xufTtcbmV4cG9ydCBkZWZhdWx0IGNsYW1wO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xhbXAuanMubWFwIiwidmFyIGZpeGVkQmFzZSA9IGZ1bmN0aW9uICh2LCBiYXNlKSB7XG4gICAgdmFyIHN0ciA9IGJhc2UudG9TdHJpbmcoKTtcbiAgICB2YXIgaW5kZXggPSBzdHIuaW5kZXhPZignLicpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQodik7XG4gICAgfVxuICAgIHZhciBsZW5ndGggPSBzdHIuc3Vic3RyKGluZGV4ICsgMSkubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggPiAyMCkge1xuICAgICAgICBsZW5ndGggPSAyMDtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQodi50b0ZpeGVkKGxlbmd0aCkpO1xufTtcbmV4cG9ydCBkZWZhdWx0IGZpeGVkQmFzZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpeGVkLWJhc2UuanMubWFwIiwiLyoqXG4gKiDliKTmlq3mmK/lkKbmlbDlrZdcbiAqIEByZXR1cm4ge0Jvb2xlYW59IOaYr+WQpuaVsOWtl1xuICovXG5pbXBvcnQgaXNUeXBlIGZyb20gJy4vaXMtdHlwZSc7XG52YXIgaXNOdW1iZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNUeXBlKHZhbHVlLCAnTnVtYmVyJyk7XG59O1xuZXhwb3J0IGRlZmF1bHQgaXNOdW1iZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1udW1iZXIuanMubWFwIiwiaW1wb3J0IGlzTnVtYmVyIGZyb20gJy4vaXMtbnVtYmVyJztcbnZhciBpc0RlY2ltYWwgPSBmdW5jdGlvbiAobnVtKSB7XG4gICAgcmV0dXJuIGlzTnVtYmVyKG51bSkgJiYgbnVtICUgMSAhPT0gMDtcbn07XG5leHBvcnQgZGVmYXVsdCBpc0RlY2ltYWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1kZWNpbWFsLmpzLm1hcCIsImltcG9ydCBpc051bWJlciBmcm9tICcuL2lzLW51bWJlcic7XG52YXIgaXNFdmVuID0gZnVuY3Rpb24gKG51bSkge1xuICAgIHJldHVybiBpc051bWJlcihudW0pICYmIG51bSAlIDIgPT09IDA7XG59O1xuZXhwb3J0IGRlZmF1bHQgaXNFdmVuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZXZlbi5qcy5tYXAiLCJpbXBvcnQgaXNOdW1iZXIgZnJvbSAnLi9pcy1udW1iZXInO1xudmFyIGlzSW50ZWdlciA9IE51bWJlci5pc0ludGVnZXIgPyBOdW1iZXIuaXNJbnRlZ2VyIDogZnVuY3Rpb24gKG51bSkge1xuICAgIHJldHVybiBpc051bWJlcihudW0pICYmIG51bSAlIDEgPT09IDA7XG59O1xuZXhwb3J0IGRlZmF1bHQgaXNJbnRlZ2VyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtaW50ZWdlci5qcy5tYXAiLCJpbXBvcnQgaXNOdW1iZXIgZnJvbSAnLi9pcy1udW1iZXInO1xudmFyIGlzTmVnYXRpdmUgPSBmdW5jdGlvbiAobnVtKSB7XG4gICAgcmV0dXJuIGlzTnVtYmVyKG51bSkgJiYgbnVtIDwgMDtcbn07XG5leHBvcnQgZGVmYXVsdCBpc05lZ2F0aXZlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmVnYXRpdmUuanMubWFwIiwidmFyIFBSRUNJU0lPTiA9IDAuMDAwMDE7IC8vIG51bWJlcnMgbGVzcyB0aGFuIHRoaXMgaXMgY29uc2lkZXJlZCBhcyAwXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc051bWJlckVxdWFsKGEsIGIsIHByZWNpc2lvbikge1xuICAgIGlmIChwcmVjaXNpb24gPT09IHZvaWQgMCkgeyBwcmVjaXNpb24gPSBQUkVDSVNJT047IH1cbiAgICByZXR1cm4gTWF0aC5hYnMoKGEgLSBiKSkgPCBwcmVjaXNpb247XG59XG47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1udW1iZXItZXF1YWwuanMubWFwIiwiaW1wb3J0IGlzTnVtYmVyIGZyb20gJy4vaXMtbnVtYmVyJztcbnZhciBpc09kZCA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICByZXR1cm4gaXNOdW1iZXIobnVtKSAmJiBudW0gJSAyICE9PSAwO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzT2RkO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtb2RkLmpzLm1hcCIsImltcG9ydCBpc051bWJlciBmcm9tICcuL2lzLW51bWJlcic7XG52YXIgaXNQb3NpdGl2ZSA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICByZXR1cm4gaXNOdW1iZXIobnVtKSAmJiBudW0gPiAwO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzUG9zaXRpdmU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wb3NpdGl2ZS5qcy5tYXAiLCJpbXBvcnQgaXNBcnJheSBmcm9tICcuL2lzLWFycmF5JztcbmltcG9ydCBpc0Z1bmN0aW9uIGZyb20gJy4vaXMtZnVuY3Rpb24nO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnIgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcmV0dXJuIHsqfSBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogMSB9LCB7ICduJzogMiB9XTtcbiAqXG4gKiBtYXhCeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICogLy8gPT4geyAnbic6IDIgfVxuICpcbiAqIG1heEJ5KG9iamVjdHMsICduJyk7XG4gKiAvLyA9PiB7ICduJzogMiB9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoYXJyLCBmbikge1xuICAgIGlmICghaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHZhciBtYXhJdGVtO1xuICAgIHZhciBtYXggPSAtSW5maW5pdHk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBhcnJbaV07XG4gICAgICAgIHZhciB2ID0gaXNGdW5jdGlvbihmbikgPyBmbihpdGVtKSA6IGl0ZW1bZm5dO1xuICAgICAgICBpZiAodiA+IG1heCkge1xuICAgICAgICAgICAgbWF4SXRlbSA9IGl0ZW07XG4gICAgICAgICAgICBtYXggPSB2O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXhJdGVtO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXgtYnkuanMubWFwIiwiaW1wb3J0IGlzQXJyYXkgZnJvbSAnLi9pcy1hcnJheSc7XG5pbXBvcnQgaXNGdW5jdGlvbiBmcm9tICcuL2lzLWZ1bmN0aW9uJztcbi8qKlxuICogQHBhcmFtIHtBcnJheX0gYXJyIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICogQHJldHVybiB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDEgfSwgeyAnbic6IDIgfV07XG4gKlxuICogbWluQnkob2JqZWN0cywgZnVuY3Rpb24obykgeyByZXR1cm4gby5uOyB9KTtcbiAqIC8vID0+IHsgJ24nOiAxIH1cbiAqXG4gKiBtaW5CeShvYmplY3RzLCAnbicpO1xuICogLy8gPT4geyAnbic6IDEgfVxuICovXG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKGFyciwgZm4pIHtcbiAgICBpZiAoIWlzQXJyYXkoYXJyKSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB2YXIgbWluSXRlbTtcbiAgICB2YXIgbWluID0gSW5maW5pdHk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBhcnJbaV07XG4gICAgICAgIHZhciB2ID0gaXNGdW5jdGlvbihmbikgPyBmbihpdGVtKSA6IGl0ZW1bZm5dO1xuICAgICAgICBpZiAodiA8IG1pbikge1xuICAgICAgICAgICAgbWluSXRlbSA9IGl0ZW07XG4gICAgICAgICAgICBtaW4gPSB2O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtaW5JdGVtO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW4tYnkuanMubWFwIiwidmFyIG1vZCA9IGZ1bmN0aW9uIChuLCBtKSB7XG4gICAgcmV0dXJuICgobiAlIG0pICsgbSkgJSBtO1xufTtcbmV4cG9ydCBkZWZhdWx0IG1vZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vZC5qcy5tYXAiLCJ2YXIgREVHUkVFID0gMTgwIC8gTWF0aC5QSTtcbnZhciB0b0RlZ3JlZSA9IGZ1bmN0aW9uIChyYWRpYW4pIHtcbiAgICByZXR1cm4gREVHUkVFICogcmFkaWFuO1xufTtcbmV4cG9ydCBkZWZhdWx0IHRvRGVncmVlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8tZGVncmVlLmpzLm1hcCIsImV4cG9ydCBkZWZhdWx0IHBhcnNlSW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8taW50ZWdlci5qcy5tYXAiLCJ2YXIgUkFESUFOID0gTWF0aC5QSSAvIDE4MDtcbnZhciB0b1JhZGlhbiA9IGZ1bmN0aW9uIChkZWdyZWUpIHtcbiAgICByZXR1cm4gUkFESUFOICogZGVncmVlO1xufTtcbmV4cG9ydCBkZWZhdWx0IHRvUmFkaWFuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8tcmFkaWFuLmpzLm1hcCIsImltcG9ydCBlYWNoIGZyb20gJy4vZWFjaCc7XG5leHBvcnQgZGVmYXVsdCBlYWNoO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Zm9yLWluLmpzLm1hcCIsImV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAob2JqLCBrZXkpIHsgcmV0dXJuIG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpOyB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhhcy5qcy5tYXAiLCJpbXBvcnQgaGFzIGZyb20gJy4vaGFzJztcbmV4cG9ydCBkZWZhdWx0IGhhcztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhhcy1rZXkuanMubWFwIiwiaW1wb3J0IGVhY2ggZnJvbSAnLi9lYWNoJztcbmltcG9ydCBpc0Z1bmN0aW9uIGZyb20gJy4vaXMtZnVuY3Rpb24nO1xuLy8gQHRzLWlnbm9yZVxudmFyIHZhbHVlcyA9IE9iamVjdC52YWx1ZXMgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBPYmplY3QudmFsdWVzKG9iaik7IH0gOiBmdW5jdGlvbiAob2JqKSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgICBpZiAoIShpc0Z1bmN0aW9uKG9iaikgJiYga2V5ID09PSAncHJvdG90eXBlJykpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuZXhwb3J0IGRlZmF1bHQgdmFsdWVzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dmFsdWVzLmpzLm1hcCIsImltcG9ydCBjb250YWlucyBmcm9tICcuL2NvbnRhaW5zJztcbmltcG9ydCB2YWx1ZXMgZnJvbSAnLi92YWx1ZXMnO1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChvYmosIHZhbHVlKSB7IHJldHVybiBjb250YWlucyh2YWx1ZXMob2JqKSwgdmFsdWUpOyB9KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWhhcy12YWx1ZS5qcy5tYXAiLCJpbXBvcnQgaXNOaWwgZnJvbSAnLi9pcy1uaWwnO1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGlmIChpc05pbCh2YWx1ZSkpXG4gICAgICAgIHJldHVybiAnJztcbiAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dG8tc3RyaW5nLmpzLm1hcCIsImltcG9ydCB0b1N0cmluZyBmcm9tICcuL3RvLXN0cmluZyc7XG52YXIgbG93ZXJDYXNlID0gZnVuY3Rpb24gKHN0cikge1xuICAgIHJldHVybiB0b1N0cmluZyhzdHIpLnRvTG93ZXJDYXNlKCk7XG59O1xuZXhwb3J0IGRlZmF1bHQgbG93ZXJDYXNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bG93ZXItY2FzZS5qcy5tYXAiLCJpbXBvcnQgdG9TdHJpbmcgZnJvbSAnLi90by1zdHJpbmcnO1xudmFyIGxvd2VyRmlyc3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgc3RyID0gdG9TdHJpbmcodmFsdWUpO1xuICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzdHIuc3Vic3RyaW5nKDEpO1xufTtcbmV4cG9ydCBkZWZhdWx0IGxvd2VyRmlyc3Q7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1sb3dlci1maXJzdC5qcy5tYXAiLCJmdW5jdGlvbiBzdWJzdGl0dXRlKHN0ciwgbykge1xuICAgIGlmICghc3RyIHx8ICFvKSB7XG4gICAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIHJldHVybiBzdHIucmVwbGFjZSgvXFxcXD9cXHsoW157fV0rKVxcfS9nLCBmdW5jdGlvbiAobWF0Y2gsIG5hbWUpIHtcbiAgICAgICAgaWYgKG1hdGNoLmNoYXJBdCgwKSA9PT0gJ1xcXFwnKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2guc2xpY2UoMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChvW25hbWVdID09PSB1bmRlZmluZWQpID8gJycgOiBvW25hbWVdO1xuICAgIH0pO1xufVxuZXhwb3J0IGRlZmF1bHQgc3Vic3RpdHV0ZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN1YnN0aXR1dGUuanMubWFwIiwiaW1wb3J0IHRvU3RyaW5nIGZyb20gJy4vdG8tc3RyaW5nJztcbnZhciB1cHBlckNhc2UgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICAgcmV0dXJuIHRvU3RyaW5nKHN0cikudG9VcHBlckNhc2UoKTtcbn07XG5leHBvcnQgZGVmYXVsdCB1cHBlckNhc2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11cHBlci1jYXNlLmpzLm1hcCIsImltcG9ydCB0b1N0cmluZyBmcm9tICcuL3RvLXN0cmluZyc7XG52YXIgdXBwZXJGaXJzdCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBzdHIgPSB0b1N0cmluZyh2YWx1ZSk7XG4gICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zdWJzdHJpbmcoMSk7XG59O1xuZXhwb3J0IGRlZmF1bHQgdXBwZXJGaXJzdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVwcGVyLWZpcnN0LmpzLm1hcCIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xudmFyIGdldFR5cGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWx1ZSkucmVwbGFjZSgvXlxcW29iamVjdCAvLCAnJykucmVwbGFjZSgvXSQvLCAnJyk7XG59O1xuZXhwb3J0IGRlZmF1bHQgZ2V0VHlwZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC10eXBlLmpzLm1hcCIsIi8qKlxuICog5piv5ZCm5piv5Y+C5pWw57G75Z6LXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlIOa1i+ivleeahOWAvFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuaW1wb3J0IGlzVHlwZSBmcm9tICcuL2lzLXR5cGUnO1xudmFyIGlzQXJndW1lbnRzID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGlzVHlwZSh2YWx1ZSwgJ0FyZ3VtZW50cycpO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzQXJndW1lbnRzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYXJndW1lbnRzLmpzLm1hcCIsIi8qKlxuICog5piv5ZCm5piv5biD5bCU57G75Z6LXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlIOa1i+ivleeahOWAvFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuaW1wb3J0IGlzVHlwZSBmcm9tICcuL2lzLXR5cGUnO1xudmFyIGlzQm9vbGVhbiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc1R5cGUodmFsdWUsICdCb29sZWFuJyk7XG59O1xuZXhwb3J0IGRlZmF1bHQgaXNCb29sZWFuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYm9vbGVhbi5qcy5tYXAiLCJpbXBvcnQgaXNUeXBlIGZyb20gJy4vaXMtdHlwZSc7XG52YXIgaXNEYXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIGlzVHlwZSh2YWx1ZSwgJ0RhdGUnKTtcbn07XG5leHBvcnQgZGVmYXVsdCBpc0RhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1kYXRlLmpzLm1hcCIsIi8qKlxuICog5piv5ZCm5piv5Y+C5pWw57G75Z6LXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlIOa1i+ivleeahOWAvFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuaW1wb3J0IGlzVHlwZSBmcm9tICcuL2lzLXR5cGUnO1xudmFyIGlzRXJyb3IgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNUeXBlKHZhbHVlLCAnRXJyb3InKTtcbn07XG5leHBvcnQgZGVmYXVsdCBpc0Vycm9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZXJyb3IuanMubWFwIiwiLyoqXG4gKiDliKTmlq3mmK/lkKbkuLrmnInpmZDmlbBcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmltcG9ydCBpc051bWJlciBmcm9tICcuL2lzLW51bWJlcic7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNOdW1iZXIodmFsdWUpICYmIGlzRmluaXRlKHZhbHVlKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWZpbml0ZS5qcy5tYXAiLCJ2YXIgaXNOdWxsID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzTnVsbDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW51bGwuanMubWFwIiwidmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcbnZhciBpc1Byb3RvdHlwZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciBDdG9yID0gdmFsdWUgJiYgdmFsdWUuY29uc3RydWN0b3I7XG4gICAgdmFyIHByb3RvID0gKHR5cGVvZiBDdG9yID09PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlKSB8fCBvYmplY3RQcm90bztcbiAgICByZXR1cm4gdmFsdWUgPT09IHByb3RvO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzUHJvdG90eXBlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtcHJvdG90eXBlLmpzLm1hcCIsImltcG9ydCBpc1R5cGUgZnJvbSAnLi9pcy10eXBlJztcbnZhciBpc1JlZ0V4cCA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gaXNUeXBlKHN0ciwgJ1JlZ0V4cCcpO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzUmVnRXhwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtcmVnLWV4cC5qcy5tYXAiLCJ2YXIgaXNVbmRlZmluZWQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn07XG5leHBvcnQgZGVmYXVsdCBpc1VuZGVmaW5lZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXVuZGVmaW5lZC5qcy5tYXAiLCIvKipcbiAqIOWIpOaWreaYr+WQpkhUTUzlhYPntKBcbiAqIEByZXR1cm4ge0Jvb2xlYW59IOaYr+WQpkhUTUzlhYPntKBcbiAqL1xudmFyIGlzRWxlbWVudCA9IGZ1bmN0aW9uIChvKSB7XG4gICAgcmV0dXJuIG8gaW5zdGFuY2VvZiBFbGVtZW50IHx8IG8gaW5zdGFuY2VvZiBIVE1MRG9jdW1lbnQ7XG59O1xuZXhwb3J0IGRlZmF1bHQgaXNFbGVtZW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZWxlbWVudC5qcy5tYXAiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZm4pIHtcbiAgICB2YXIgbWV0aG9kID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgd2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHdpbmRvdy5tc1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgICAgICBmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZiwgMTYpO1xuICAgICAgICB9O1xuICAgIHJldHVybiBtZXRob2QoZm4pO1xufVxuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVxdWVzdC1hbmltYXRpb24tZnJhbWUuanMubWFwIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY2FuY2VsQW5pbWF0aW9uRnJhbWUoaGFuZGxlcikge1xuICAgIHZhciBtZXRob2QgPSB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgd2luZG93LndlYmtpdENhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgd2luZG93Lm1vekNhbmNlbEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgd2luZG93Lm1zQ2FuY2VsQW5pbWF0aW9uRnJhbWUgfHxcbiAgICAgICAgY2xlYXJUaW1lb3V0O1xuICAgIG1ldGhvZChoYW5kbGVyKTtcbn1cbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsZWFyLWFuaW1hdGlvbi1mcmFtZS5qcy5tYXAiLCIvLyBGSVhNRTogTXV0YWJsZSBwYXJhbSBzaG91bGQgYmUgZm9yYmlkZGVuIGluIHN0YXRpYyBsYW5nLlxuZnVuY3Rpb24gX21peChkaXN0LCBvYmopIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoa2V5KSAmJiBrZXkgIT09ICdjb25zdHJ1Y3RvcicgJiYgb2JqW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZGlzdFtrZXldID0gb2JqW2tleV07XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtaXgoZGlzdCwgc3JjMSwgc3JjMiwgc3JjMykge1xuICAgIGlmIChzcmMxKVxuICAgICAgICBfbWl4KGRpc3QsIHNyYzEpO1xuICAgIGlmIChzcmMyKVxuICAgICAgICBfbWl4KGRpc3QsIHNyYzIpO1xuICAgIGlmIChzcmMzKVxuICAgICAgICBfbWl4KGRpc3QsIHNyYzMpO1xuICAgIHJldHVybiBkaXN0O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWl4LmpzLm1hcCIsImltcG9ydCBtaXggZnJvbSAnLi9taXgnO1xuaW1wb3J0IGlzRnVuY3Rpb24gZnJvbSAnLi9pcy1mdW5jdGlvbic7XG52YXIgYXVnbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgdmFyIGMgPSBhcmdzWzBdO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgb2JqID0gYXJnc1tpXTtcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24ob2JqKSkge1xuICAgICAgICAgICAgb2JqID0gb2JqLnByb3RvdHlwZTtcbiAgICAgICAgfVxuICAgICAgICBtaXgoYy5wcm90b3R5cGUsIG9iaik7XG4gICAgfVxufTtcbmV4cG9ydCBkZWZhdWx0IGF1Z21lbnQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWdtZW50LmpzLm1hcCIsImltcG9ydCBpc0FycmF5IGZyb20gJy4vaXMtYXJyYXknO1xudmFyIGNsb25lID0gZnVuY3Rpb24gKG9iaikge1xuICAgIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCBvYmogPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG4gICAgdmFyIHJzdDtcbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgIHJzdCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqW2ldID09PSAnb2JqZWN0JyAmJiBvYmpbaV0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJzdFtpXSA9IGNsb25lKG9ialtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByc3RbaV0gPSBvYmpbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJzdCA9IHt9O1xuICAgICAgICBmb3IgKHZhciBrIGluIG9iaikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmpba10gPT09ICdvYmplY3QnICYmIG9ialtrXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcnN0W2tdID0gY2xvbmUob2JqW2tdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJzdFtrXSA9IG9ialtrXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcnN0O1xufTtcbmV4cG9ydCBkZWZhdWx0IGNsb25lO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xvbmUuanMubWFwIiwiZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgaW1tZWRpYXRlKSB7XG4gICAgdmFyIHRpbWVvdXQ7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLCBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgICAgIGlmICghaW1tZWRpYXRlKSB7XG4gICAgICAgICAgICAgICAgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGNhbGxOb3cgPSBpbW1lZGlhdGUgJiYgIXRpbWVvdXQ7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICAgICAgICBpZiAoY2FsbE5vdykge1xuICAgICAgICAgICAgZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnQgZGVmYXVsdCBkZWJvdW5jZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlYm91bmNlLmpzLm1hcCIsImltcG9ydCBpc0Z1bmN0aW9uIGZyb20gJy4vaXMtZnVuY3Rpb24nO1xuLyoqXG4gKiBfLm1lbW9pemUoY2FsQ29sb3IpO1xuICogXy5tZW1vaXplKGNhbENvbG9yLCAoLi4uYXJncykgPT4gYXJnc1swXSk7XG4gKiBAcGFyYW0gZlxuICogQHBhcmFtIHJlc29sdmVyXG4gKi9cbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoZiwgcmVzb2x2ZXIpIHtcbiAgICBpZiAoIWlzRnVuY3Rpb24oZikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBhcmdzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgLy8g5L2/55So5pa55rOV5p6E6YCgIGtlee+8jOWmguaenOS4jeWtmOWcqCByZXNvbHZlcu+8jOWImeebtOaOpeWPluesrOS4gOS4quWPguaVsOS9nOS4uiBrZXlcbiAgICAgICAgdmFyIGtleSA9IHJlc29sdmVyID8gcmVzb2x2ZXIuYXBwbHkodGhpcywgYXJncykgOiBhcmdzWzBdO1xuICAgICAgICB2YXIgY2FjaGUgPSBtZW1vaXplZC5jYWNoZTtcbiAgICAgICAgaWYgKGNhY2hlLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGUuZ2V0KGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc3VsdCA9IGYuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIC8vIOe8k+WtmOi1t+adpVxuICAgICAgICBjYWNoZS5zZXQoa2V5LCByZXN1bHQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgbWVtb2l6ZWQuY2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgcmV0dXJuIG1lbW9pemVkO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZW1vaXplLmpzLm1hcCIsImltcG9ydCBpc0FycmF5IGZyb20gJy4vaXMtYXJyYXknO1xuaW1wb3J0IGlzUGxhaW5PYmplY3QgZnJvbSAnLi9pcy1wbGFpbi1vYmplY3QnO1xudmFyIE1BWF9NSVhfTEVWRUwgPSA1O1xuZnVuY3Rpb24gX2RlZXBNaXgoZGlzdCwgc3JjLCBsZXZlbCwgbWF4TGV2ZWwpIHtcbiAgICBsZXZlbCA9IGxldmVsIHx8IDA7XG4gICAgbWF4TGV2ZWwgPSBtYXhMZXZlbCB8fCBNQVhfTUlYX0xFVkVMO1xuICAgIGZvciAodmFyIGtleSBpbiBzcmMpIHtcbiAgICAgICAgaWYgKHNyYy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBzcmNba2V5XTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiBpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmICghaXNQbGFpbk9iamVjdChkaXN0W2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3Rba2V5XSA9IHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobGV2ZWwgPCBtYXhMZXZlbCkge1xuICAgICAgICAgICAgICAgICAgICBfZGVlcE1peChkaXN0W2tleV0sIHZhbHVlLCBsZXZlbCArIDEsIG1heExldmVsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3Rba2V5XSA9IHNyY1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgZGlzdFtrZXldID0gW107XG4gICAgICAgICAgICAgICAgZGlzdFtrZXldID0gZGlzdFtrZXldLmNvbmNhdCh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZGlzdFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyB0b2RvIOmHjeWGmVxudmFyIGRlZXBNaXggPSBmdW5jdGlvbiAocnN0KSB7XG4gICAgdmFyIGFyZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICBhcmdzW19pIC0gMV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgX2RlZXBNaXgocnN0LCBhcmdzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJzdDtcbn07XG5leHBvcnQgZGVmYXVsdCBkZWVwTWl4O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVlcC1taXguanMubWFwIiwiaW1wb3J0IG1peCBmcm9tICcuL21peCc7XG5pbXBvcnQgaXNGdW5jdGlvbiBmcm9tICcuL2lzLWZ1bmN0aW9uJztcbnZhciBleHRlbmQgPSBmdW5jdGlvbiAoc3ViY2xhc3MsIHN1cGVyY2xhc3MsIG92ZXJyaWRlcywgc3RhdGljT3ZlcnJpZGVzKSB7XG4gICAgLy8g5aaC5p6c5Y+q5o+Q5L6b54i257G75p6E6YCg5Ye95pWw77yM5YiZ6Ieq5Yqo55Sf5oiQ5a2Q57G75p6E6YCg5Ye95pWwXG4gICAgaWYgKCFpc0Z1bmN0aW9uKHN1cGVyY2xhc3MpKSB7XG4gICAgICAgIG92ZXJyaWRlcyA9IHN1cGVyY2xhc3M7XG4gICAgICAgIHN1cGVyY2xhc3MgPSBzdWJjbGFzcztcbiAgICAgICAgc3ViY2xhc3MgPSBmdW5jdGlvbiAoKSB7IH07XG4gICAgfVxuICAgIHZhciBjcmVhdGUgPSBPYmplY3QuY3JlYXRlID9cbiAgICAgICAgZnVuY3Rpb24gKHByb3RvLCBjKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmNyZWF0ZShwcm90bywge1xuICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBjXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gOlxuICAgICAgICBmdW5jdGlvbiAocHJvdG8sIGMpIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIFRtcCgpIHsgfVxuICAgICAgICAgICAgVG1wLnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgICAgICAgdmFyIG8gPSBuZXcgVG1wKCk7XG4gICAgICAgICAgICBvLmNvbnN0cnVjdG9yID0gYztcbiAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICB9O1xuICAgIHZhciBzdXBlck9iaiA9IGNyZWF0ZShzdXBlcmNsYXNzLnByb3RvdHlwZSwgc3ViY2xhc3MpOyAvLyBuZXcgc3VwZXJjbGFzcygpLC8v5a6e5L6L5YyW54i257G75L2c5Li65a2Q57G755qEcHJvdG90eXBlXG4gICAgc3ViY2xhc3MucHJvdG90eXBlID0gbWl4KHN1cGVyT2JqLCBzdWJjbGFzcy5wcm90b3R5cGUpOyAvLyDmjIflrprlrZDnsbvnmoRwcm90b3R5cGVcbiAgICBzdWJjbGFzcy5zdXBlcmNsYXNzID0gY3JlYXRlKHN1cGVyY2xhc3MucHJvdG90eXBlLCBzdXBlcmNsYXNzKTtcbiAgICBtaXgoc3VwZXJPYmosIG92ZXJyaWRlcyk7XG4gICAgbWl4KHN1YmNsYXNzLCBzdGF0aWNPdmVycmlkZXMpO1xuICAgIHJldHVybiBzdWJjbGFzcztcbn07XG5leHBvcnQgZGVmYXVsdCBleHRlbmQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1leHRlbmQuanMubWFwIiwiaW1wb3J0IGlzQXJyYXlMaWtlIGZyb20gJy4vaXMtYXJyYXktbGlrZSc7XG52YXIgaW5kZXhPZiA9IGZ1bmN0aW9uIChhcnIsIG9iaikge1xuICAgIGlmICghaXNBcnJheUxpa2UoYXJyKSkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHZhciBtID0gQXJyYXkucHJvdG90eXBlLmluZGV4T2Y7XG4gICAgaWYgKG0pIHtcbiAgICAgICAgcmV0dXJuIG0uY2FsbChhcnIsIG9iaik7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IC0xO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChhcnJbaV0gPT09IG9iaikge1xuICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xufTtcbmV4cG9ydCBkZWZhdWx0IGluZGV4T2Y7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC1vZi5qcy5tYXAiLCJpbXBvcnQgaXNOaWwgZnJvbSAnLi9pcy1uaWwnO1xuaW1wb3J0IGlzQXJyYXlMaWtlIGZyb20gJy4vaXMtYXJyYXktbGlrZSc7XG5pbXBvcnQgZ2V0VHlwZSBmcm9tICcuL2dldC10eXBlJztcbmltcG9ydCBpc1Byb3RvdHlwZSBmcm9tICcuL2lzLXByb3RvdHlwZSc7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaXNFbXB0eSh2YWx1ZSkge1xuICAgIC8qKlxuICAgICAqIGlzRW1wdHkobnVsbCkgPT4gdHJ1ZVxuICAgICAqIGlzRW1wdHkoKSA9PiB0cnVlXG4gICAgICogaXNFbXB0eSh0cnVlKSA9PiB0cnVlXG4gICAgICogaXNFbXB0eSgxKSA9PiB0cnVlXG4gICAgICogaXNFbXB0eShbMSwgMiwgM10pID0+IGZhbHNlXG4gICAgICogaXNFbXB0eSgnYWJjJykgPT4gZmFsc2VcbiAgICAgKiBpc0VtcHR5KHsgYTogMSB9KSA9PiBmYWxzZVxuICAgICAqL1xuICAgIGlmIChpc05pbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuICF2YWx1ZS5sZW5ndGg7XG4gICAgfVxuICAgIHZhciB0eXBlID0gZ2V0VHlwZSh2YWx1ZSk7XG4gICAgaWYgKHR5cGUgPT09ICdNYXAnIHx8IHR5cGUgPT09ICdTZXQnKSB7XG4gICAgICAgIHJldHVybiAhdmFsdWUuc2l6ZTtcbiAgICB9XG4gICAgaWYgKGlzUHJvdG90eXBlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gIU9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGg7XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZXhwb3J0IGRlZmF1bHQgaXNFbXB0eTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWVtcHR5LmpzLm1hcCIsImltcG9ydCBpc09iamVjdExpa2UgZnJvbSAnLi9pcy1vYmplY3QtbGlrZSc7XG5pbXBvcnQgaXNBcnJheUxpa2UgZnJvbSAnLi9pcy1hcnJheS1saWtlJztcbmltcG9ydCBpc1N0cmluZyBmcm9tICcuL2lzLXN0cmluZyc7XG52YXIgaXNFcXVhbCA9IGZ1bmN0aW9uICh2YWx1ZSwgb3RoZXIpIHtcbiAgICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoIXZhbHVlIHx8ICFvdGhlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkgfHwgaXNTdHJpbmcob3RoZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSB8fCBpc0FycmF5TGlrZShvdGhlcikpIHtcbiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCAhPT0gb3RoZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJzdCA9IHRydWU7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHJzdCA9IGlzRXF1YWwodmFsdWVbaV0sIG90aGVyW2ldKTtcbiAgICAgICAgICAgIGlmICghcnN0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9XG4gICAgaWYgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgfHwgaXNPYmplY3RMaWtlKG90aGVyKSkge1xuICAgICAgICB2YXIgdmFsdWVLZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICAgICAgICB2YXIgb3RoZXJLZXlzID0gT2JqZWN0LmtleXMob3RoZXIpO1xuICAgICAgICBpZiAodmFsdWVLZXlzLmxlbmd0aCAhPT0gb3RoZXJLZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciByc3QgPSB0cnVlO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcnN0ID0gaXNFcXVhbCh2YWx1ZVt2YWx1ZUtleXNbaV1dLCBvdGhlclt2YWx1ZUtleXNbaV1dKTtcbiAgICAgICAgICAgIGlmICghcnN0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJzdDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbmV4cG9ydCBkZWZhdWx0IGlzRXF1YWw7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1lcXVhbC5qcy5tYXAiLCJpbXBvcnQgaXNGdW5jdGlvbiBmcm9tICcuL2lzLWZ1bmN0aW9uJztcbmltcG9ydCBpc0VxdWFsIGZyb20gJy4vaXMtZXF1YWwnO1xuLyoqXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIGlzR3JlZXRpbmcodmFsdWUpIHtcbiAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAqIH1cbiAqXG4gKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSkge1xuICogICBpZiAoaXNHcmVldGluZyhvYmpWYWx1ZSkgJiYgaXNHcmVldGluZyhvdGhWYWx1ZSkpIHtcbiAqICAgICByZXR1cm4gdHJ1ZTtcbiAqICAgfVxuICogfVxuICpcbiAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICogdmFyIG90aGVyID0gWydoaScsICdnb29kYnllJ107XG4gKlxuICogaXNFcXVhbFdpdGgoYXJyYXksIG90aGVyLCBjdXN0b21pemVyKTsgIC8vID0+IHRydWVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uICh2YWx1ZSwgb3RoZXIsIGZuKSB7XG4gICAgaWYgKCFpc0Z1bmN0aW9uKGZuKSkge1xuICAgICAgICByZXR1cm4gaXNFcXVhbCh2YWx1ZSwgb3RoZXIpO1xuICAgIH1cbiAgICByZXR1cm4gISFmbih2YWx1ZSwgb3RoZXIpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1lcXVhbC13aXRoLmpzLm1hcCIsImltcG9ydCBpc0FycmF5TGlrZSBmcm9tICcuL2lzLWFycmF5LWxpa2UnO1xudmFyIG1hcCA9IGZ1bmN0aW9uIChhcnIsIGZ1bmMpIHtcbiAgICBpZiAoIWlzQXJyYXlMaWtlKGFycikpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IGFyci5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyW2luZGV4XTtcbiAgICAgICAgcmVzdWx0LnB1c2goZnVuYyh2YWx1ZSwgaW5kZXgpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn07XG5leHBvcnQgZGVmYXVsdCBtYXA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYXAuanMubWFwIiwiaW1wb3J0IGlzTmlsIGZyb20gJy4vaXMtbmlsJztcbmltcG9ydCBpc09iamVjdCBmcm9tICcuL2lzLW9iamVjdCc7XG52YXIgaWRlbnRpdHkgPSBmdW5jdGlvbiAodikgeyByZXR1cm4gdjsgfTtcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAob2JqZWN0LCBmdW5jKSB7XG4gICAgaWYgKGZ1bmMgPT09IHZvaWQgMCkgeyBmdW5jID0gaWRlbnRpdHk7IH1cbiAgICB2YXIgciA9IHt9O1xuICAgIGlmIChpc09iamVjdChvYmplY3QpICYmICFpc05pbChvYmplY3QpKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKG9iamVjdCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICByW2tleV0gPSBmdW5jKG9iamVjdFtrZXldLCBrZXkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHI7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1hcC12YWx1ZXMuanMubWFwIiwiaW1wb3J0IGlzU3RyaW5nIGZyb20gJy4vaXMtc3RyaW5nJztcbi8qKlxuICogaHR0cHM6Ly9naXRodWIuY29tL2RldmVsb3BpdC9kbHYvYmxvYi9tYXN0ZXIvaW5kZXguanNcbiAqIEBwYXJhbSBvYmpcbiAqIEBwYXJhbSBrZXlcbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChvYmosIGtleSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgdmFyIHAgPSAwO1xuICAgIHZhciBrZXlBcnIgPSBpc1N0cmluZyhrZXkpID8ga2V5LnNwbGl0KCcuJykgOiBrZXk7XG4gICAgd2hpbGUgKG9iaiAmJiBwIDwga2V5QXJyLmxlbmd0aCkge1xuICAgICAgICBvYmogPSBvYmpba2V5QXJyW3ArK11dO1xuICAgIH1cbiAgICByZXR1cm4gKG9iaiA9PT0gdW5kZWZpbmVkIHx8IHAgPCBrZXlBcnIubGVuZ3RoKSA/IGRlZmF1bHRWYWx1ZSA6IG9iajtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LmpzLm1hcCIsImltcG9ydCBpc09iamVjdCBmcm9tICcuL2lzLW9iamVjdCc7XG5pbXBvcnQgaXNTdHJpbmcgZnJvbSAnLi9pcy1zdHJpbmcnO1xuaW1wb3J0IGlzTnVtYmVyIGZyb20gJy4vaXMtbnVtYmVyJztcbi8qKlxuICogaHR0cHM6Ly9naXRodWIuY29tL2RldmVsb3BpdC9kbHYvYmxvYi9tYXN0ZXIvaW5kZXguanNcbiAqIEBwYXJhbSBvYmpcbiAqIEBwYXJhbSBwYXRoXG4gKiBAcGFyYW0gdmFsdWVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChvYmosIHBhdGgsIHZhbHVlKSB7XG4gICAgdmFyIG8gPSBvYmo7XG4gICAgdmFyIGtleUFyciA9IGlzU3RyaW5nKHBhdGgpID8gcGF0aC5zcGxpdCgnLicpIDogcGF0aDtcbiAgICBrZXlBcnIuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBpZHgpIHtcbiAgICAgICAgLy8g5LiN5piv5pyA5ZCO5LiA5LiqXG4gICAgICAgIGlmIChpZHggPCBrZXlBcnIubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgaWYgKCFpc09iamVjdChvW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgb1trZXldID0gaXNOdW1iZXIoa2V5QXJyW2lkeCArIDFdKSA/IFtdIDoge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvID0gb1trZXldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgb1trZXldID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQuanMubWFwIiwiaW1wb3J0IGVhY2ggZnJvbSAnLi9lYWNoJztcbmltcG9ydCBpc1BsYWluT2JqZWN0IGZyb20gJy4vaXMtcGxhaW4tb2JqZWN0JztcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKG9iamVjdCwga2V5cykge1xuICAgIGlmIChvYmplY3QgPT09IG51bGwgfHwgIWlzUGxhaW5PYmplY3Qob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICBlYWNoKGtleXMsIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IG9iamVjdFtrZXldO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGljay5qcy5tYXAiLCJpbXBvcnQgcmVkdWNlIGZyb20gJy4vcmVkdWNlJztcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAob2JqLCBrZXlzKSB7XG4gICAgcmV0dXJuIHJlZHVjZShvYmosIGZ1bmN0aW9uIChyLCBjdXJyLCBrZXkpIHtcbiAgICAgICAgaWYgKCFrZXlzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICAgIHJba2V5XSA9IGN1cnI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgfSwge30pO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vbWl0LmpzLm1hcCIsImV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgIHZhciB0aW1lb3V0LCBjb250ZXh0LCBhcmdzLCByZXN1bHQ7XG4gICAgdmFyIHByZXZpb3VzID0gMDtcbiAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHByZXZpb3VzID0gb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSA/IDAgOiBEYXRlLm5vdygpO1xuICAgICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgaWYgKCF0aW1lb3V0KVxuICAgICAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgIH07XG4gICAgdmFyIHRocm90dGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGlmICghcHJldmlvdXMgJiYgb3B0aW9ucy5sZWFkaW5nID09PSBmYWxzZSlcbiAgICAgICAgICAgIHByZXZpb3VzID0gbm93O1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gd2FpdCAtIChub3cgLSBwcmV2aW91cyk7XG4gICAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgICBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBpZiAocmVtYWluaW5nIDw9IDAgfHwgcmVtYWluaW5nID4gd2FpdCkge1xuICAgICAgICAgICAgaWYgKHRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgICAgICBpZiAoIXRpbWVvdXQpXG4gICAgICAgICAgICAgICAgY29udGV4dCA9IGFyZ3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0aW1lb3V0ICYmIG9wdGlvbnMudHJhaWxpbmcgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgcmVtYWluaW5nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gICAgdGhyb3R0bGVkLmNhbmNlbCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICBwcmV2aW91cyA9IDA7XG4gICAgICAgIHRpbWVvdXQgPSBjb250ZXh0ID0gYXJncyA9IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gdGhyb3R0bGVkO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD10aHJvdHRsZS5qcy5tYXAiLCJpbXBvcnQgaXNBcnJheUxpa2UgZnJvbSAnLi9pcy1hcnJheS1saWtlJztcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNBcnJheUxpa2UodmFsdWUpID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodmFsdWUpIDogW107XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRvLWFycmF5LmpzLm1hcCIsInZhciBtYXAgPSB7fTtcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAocHJlZml4KSB7XG4gICAgcHJlZml4ID0gcHJlZml4IHx8ICdnJztcbiAgICBpZiAoIW1hcFtwcmVmaXhdKSB7XG4gICAgICAgIG1hcFtwcmVmaXhdID0gMTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG1hcFtwcmVmaXhdICs9IDE7XG4gICAgfVxuICAgIHJldHVybiBwcmVmaXggKyBtYXBbcHJlZml4XTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dW5pcXVlLWlkLmpzLm1hcCIsImV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoKSB7IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bm9vcC5qcy5tYXAiLCJleHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHY7IH0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWRlbnRpdHkuanMubWFwIiwiaW1wb3J0IGlzTmlsIGZyb20gJy4vaXMtbmlsJztcbmltcG9ydCBpc0FycmF5bGlrZSBmcm9tICcuL2lzLWFycmF5LWxpa2UnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gc2l6ZShvKSB7XG4gICAgaWYgKGlzTmlsKG8pKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAoaXNBcnJheWxpa2UobykpIHtcbiAgICAgICAgcmV0dXJuIG8ubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmtleXMobykubGVuZ3RoO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2l6ZS5qcy5tYXAiLCJpbXBvcnQgeyBfX3NwcmVhZEFycmF5cyB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHZhbHVlcyBmcm9tICcuL3ZhbHVlcyc7XG5pbXBvcnQgbWVtb2l6ZSBmcm9tICcuL21lbW9pemUnO1xuaW1wb3J0IGlzU3RyaW5nIGZyb20gJy4vaXMtc3RyaW5nJztcbnZhciBjdHg7XG4vKipcbiAqIOiuoeeul+aWh+acrOeahOWuveW6plxuICovXG5leHBvcnQgZGVmYXVsdCBtZW1vaXplKGZ1bmN0aW9uICh0ZXh0LCBmb250KSB7XG4gICAgaWYgKGZvbnQgPT09IHZvaWQgMCkgeyBmb250ID0ge307IH1cbiAgICB2YXIgZm9udFNpemUgPSBmb250LmZvbnRTaXplLCBmb250RmFtaWx5ID0gZm9udC5mb250RmFtaWx5LCBmb250V2VpZ2h0ID0gZm9udC5mb250V2VpZ2h0LCBmb250U3R5bGUgPSBmb250LmZvbnRTdHlsZSwgZm9udFZhcmlhbnQgPSBmb250LmZvbnRWYXJpYW50O1xuICAgIGlmICghY3R4KSB7XG4gICAgICAgIGN0eCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQoJzJkJyk7XG4gICAgfVxuICAgIGN0eC5mb250ID0gW2ZvbnRTdHlsZSwgZm9udFZhcmlhbnQsIGZvbnRXZWlnaHQsIGZvbnRTaXplICsgXCJweFwiLCBmb250RmFtaWx5XS5qb2luKCcgJyk7XG4gICAgcmV0dXJuIGN0eC5tZWFzdXJlVGV4dChpc1N0cmluZyh0ZXh0KSA/IHRleHQgOiAnJykud2lkdGg7XG59LCBmdW5jdGlvbiAodGV4dCwgZm9udCkge1xuICAgIGlmIChmb250ID09PSB2b2lkIDApIHsgZm9udCA9IHt9OyB9XG4gICAgcmV0dXJuIF9fc3ByZWFkQXJyYXlzKFt0ZXh0XSwgdmFsdWVzKGZvbnQpKS5qb2luKCcnKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVhc3VyZS10ZXh0LXdpZHRoLmpzLm1hcCIsImltcG9ydCBpc1N0cmluZyBmcm9tICcuL2lzLXN0cmluZyc7XG5pbXBvcnQgdG9TdHJpbmcgZnJvbSAnLi90by1zdHJpbmcnO1xuaW1wb3J0IHsgZGVmYXVsdCBhcyBtZWFzdXJlVGV4dFdpZHRoIH0gZnJvbSAnLi9tZWFzdXJlLXRleHQtd2lkdGgnO1xuLyoqXG4gKiDojrflj5bmlofmnKznmoQgLi4uIOaWh+acrOOAglxuICog566X5rOV77yI5YeP5bCR5q+P5qyhIG1lYXN1cmVUZXh0IOeahOmVv+W6pu+8jG1lYXN1cmVUZXh0IOeahOaAp+iDvei3n+Wtl+espuS4suaXtumXtOebuOWFs++8ie+8mlxuICogMS4g5YWI6YCa6L+HIFNURVAg6YCQ5q2l6K6h566X77yM5om+5Yiw5pyA5ZCO5LiA5Liq5bCP5LqOIG1heFdpZHRoIOeahOWtl+espuS4slxuICogMi4g54S25ZCO5a+55pyA5ZCO6L+Z5Liq5a2X56ym5Liy5LqM5YiG6K6h566XXG4gKiBAcGFyYW0gdGV4dCDpnIDopoHorqHnrpfnmoTmlofmnKwsIOeUseS6juWOhuWPsuWOn+WboCDpmaTkuobmlK/mjIFzdHJpbmfvvIzov5jmlK/mjIHnqbrlgLwsbnVtYmVy5ZKM5pWw57uE562JXG4gKiBAcGFyYW0gbWF4V2lkdGgg5pyA5aSn5a695bqmXG4gKiBAcGFyYW0gZm9udCDlrZfkvZNcbiAqIEBwYXJhbSBzdHIg6KaB5pu/5o2i55qE5paH5pysXG4gKi9cbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAodGV4dCwgbWF4V2lkdGgsIGZvbnQsIHN0cikge1xuICAgIGlmIChzdHIgPT09IHZvaWQgMCkgeyBzdHIgPSAnLi4uJzsgfVxuICAgIHZhciBTVEVQID0gMTY7IC8vIOavj+asoSAxNu+8jOiwg+WPguW3peeoi+W4iFxuICAgIHZhciBQTEFDRUhPTERFUl9XSURUSCA9IG1lYXN1cmVUZXh0V2lkdGgoc3RyLCBmb250KTtcbiAgICB2YXIgbGVmdFRleHQgPSAhaXNTdHJpbmcodGV4dCkgPyB0b1N0cmluZyh0ZXh0KSA6IHRleHQ7XG4gICAgdmFyIGxlZnRXaWR0aCA9IG1heFdpZHRoO1xuICAgIHZhciByID0gW107IC8vIOacgOe7iOeahOWIhuauteWtl+espuS4slxuICAgIHZhciBjdXJyZW50VGV4dDtcbiAgICB2YXIgY3VycmVudFdpZHRoO1xuICAgIGlmIChtZWFzdXJlVGV4dFdpZHRoKHRleHQsIGZvbnQpIDw9IG1heFdpZHRoKSB7XG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICAvLyDpppblhYjpgJrov4cgc3RlcCDorqHnrpfvvIzmib7lh7rmnIDlpKfnmoTmnKrotoXlh7rplb/luqbnmoRcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc3RhbnQtY29uZGl0aW9uXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgLy8g5pu05paw5a2X56ym5LiyXG4gICAgICAgIGN1cnJlbnRUZXh0ID0gbGVmdFRleHQuc3Vic3RyKDAsIFNURVApO1xuICAgICAgICAvLyDorqHnrpflrr3luqZcbiAgICAgICAgY3VycmVudFdpZHRoID0gbWVhc3VyZVRleHRXaWR0aChjdXJyZW50VGV4dCwgZm9udCk7XG4gICAgICAgIC8vIOi2heWHuuWJqeS9meWuveW6pu+8jOWImeWBnOatolxuICAgICAgICBpZiAoY3VycmVudFdpZHRoICsgUExBQ0VIT0xERVJfV0lEVEggPiBsZWZ0V2lkdGgpIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50V2lkdGggPiBsZWZ0V2lkdGgpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByLnB1c2goY3VycmVudFRleHQpO1xuICAgICAgICAvLyDmsqHmnInotoXlh7rvvIzliJnorqHnrpfliankvZnlrr3luqZcbiAgICAgICAgbGVmdFdpZHRoIC09IGN1cnJlbnRXaWR0aDtcbiAgICAgICAgbGVmdFRleHQgPSBsZWZ0VGV4dC5zdWJzdHIoU1RFUCk7XG4gICAgICAgIC8vIOWtl+espuS4suaVtOS9k+ayoeaciei2heWHulxuICAgICAgICBpZiAoIWxlZnRUZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gci5qb2luKCcnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyDmnIDkuIvnmoTmnIDlkI7kuIDkuKogU1RFUO+8jOS9v+eUqCAxIOmAkuWinu+8iOeUqOS6jOWIhuaViOaenOabtOmrmO+8iVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zdGFudC1jb25kaXRpb25cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAvLyDmm7TmlrDlrZfnrKbkuLJcbiAgICAgICAgY3VycmVudFRleHQgPSBsZWZ0VGV4dC5zdWJzdHIoMCwgMSk7XG4gICAgICAgIC8vIOiuoeeul+WuveW6plxuICAgICAgICBjdXJyZW50V2lkdGggPSBtZWFzdXJlVGV4dFdpZHRoKGN1cnJlbnRUZXh0LCBmb250KTtcbiAgICAgICAgLy8g6LaF5Ye65Ymp5L2Z5a695bqm77yM5YiZ5YGc5q2iXG4gICAgICAgIGlmIChjdXJyZW50V2lkdGggKyBQTEFDRUhPTERFUl9XSURUSCA+IGxlZnRXaWR0aCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgci5wdXNoKGN1cnJlbnRUZXh0KTtcbiAgICAgICAgLy8g5rKh5pyJ6LaF5Ye677yM5YiZ6K6h566X5Ymp5L2Z5a695bqmXG4gICAgICAgIGxlZnRXaWR0aCAtPSBjdXJyZW50V2lkdGg7XG4gICAgICAgIGxlZnRUZXh0ID0gbGVmdFRleHQuc3Vic3RyKDEpO1xuICAgICAgICBpZiAoIWxlZnRUZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gci5qb2luKCcnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gXCJcIiArIHIuam9pbignJykgKyBzdHI7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1lbGxpcHNpcy10ZXh0LmpzLm1hcCIsIi8qKlxuICogay12IOWtmOWCqFxuICovXG52YXIgZGVmYXVsdF8xID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIGRlZmF1bHRfMSgpIHtcbiAgICAgICAgdGhpcy5tYXAgPSB7fTtcbiAgICB9XG4gICAgZGVmYXVsdF8xLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcFtrZXldICE9PSB1bmRlZmluZWQ7XG4gICAgfTtcbiAgICBkZWZhdWx0XzEucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXksIGRlZikge1xuICAgICAgICB2YXIgdiA9IHRoaXMubWFwW2tleV07XG4gICAgICAgIHJldHVybiB2ID09PSB1bmRlZmluZWQgPyBkZWYgOiB2O1xuICAgIH07XG4gICAgZGVmYXVsdF8xLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLm1hcFtrZXldID0gdmFsdWU7XG4gICAgfTtcbiAgICBkZWZhdWx0XzEucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm1hcCA9IHt9O1xuICAgIH07XG4gICAgZGVmYXVsdF8xLnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm1hcFtrZXldO1xuICAgIH07XG4gICAgZGVmYXVsdF8xLnByb3RvdHlwZS5zaXplID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5tYXApLmxlbmd0aDtcbiAgICB9O1xuICAgIHJldHVybiBkZWZhdWx0XzE7XG59KCkpO1xuZXhwb3J0IGRlZmF1bHQgZGVmYXVsdF8xO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2FjaGUuanMubWFwIiwiLy8gYXJyYXlcbmV4cG9ydCB7IGRlZmF1bHQgYXMgY29udGFpbnMsIGRlZmF1bHQgYXMgaW5jbHVkZXMgfSBmcm9tICcuL2NvbnRhaW5zJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZGlmZmVyZW5jZSB9IGZyb20gJy4vZGlmZmVyZW5jZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGZpbmQgfSBmcm9tICcuL2ZpbmQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaW5kSW5kZXggfSBmcm9tICcuL2ZpbmQtaW5kZXgnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaXJzdFZhbHVlIH0gZnJvbSAnLi9maXJzdC12YWx1ZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGZsYXR0ZW4gfSBmcm9tICcuL2ZsYXR0ZW4nO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmbGF0dGVuRGVlcCB9IGZyb20gJy4vZmxhdHRlbi1kZWVwJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZ2V0UmFuZ2UgfSBmcm9tICcuL2dldC1yYW5nZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHB1bGwgfSBmcm9tICcuL3B1bGwnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBwdWxsQXQgfSBmcm9tICcuL3B1bGwtYXQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyByZWR1Y2UgfSBmcm9tICcuL3JlZHVjZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHJlbW92ZSB9IGZyb20gJy4vcmVtb3ZlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgc29ydEJ5IH0gZnJvbSAnLi9zb3J0LWJ5JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdW5pb24gfSBmcm9tICcuL3VuaW9uJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdW5pcSB9IGZyb20gJy4vdW5pcSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHZhbHVlc09mS2V5IH0gZnJvbSAnLi92YWx1ZXMtb2Yta2V5JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaGVhZCB9IGZyb20gJy4vaGVhZCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGxhc3QgfSBmcm9tICcuL2xhc3QnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzdGFydHNXaXRoIH0gZnJvbSAnLi9zdGFydHMtd2l0aCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGVuZHNXaXRoIH0gZnJvbSAnLi9lbmRzLXdpdGgnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaWx0ZXIgfSBmcm9tICcuL2ZpbHRlcic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGV2ZXJ5IH0gZnJvbSAnLi9ldmVyeSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHNvbWUgfSBmcm9tICcuL3NvbWUnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBncm91cCB9IGZyb20gJy4vZ3JvdXAnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBncm91cEJ5IH0gZnJvbSAnLi9ncm91cC1ieSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGdyb3VwVG9NYXAgfSBmcm9tICcuL2dyb3VwLXRvLW1hcCc7XG4vLyBldmVudFxuZXhwb3J0IHsgZGVmYXVsdCBhcyBnZXRXcmFwQmVoYXZpb3IgfSBmcm9tICcuL2dldC13cmFwLWJlaGF2aW9yJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgd3JhcEJlaGF2aW9yIH0gZnJvbSAnLi93cmFwLWJlaGF2aW9yJztcbi8vIGZvcm1hdFxuZXhwb3J0IHsgZGVmYXVsdCBhcyBudW1iZXIyY29sb3IgfSBmcm9tICcuL251bWJlcjJjb2xvcic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHBhcnNlUmFkaXVzIH0gZnJvbSAnLi9wYXJzZS1yYWRpdXMnO1xuLy8gbWF0aFxuZXhwb3J0IHsgZGVmYXVsdCBhcyBjbGFtcCB9IGZyb20gJy4vY2xhbXAnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaXhlZEJhc2UgfSBmcm9tICcuL2ZpeGVkLWJhc2UnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0RlY2ltYWwgfSBmcm9tICcuL2lzLWRlY2ltYWwnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0V2ZW4gfSBmcm9tICcuL2lzLWV2ZW4nO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0ludGVnZXIgfSBmcm9tICcuL2lzLWludGVnZXInO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc05lZ2F0aXZlIH0gZnJvbSAnLi9pcy1uZWdhdGl2ZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzTnVtYmVyRXF1YWwgfSBmcm9tICcuL2lzLW51bWJlci1lcXVhbCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzT2RkIH0gZnJvbSAnLi9pcy1vZGQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc1Bvc2l0aXZlIH0gZnJvbSAnLi9pcy1wb3NpdGl2ZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG1heCB9IGZyb20gJy4vbWF4JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbWF4QnkgfSBmcm9tICcuL21heC1ieSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG1pbiB9IGZyb20gJy4vbWluJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbWluQnkgfSBmcm9tICcuL21pbi1ieSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG1vZCB9IGZyb20gJy4vbW9kJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdG9EZWdyZWUgfSBmcm9tICcuL3RvLWRlZ3JlZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHRvSW50ZWdlciB9IGZyb20gJy4vdG8taW50ZWdlcic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHRvUmFkaWFuIH0gZnJvbSAnLi90by1yYWRpYW4nO1xuLy8gb2JqZWN0XG5leHBvcnQgeyBkZWZhdWx0IGFzIGZvckluIH0gZnJvbSAnLi9mb3ItaW4nO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBoYXMgfSBmcm9tICcuL2hhcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGhhc0tleSB9IGZyb20gJy4vaGFzLWtleSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGhhc1ZhbHVlIH0gZnJvbSAnLi9oYXMtdmFsdWUnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBrZXlzIH0gZnJvbSAnLi9rZXlzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNNYXRjaCB9IGZyb20gJy4vaXMtbWF0Y2gnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB2YWx1ZXMgfSBmcm9tICcuL3ZhbHVlcyc7XG4vLyBzdHJpbmdcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbG93ZXJDYXNlIH0gZnJvbSAnLi9sb3dlci1jYXNlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbG93ZXJGaXJzdCB9IGZyb20gJy4vbG93ZXItZmlyc3QnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzdWJzdGl0dXRlIH0gZnJvbSAnLi9zdWJzdGl0dXRlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdXBwZXJDYXNlIH0gZnJvbSAnLi91cHBlci1jYXNlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdXBwZXJGaXJzdCB9IGZyb20gJy4vdXBwZXItZmlyc3QnO1xuLy8gdHlwZVxuZXhwb3J0IHsgZGVmYXVsdCBhcyBnZXRUeXBlIH0gZnJvbSAnLi9nZXQtdHlwZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzQXJndW1lbnRzIH0gZnJvbSAnLi9pcy1hcmd1bWVudHMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0FycmF5IH0gZnJvbSAnLi9pcy1hcnJheSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzQXJyYXlMaWtlIH0gZnJvbSAnLi9pcy1hcnJheS1saWtlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNCb29sZWFuIH0gZnJvbSAnLi9pcy1ib29sZWFuJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNEYXRlIH0gZnJvbSAnLi9pcy1kYXRlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNFcnJvciB9IGZyb20gJy4vaXMtZXJyb3InO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0Z1bmN0aW9uIH0gZnJvbSAnLi9pcy1mdW5jdGlvbic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzRmluaXRlIH0gZnJvbSAnLi9pcy1maW5pdGUnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc05pbCB9IGZyb20gJy4vaXMtbmlsJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNOdWxsIH0gZnJvbSAnLi9pcy1udWxsJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNOdW1iZXIgfSBmcm9tICcuL2lzLW51bWJlcic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzT2JqZWN0IH0gZnJvbSAnLi9pcy1vYmplY3QnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc09iamVjdExpa2UgfSBmcm9tICcuL2lzLW9iamVjdC1saWtlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNQbGFpbk9iamVjdCB9IGZyb20gJy4vaXMtcGxhaW4tb2JqZWN0JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNQcm90b3R5cGUgfSBmcm9tICcuL2lzLXByb3RvdHlwZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzUmVnRXhwIH0gZnJvbSAnLi9pcy1yZWctZXhwJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNTdHJpbmcgfSBmcm9tICcuL2lzLXN0cmluZyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzVHlwZSB9IGZyb20gJy4vaXMtdHlwZSc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzVW5kZWZpbmVkIH0gZnJvbSAnLi9pcy11bmRlZmluZWQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0VsZW1lbnQgfSBmcm9tICcuL2lzLWVsZW1lbnQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfSBmcm9tICcuL3JlcXVlc3QtYW5pbWF0aW9uLWZyYW1lJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgY2xlYXJBbmltYXRpb25GcmFtZSB9IGZyb20gJy4vY2xlYXItYW5pbWF0aW9uLWZyYW1lJztcbi8vIG90aGVyXG5leHBvcnQgeyBkZWZhdWx0IGFzIGF1Z21lbnQgfSBmcm9tICcuL2F1Z21lbnQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBjbG9uZSB9IGZyb20gJy4vY2xvbmUnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBkZWJvdW5jZSB9IGZyb20gJy4vZGVib3VuY2UnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBtZW1vaXplIH0gZnJvbSAnLi9tZW1vaXplJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZGVlcE1peCB9IGZyb20gJy4vZGVlcC1taXgnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBlYWNoIH0gZnJvbSAnLi9lYWNoJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZXh0ZW5kIH0gZnJvbSAnLi9leHRlbmQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpbmRleE9mIH0gZnJvbSAnLi9pbmRleC1vZic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGlzRW1wdHkgfSBmcm9tICcuL2lzLWVtcHR5JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNFcXVhbCB9IGZyb20gJy4vaXMtZXF1YWwnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpc0VxdWFsV2l0aCB9IGZyb20gJy4vaXMtZXF1YWwtd2l0aCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG1hcCB9IGZyb20gJy4vbWFwJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbWFwVmFsdWVzIH0gZnJvbSAnLi9tYXAtdmFsdWVzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbWl4LCBkZWZhdWx0IGFzIGFzc2lnbiB9IGZyb20gJy4vbWl4JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZ2V0IH0gZnJvbSAnLi9nZXQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzZXQgfSBmcm9tICcuL3NldCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHBpY2sgfSBmcm9tICcuL3BpY2snO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBvbWl0IH0gZnJvbSAnLi9vbWl0JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdGhyb3R0bGUgfSBmcm9tICcuL3Rocm90dGxlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdG9BcnJheSB9IGZyb20gJy4vdG8tYXJyYXknO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyB0b1N0cmluZyB9IGZyb20gJy4vdG8tc3RyaW5nJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgdW5pcXVlSWQgfSBmcm9tICcuL3VuaXF1ZS1pZCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIG5vb3AgfSBmcm9tICcuL25vb3AnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBpZGVudGl0eSB9IGZyb20gJy4vaWRlbnRpdHknO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBzaXplIH0gZnJvbSAnLi9zaXplJztcbi8vIHRleHRcbmV4cG9ydCB7IGRlZmF1bHQgYXMgbWVhc3VyZVRleHRXaWR0aCB9IGZyb20gJy4vbWVhc3VyZS10ZXh0LXdpZHRoJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZ2V0RWxsaXBzaXNUZXh0IH0gZnJvbSAnLi9nZXQtZWxsaXBzaXMtdGV4dCc7XG4vLyDkuI3nn6XpgZPkuLrku4DkuYjvvIzpnIDopoHmiorov5nkuKogZXhwb3J077yM5LiN54S2IHRzIOS8muaKpeexu+Wei+mUmeivr1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBDYWNoZSB9IGZyb20gJy4vY2FjaGUnO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__extends", function() { return __extends; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__assign", function() { return __assign; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__rest", function() { return __rest; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__decorate", function() { return __decorate; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__param", function() { return __param; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__createBinding", function() { return __createBinding; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spread", function() { return __spread; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spreadArrays", function() { return __spreadArrays; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spreadArray", function() { return __spreadArray; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__await", function() { return __await; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncGenerator", function() { return __asyncGenerator; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncDelegator", function() { return __asyncDelegator; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncValues", function() { return __asyncValues; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldGet", function() { return __classPrivateFieldGet; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldSet", function() { return __classPrivateFieldSet; });\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n if (typeof b !== "function" && b !== null)\r\n throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nfunction __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nfunction __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError("Generator is already executing.");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nvar __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nfunction __exportStar(m, o) {\r\n for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nfunction __values(o) {\r\n var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === "number") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");\r\n}\r\n\r\nfunction __read(o, n) {\r\n var m = typeof Symbol === "function" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i["return"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume("next", value); }\r\n function reject(value) { resume("throw", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, "default", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o["default"] = v;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");\r\n return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === "m") throw new TypeError("Private method is not writable");\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");\r\n return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzPzlhYjQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVLGdCQUFnQixzQ0FBc0MsaUJBQWlCLEVBQUU7QUFDbkYseUJBQXlCLDhFQUE4RTtBQUN2RztBQUNBOztBQUVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHNCQUFzQjtBQUN6QztBQUNBOztBQUVPO0FBQ1A7QUFDQSxnREFBZ0QsT0FBTztBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTRELGNBQWM7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQSw0Q0FBNEMsUUFBUTtBQUNwRDtBQUNBOztBQUVPO0FBQ1AsbUNBQW1DLG9DQUFvQztBQUN2RTs7QUFFTztBQUNQO0FBQ0E7O0FBRU87QUFDUCwyQkFBMkIsK0RBQStELGdCQUFnQixFQUFFLEVBQUU7QUFDOUc7QUFDQSxtQ0FBbUMsTUFBTSw2QkFBNkIsRUFBRSxZQUFZLFdBQVcsRUFBRTtBQUNqRyxrQ0FBa0MsTUFBTSxpQ0FBaUMsRUFBRSxZQUFZLFdBQVcsRUFBRTtBQUNwRywrQkFBK0IscUZBQXFGO0FBQ3BIO0FBQ0EsS0FBSztBQUNMOztBQUVPO0FBQ1AsYUFBYSw2QkFBNkIsMEJBQTBCLGFBQWEsRUFBRSxxQkFBcUI7QUFDeEcsZ0JBQWdCLHFEQUFxRCxvRUFBb0UsYUFBYSxFQUFFO0FBQ3hKLHNCQUFzQixzQkFBc0IscUJBQXFCLEdBQUc7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDO0FBQ3ZDLGtDQUFrQyxTQUFTO0FBQzNDLGtDQUFrQyxXQUFXLFVBQVU7QUFDdkQseUNBQXlDLGNBQWM7QUFDdkQ7QUFDQSw2R0FBNkcsT0FBTyxVQUFVO0FBQzlILGdGQUFnRixpQkFBaUIsT0FBTztBQUN4Ryx3REFBd0QsZ0JBQWdCLFFBQVEsT0FBTztBQUN2Riw4Q0FBOEMsZ0JBQWdCLGdCQUFnQixPQUFPO0FBQ3JGO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQSxTQUFTLFlBQVksYUFBYSxPQUFPLEVBQUUsVUFBVSxXQUFXO0FBQ2hFLG1DQUFtQyxTQUFTO0FBQzVDO0FBQ0E7O0FBRU87QUFDUDtBQUNBLGtDQUFrQyxvQ0FBb0MsYUFBYSxFQUFFLEVBQUU7QUFDdkYsQ0FBQztBQUNEO0FBQ0E7QUFDQSxDQUFDOztBQUVNO0FBQ1A7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsTUFBTSxnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsc0JBQXNCO0FBQ3ZDO0FBQ0E7QUFDQTs7QUFFQTtBQUNPO0FBQ1AsNEJBQTRCLHNCQUFzQjtBQUNsRDtBQUNBO0FBQ0E7O0FBRUE7QUFDTztBQUNQLGlEQUFpRCxRQUFRO0FBQ3pELHdDQUF3QyxRQUFRO0FBQ2hELHdEQUF3RCxRQUFRO0FBQ2hFO0FBQ0E7QUFDQTs7QUFFTztBQUNQLDRFQUE0RSxPQUFPO0FBQ25GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVPO0FBQ1A7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQSxpQkFBaUIsc0ZBQXNGLGFBQWEsRUFBRTtBQUN0SCxzQkFBc0IsZ0NBQWdDLHFDQUFxQywwQ0FBMEMsRUFBRSxFQUFFLEdBQUc7QUFDNUksMkJBQTJCLE1BQU0sZUFBZSxFQUFFLFlBQVksb0JBQW9CLEVBQUU7QUFDcEYsc0JBQXNCLG9HQUFvRztBQUMxSCw2QkFBNkIsdUJBQXVCO0FBQ3BELDRCQUE0Qix3QkFBd0I7QUFDcEQsMkJBQTJCLHlEQUF5RDtBQUNwRjs7QUFFTztBQUNQO0FBQ0EsaUJBQWlCLDRDQUE0QyxTQUFTLEVBQUUscURBQXFELGFBQWEsRUFBRTtBQUM1SSx5QkFBeUIsNkJBQTZCLG9CQUFvQixnREFBZ0QsZ0JBQWdCLEVBQUUsS0FBSztBQUNqSjs7QUFFTztBQUNQO0FBQ0E7QUFDQSwyR0FBMkcsc0ZBQXNGLGFBQWEsRUFBRTtBQUNoTixzQkFBc0IsOEJBQThCLGdEQUFnRCx1REFBdUQsRUFBRSxFQUFFLEdBQUc7QUFDbEssNENBQTRDLHNDQUFzQyxVQUFVLG9CQUFvQixFQUFFLEVBQUUsVUFBVTtBQUM5SDs7QUFFTztBQUNQLGdDQUFnQyx1Q0FBdUMsYUFBYSxFQUFFLEVBQUUsT0FBTyxrQkFBa0I7QUFDakg7QUFDQTs7QUFFQTtBQUNBLHlDQUF5Qyw2QkFBNkI7QUFDdEUsQ0FBQztBQUNEO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRU87QUFDUCw0Q0FBNEM7QUFDNUM7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTs7QUFFTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfSk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///1\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, "a", function() { return /* reexport */ mat3_namespaceObject; });\n__webpack_require__.d(__webpack_exports__, "b", function() { return /* reexport */ mat4_namespaceObject; });\n__webpack_require__.d(__webpack_exports__, "c", function() { return /* reexport */ quat_namespaceObject; });\n__webpack_require__.d(__webpack_exports__, "d", function() { return /* reexport */ vec2; });\n__webpack_require__.d(__webpack_exports__, "e", function() { return /* reexport */ vec3; });\n__webpack_require__.d(__webpack_exports__, "f", function() { return /* reexport */ vec4_namespaceObject; });\n\n// UNUSED EXPORTS: glMatrix, mat2, mat2d, quat2\n\n// NAMESPACE OBJECT: ./node_modules/gl-matrix/esm/mat3.js\nvar mat3_namespaceObject = {};\n__webpack_require__.r(mat3_namespaceObject);\n__webpack_require__.d(mat3_namespaceObject, "create", function() { return create; });\n__webpack_require__.d(mat3_namespaceObject, "fromMat4", function() { return fromMat4; });\n__webpack_require__.d(mat3_namespaceObject, "clone", function() { return clone; });\n__webpack_require__.d(mat3_namespaceObject, "copy", function() { return copy; });\n__webpack_require__.d(mat3_namespaceObject, "fromValues", function() { return fromValues; });\n__webpack_require__.d(mat3_namespaceObject, "set", function() { return set; });\n__webpack_require__.d(mat3_namespaceObject, "identity", function() { return identity; });\n__webpack_require__.d(mat3_namespaceObject, "transpose", function() { return transpose; });\n__webpack_require__.d(mat3_namespaceObject, "invert", function() { return invert; });\n__webpack_require__.d(mat3_namespaceObject, "adjoint", function() { return adjoint; });\n__webpack_require__.d(mat3_namespaceObject, "determinant", function() { return determinant; });\n__webpack_require__.d(mat3_namespaceObject, "multiply", function() { return multiply; });\n__webpack_require__.d(mat3_namespaceObject, "translate", function() { return translate; });\n__webpack_require__.d(mat3_namespaceObject, "rotate", function() { return rotate; });\n__webpack_require__.d(mat3_namespaceObject, "scale", function() { return mat3_scale; });\n__webpack_require__.d(mat3_namespaceObject, "fromTranslation", function() { return fromTranslation; });\n__webpack_require__.d(mat3_namespaceObject, "fromRotation", function() { return fromRotation; });\n__webpack_require__.d(mat3_namespaceObject, "fromScaling", function() { return fromScaling; });\n__webpack_require__.d(mat3_namespaceObject, "fromMat2d", function() { return fromMat2d; });\n__webpack_require__.d(mat3_namespaceObject, "fromQuat", function() { return fromQuat; });\n__webpack_require__.d(mat3_namespaceObject, "normalFromMat4", function() { return normalFromMat4; });\n__webpack_require__.d(mat3_namespaceObject, "projection", function() { return projection; });\n__webpack_require__.d(mat3_namespaceObject, "str", function() { return str; });\n__webpack_require__.d(mat3_namespaceObject, "frob", function() { return frob; });\n__webpack_require__.d(mat3_namespaceObject, "add", function() { return add; });\n__webpack_require__.d(mat3_namespaceObject, "subtract", function() { return subtract; });\n__webpack_require__.d(mat3_namespaceObject, "multiplyScalar", function() { return multiplyScalar; });\n__webpack_require__.d(mat3_namespaceObject, "multiplyScalarAndAdd", function() { return multiplyScalarAndAdd; });\n__webpack_require__.d(mat3_namespaceObject, "exactEquals", function() { return exactEquals; });\n__webpack_require__.d(mat3_namespaceObject, "equals", function() { return equals; });\n__webpack_require__.d(mat3_namespaceObject, "mul", function() { return mul; });\n__webpack_require__.d(mat3_namespaceObject, "sub", function() { return sub; });\n\n// NAMESPACE OBJECT: ./node_modules/gl-matrix/esm/mat4.js\nvar mat4_namespaceObject = {};\n__webpack_require__.r(mat4_namespaceObject);\n__webpack_require__.d(mat4_namespaceObject, "create", function() { return mat4_create; });\n__webpack_require__.d(mat4_namespaceObject, "clone", function() { return mat4_clone; });\n__webpack_require__.d(mat4_namespaceObject, "copy", function() { return mat4_copy; });\n__webpack_require__.d(mat4_namespaceObject, "fromValues", function() { return mat4_fromValues; });\n__webpack_require__.d(mat4_namespaceObject, "set", function() { return mat4_set; });\n__webpack_require__.d(mat4_namespaceObject, "identity", function() { return mat4_identity; });\n__webpack_require__.d(mat4_namespaceObject, "transpose", function() { return mat4_transpose; });\n__webpack_require__.d(mat4_namespaceObject, "invert", function() { return mat4_invert; });\n__webpack_require__.d(mat4_namespaceObject, "adjoint", function() { return mat4_adjoint; });\n__webpack_require__.d(mat4_namespaceObject, "determinant", function() { return mat4_determinant; });\n__webpack_require__.d(mat4_namespaceObject, "multiply", function() { return mat4_multiply; });\n__webpack_require__.d(mat4_namespaceObject, "translate", function() { return mat4_translate; });\n__webpack_require__.d(mat4_namespaceObject, "scale", function() { return mat4_scale; });\n__webpack_require__.d(mat4_namespaceObject, "rotate", function() { return mat4_rotate; });\n__webpack_require__.d(mat4_namespaceObject, "rotateX", function() { return rotateX; });\n__webpack_require__.d(mat4_namespaceObject, "rotateY", function() { return rotateY; });\n__webpack_require__.d(mat4_namespaceObject, "rotateZ", function() { return rotateZ; });\n__webpack_require__.d(mat4_namespaceObject, "fromTranslation", function() { return mat4_fromTranslation; });\n__webpack_require__.d(mat4_namespaceObject, "fromScaling", function() { return mat4_fromScaling; });\n__webpack_require__.d(mat4_namespaceObject, "fromRotation", function() { return mat4_fromRotation; });\n__webpack_require__.d(mat4_namespaceObject, "fromXRotation", function() { return fromXRotation; });\n__webpack_require__.d(mat4_namespaceObject, "fromYRotation", function() { return fromYRotation; });\n__webpack_require__.d(mat4_namespaceObject, "fromZRotation", function() { return fromZRotation; });\n__webpack_require__.d(mat4_namespaceObject, "fromRotationTranslation", function() { return fromRotationTranslation; });\n__webpack_require__.d(mat4_namespaceObject, "fromQuat2", function() { return fromQuat2; });\n__webpack_require__.d(mat4_namespaceObject, "getTranslation", function() { return getTranslation; });\n__webpack_require__.d(mat4_namespaceObject, "getScaling", function() { return getScaling; });\n__webpack_require__.d(mat4_namespaceObject, "getRotation", function() { return getRotation; });\n__webpack_require__.d(mat4_namespaceObject, "fromRotationTranslationScale", function() { return fromRotationTranslationScale; });\n__webpack_require__.d(mat4_namespaceObject, "fromRotationTranslationScaleOrigin", function() { return fromRotationTranslationScaleOrigin; });\n__webpack_require__.d(mat4_namespaceObject, "fromQuat", function() { return mat4_fromQuat; });\n__webpack_require__.d(mat4_namespaceObject, "frustum", function() { return frustum; });\n__webpack_require__.d(mat4_namespaceObject, "perspectiveNO", function() { return perspectiveNO; });\n__webpack_require__.d(mat4_namespaceObject, "perspective", function() { return perspective; });\n__webpack_require__.d(mat4_namespaceObject, "perspectiveZO", function() { return perspectiveZO; });\n__webpack_require__.d(mat4_namespaceObject, "perspectiveFromFieldOfView", function() { return perspectiveFromFieldOfView; });\n__webpack_require__.d(mat4_namespaceObject, "orthoNO", function() { return orthoNO; });\n__webpack_require__.d(mat4_namespaceObject, "ortho", function() { return ortho; });\n__webpack_require__.d(mat4_namespaceObject, "orthoZO", function() { return orthoZO; });\n__webpack_require__.d(mat4_namespaceObject, "lookAt", function() { return lookAt; });\n__webpack_require__.d(mat4_namespaceObject, "targetTo", function() { return targetTo; });\n__webpack_require__.d(mat4_namespaceObject, "str", function() { return mat4_str; });\n__webpack_require__.d(mat4_namespaceObject, "frob", function() { return mat4_frob; });\n__webpack_require__.d(mat4_namespaceObject, "add", function() { return mat4_add; });\n__webpack_require__.d(mat4_namespaceObject, "subtract", function() { return mat4_subtract; });\n__webpack_require__.d(mat4_namespaceObject, "multiplyScalar", function() { return mat4_multiplyScalar; });\n__webpack_require__.d(mat4_namespaceObject, "multiplyScalarAndAdd", function() { return mat4_multiplyScalarAndAdd; });\n__webpack_require__.d(mat4_namespaceObject, "exactEquals", function() { return mat4_exactEquals; });\n__webpack_require__.d(mat4_namespaceObject, "equals", function() { return mat4_equals; });\n__webpack_require__.d(mat4_namespaceObject, "mul", function() { return mat4_mul; });\n__webpack_require__.d(mat4_namespaceObject, "sub", function() { return mat4_sub; });\n\n// NAMESPACE OBJECT: ./node_modules/gl-matrix/esm/vec4.js\nvar vec4_namespaceObject = {};\n__webpack_require__.r(vec4_namespaceObject);\n__webpack_require__.d(vec4_namespaceObject, "create", function() { return vec4_create; });\n__webpack_require__.d(vec4_namespaceObject, "clone", function() { return vec4_clone; });\n__webpack_require__.d(vec4_namespaceObject, "fromValues", function() { return vec4_fromValues; });\n__webpack_require__.d(vec4_namespaceObject, "copy", function() { return vec4_copy; });\n__webpack_require__.d(vec4_namespaceObject, "set", function() { return vec4_set; });\n__webpack_require__.d(vec4_namespaceObject, "add", function() { return vec4_add; });\n__webpack_require__.d(vec4_namespaceObject, "subtract", function() { return vec4_subtract; });\n__webpack_require__.d(vec4_namespaceObject, "multiply", function() { return vec4_multiply; });\n__webpack_require__.d(vec4_namespaceObject, "divide", function() { return divide; });\n__webpack_require__.d(vec4_namespaceObject, "ceil", function() { return ceil; });\n__webpack_require__.d(vec4_namespaceObject, "floor", function() { return floor; });\n__webpack_require__.d(vec4_namespaceObject, "min", function() { return min; });\n__webpack_require__.d(vec4_namespaceObject, "max", function() { return max; });\n__webpack_require__.d(vec4_namespaceObject, "round", function() { return round; });\n__webpack_require__.d(vec4_namespaceObject, "scale", function() { return vec4_scale; });\n__webpack_require__.d(vec4_namespaceObject, "scaleAndAdd", function() { return scaleAndAdd; });\n__webpack_require__.d(vec4_namespaceObject, "distance", function() { return distance; });\n__webpack_require__.d(vec4_namespaceObject, "squaredDistance", function() { return squaredDistance; });\n__webpack_require__.d(vec4_namespaceObject, "length", function() { return vec4_length; });\n__webpack_require__.d(vec4_namespaceObject, "squaredLength", function() { return squaredLength; });\n__webpack_require__.d(vec4_namespaceObject, "negate", function() { return negate; });\n__webpack_require__.d(vec4_namespaceObject, "inverse", function() { return inverse; });\n__webpack_require__.d(vec4_namespaceObject, "normalize", function() { return normalize; });\n__webpack_require__.d(vec4_namespaceObject, "dot", function() { return vec4_dot; });\n__webpack_require__.d(vec4_namespaceObject, "cross", function() { return cross; });\n__webpack_require__.d(vec4_namespaceObject, "lerp", function() { return lerp; });\n__webpack_require__.d(vec4_namespaceObject, "random", function() { return random; });\n__webpack_require__.d(vec4_namespaceObject, "transformMat4", function() { return transformMat4; });\n__webpack_require__.d(vec4_namespaceObject, "transformQuat", function() { return transformQuat; });\n__webpack_require__.d(vec4_namespaceObject, "zero", function() { return zero; });\n__webpack_require__.d(vec4_namespaceObject, "str", function() { return vec4_str; });\n__webpack_require__.d(vec4_namespaceObject, "exactEquals", function() { return vec4_exactEquals; });\n__webpack_require__.d(vec4_namespaceObject, "equals", function() { return vec4_equals; });\n__webpack_require__.d(vec4_namespaceObject, "sub", function() { return vec4_sub; });\n__webpack_require__.d(vec4_namespaceObject, "mul", function() { return vec4_mul; });\n__webpack_require__.d(vec4_namespaceObject, "div", function() { return div; });\n__webpack_require__.d(vec4_namespaceObject, "dist", function() { return dist; });\n__webpack_require__.d(vec4_namespaceObject, "sqrDist", function() { return sqrDist; });\n__webpack_require__.d(vec4_namespaceObject, "len", function() { return vec4_len; });\n__webpack_require__.d(vec4_namespaceObject, "sqrLen", function() { return sqrLen; });\n__webpack_require__.d(vec4_namespaceObject, "forEach", function() { return forEach; });\n\n// NAMESPACE OBJECT: ./node_modules/gl-matrix/esm/quat.js\nvar quat_namespaceObject = {};\n__webpack_require__.r(quat_namespaceObject);\n__webpack_require__.d(quat_namespaceObject, "create", function() { return quat_create; });\n__webpack_require__.d(quat_namespaceObject, "identity", function() { return quat_identity; });\n__webpack_require__.d(quat_namespaceObject, "setAxisAngle", function() { return setAxisAngle; });\n__webpack_require__.d(quat_namespaceObject, "getAxisAngle", function() { return getAxisAngle; });\n__webpack_require__.d(quat_namespaceObject, "getAngle", function() { return getAngle; });\n__webpack_require__.d(quat_namespaceObject, "multiply", function() { return quat_multiply; });\n__webpack_require__.d(quat_namespaceObject, "rotateX", function() { return quat_rotateX; });\n__webpack_require__.d(quat_namespaceObject, "rotateY", function() { return quat_rotateY; });\n__webpack_require__.d(quat_namespaceObject, "rotateZ", function() { return quat_rotateZ; });\n__webpack_require__.d(quat_namespaceObject, "calculateW", function() { return calculateW; });\n__webpack_require__.d(quat_namespaceObject, "exp", function() { return exp; });\n__webpack_require__.d(quat_namespaceObject, "ln", function() { return ln; });\n__webpack_require__.d(quat_namespaceObject, "pow", function() { return pow; });\n__webpack_require__.d(quat_namespaceObject, "slerp", function() { return slerp; });\n__webpack_require__.d(quat_namespaceObject, "random", function() { return quat_random; });\n__webpack_require__.d(quat_namespaceObject, "invert", function() { return quat_invert; });\n__webpack_require__.d(quat_namespaceObject, "conjugate", function() { return conjugate; });\n__webpack_require__.d(quat_namespaceObject, "fromMat3", function() { return fromMat3; });\n__webpack_require__.d(quat_namespaceObject, "fromEuler", function() { return fromEuler; });\n__webpack_require__.d(quat_namespaceObject, "str", function() { return quat_str; });\n__webpack_require__.d(quat_namespaceObject, "clone", function() { return quat_clone; });\n__webpack_require__.d(quat_namespaceObject, "fromValues", function() { return quat_fromValues; });\n__webpack_require__.d(quat_namespaceObject, "copy", function() { return quat_copy; });\n__webpack_require__.d(quat_namespaceObject, "set", function() { return quat_set; });\n__webpack_require__.d(quat_namespaceObject, "add", function() { return quat_add; });\n__webpack_require__.d(quat_namespaceObject, "mul", function() { return quat_mul; });\n__webpack_require__.d(quat_namespaceObject, "scale", function() { return quat_scale; });\n__webpack_require__.d(quat_namespaceObject, "dot", function() { return quat_dot; });\n__webpack_require__.d(quat_namespaceObject, "lerp", function() { return quat_lerp; });\n__webpack_require__.d(quat_namespaceObject, "length", function() { return quat_length; });\n__webpack_require__.d(quat_namespaceObject, "len", function() { return quat_len; });\n__webpack_require__.d(quat_namespaceObject, "squaredLength", function() { return quat_squaredLength; });\n__webpack_require__.d(quat_namespaceObject, "sqrLen", function() { return quat_sqrLen; });\n__webpack_require__.d(quat_namespaceObject, "normalize", function() { return quat_normalize; });\n__webpack_require__.d(quat_namespaceObject, "exactEquals", function() { return quat_exactEquals; });\n__webpack_require__.d(quat_namespaceObject, "equals", function() { return quat_equals; });\n__webpack_require__.d(quat_namespaceObject, "rotationTo", function() { return rotationTo; });\n__webpack_require__.d(quat_namespaceObject, "sqlerp", function() { return sqlerp; });\n__webpack_require__.d(quat_namespaceObject, "setAxes", function() { return setAxes; });\n\n// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/common.js\nvar common = __webpack_require__(12);\n\n// CONCATENATED MODULE: ./node_modules/gl-matrix/esm/mat3.js\n\n/**\n * 3x3 Matrix\n * @module mat3\n */\n\n/**\n * Creates a new identity mat3\n *\n * @returns {mat3} a new 3x3 matrix\n */\n\nfunction create() {\n var out = new common["a" /* ARRAY_TYPE */](9);\n\n if (common["a" /* ARRAY_TYPE */] != Float32Array) {\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n }\n\n out[0] = 1;\n out[4] = 1;\n out[8] = 1;\n return out;\n}\n/**\n * Copies the upper-left 3x3 values into the given mat3.\n *\n * @param {mat3} out the receiving 3x3 matrix\n * @param {ReadonlyMat4} a the source 4x4 matrix\n * @returns {mat3} out\n */\n\nfunction fromMat4(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[4];\n out[4] = a[5];\n out[5] = a[6];\n out[6] = a[8];\n out[7] = a[9];\n out[8] = a[10];\n return out;\n}\n/**\n * Creates a new mat3 initialized with values from an existing matrix\n *\n * @param {ReadonlyMat3} a matrix to clone\n * @returns {mat3} a new 3x3 matrix\n */\n\nfunction clone(a) {\n var out = new common["a" /* ARRAY_TYPE */](9);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n return out;\n}\n/**\n * Copy the values from one mat3 to another\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\n\nfunction copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n return out;\n}\n/**\n * Create a new mat3 with the given values\n *\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m10 Component in column 1, row 0 position (index 3)\n * @param {Number} m11 Component in column 1, row 1 position (index 4)\n * @param {Number} m12 Component in column 1, row 2 position (index 5)\n * @param {Number} m20 Component in column 2, row 0 position (index 6)\n * @param {Number} m21 Component in column 2, row 1 position (index 7)\n * @param {Number} m22 Component in column 2, row 2 position (index 8)\n * @returns {mat3} A new mat3\n */\n\nfunction fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n var out = new common["a" /* ARRAY_TYPE */](9);\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m10;\n out[4] = m11;\n out[5] = m12;\n out[6] = m20;\n out[7] = m21;\n out[8] = m22;\n return out;\n}\n/**\n * Set the components of a mat3 to the given values\n *\n * @param {mat3} out the receiving matrix\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m10 Component in column 1, row 0 position (index 3)\n * @param {Number} m11 Component in column 1, row 1 position (index 4)\n * @param {Number} m12 Component in column 1, row 2 position (index 5)\n * @param {Number} m20 Component in column 2, row 0 position (index 6)\n * @param {Number} m21 Component in column 2, row 1 position (index 7)\n * @param {Number} m22 Component in column 2, row 2 position (index 8)\n * @returns {mat3} out\n */\n\nfunction set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m10;\n out[4] = m11;\n out[5] = m12;\n out[6] = m20;\n out[7] = m21;\n out[8] = m22;\n return out;\n}\n/**\n * Set a mat3 to the identity matrix\n *\n * @param {mat3} out the receiving matrix\n * @returns {mat3} out\n */\n\nfunction identity(out) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 1;\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 1;\n return out;\n}\n/**\n * Transpose the values of a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\n\nfunction transpose(out, a) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n if (out === a) {\n var a01 = a[1],\n a02 = a[2],\n a12 = a[5];\n out[1] = a[3];\n out[2] = a[6];\n out[3] = a01;\n out[5] = a[7];\n out[6] = a02;\n out[7] = a12;\n } else {\n out[0] = a[0];\n out[1] = a[3];\n out[2] = a[6];\n out[3] = a[1];\n out[4] = a[4];\n out[5] = a[7];\n out[6] = a[2];\n out[7] = a[5];\n out[8] = a[8];\n }\n\n return out;\n}\n/**\n * Inverts a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\n\nfunction invert(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n var b01 = a22 * a11 - a12 * a21;\n var b11 = -a22 * a10 + a12 * a20;\n var b21 = a21 * a10 - a11 * a20; // Calculate the determinant\n\n var det = a00 * b01 + a01 * b11 + a02 * b21;\n\n if (!det) {\n return null;\n }\n\n det = 1.0 / det;\n out[0] = b01 * det;\n out[1] = (-a22 * a01 + a02 * a21) * det;\n out[2] = (a12 * a01 - a02 * a11) * det;\n out[3] = b11 * det;\n out[4] = (a22 * a00 - a02 * a20) * det;\n out[5] = (-a12 * a00 + a02 * a10) * det;\n out[6] = b21 * det;\n out[7] = (-a21 * a00 + a01 * a20) * det;\n out[8] = (a11 * a00 - a01 * a10) * det;\n return out;\n}\n/**\n * Calculates the adjugate of a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the source matrix\n * @returns {mat3} out\n */\n\nfunction adjoint(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n out[0] = a11 * a22 - a12 * a21;\n out[1] = a02 * a21 - a01 * a22;\n out[2] = a01 * a12 - a02 * a11;\n out[3] = a12 * a20 - a10 * a22;\n out[4] = a00 * a22 - a02 * a20;\n out[5] = a02 * a10 - a00 * a12;\n out[6] = a10 * a21 - a11 * a20;\n out[7] = a01 * a20 - a00 * a21;\n out[8] = a00 * a11 - a01 * a10;\n return out;\n}\n/**\n * Calculates the determinant of a mat3\n *\n * @param {ReadonlyMat3} a the source matrix\n * @returns {Number} determinant of a\n */\n\nfunction determinant(a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);\n}\n/**\n * Multiplies two mat3\'s\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\n\nfunction multiply(out, a, b) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2];\n var a10 = a[3],\n a11 = a[4],\n a12 = a[5];\n var a20 = a[6],\n a21 = a[7],\n a22 = a[8];\n var b00 = b[0],\n b01 = b[1],\n b02 = b[2];\n var b10 = b[3],\n b11 = b[4],\n b12 = b[5];\n var b20 = b[6],\n b21 = b[7],\n b22 = b[8];\n out[0] = b00 * a00 + b01 * a10 + b02 * a20;\n out[1] = b00 * a01 + b01 * a11 + b02 * a21;\n out[2] = b00 * a02 + b01 * a12 + b02 * a22;\n out[3] = b10 * a00 + b11 * a10 + b12 * a20;\n out[4] = b10 * a01 + b11 * a11 + b12 * a21;\n out[5] = b10 * a02 + b11 * a12 + b12 * a22;\n out[6] = b20 * a00 + b21 * a10 + b22 * a20;\n out[7] = b20 * a01 + b21 * a11 + b22 * a21;\n out[8] = b20 * a02 + b21 * a12 + b22 * a22;\n return out;\n}\n/**\n * Translate a mat3 by the given vector\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to translate\n * @param {ReadonlyVec2} v vector to translate by\n * @returns {mat3} out\n */\n\nfunction translate(out, a, v) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a10 = a[3],\n a11 = a[4],\n a12 = a[5],\n a20 = a[6],\n a21 = a[7],\n a22 = a[8],\n x = v[0],\n y = v[1];\n out[0] = a00;\n out[1] = a01;\n out[2] = a02;\n out[3] = a10;\n out[4] = a11;\n out[5] = a12;\n out[6] = x * a00 + y * a10 + a20;\n out[7] = x * a01 + y * a11 + a21;\n out[8] = x * a02 + y * a12 + a22;\n return out;\n}\n/**\n * Rotates a mat3 by the given angle\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat3} out\n */\n\nfunction rotate(out, a, rad) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a10 = a[3],\n a11 = a[4],\n a12 = a[5],\n a20 = a[6],\n a21 = a[7],\n a22 = a[8],\n s = Math.sin(rad),\n c = Math.cos(rad);\n out[0] = c * a00 + s * a10;\n out[1] = c * a01 + s * a11;\n out[2] = c * a02 + s * a12;\n out[3] = c * a10 - s * a00;\n out[4] = c * a11 - s * a01;\n out[5] = c * a12 - s * a02;\n out[6] = a20;\n out[7] = a21;\n out[8] = a22;\n return out;\n}\n/**\n * Scales the mat3 by the dimensions in the given vec2\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to rotate\n * @param {ReadonlyVec2} v the vec2 to scale the matrix by\n * @returns {mat3} out\n **/\n\nfunction mat3_scale(out, a, v) {\n var x = v[0],\n y = v[1];\n out[0] = x * a[0];\n out[1] = x * a[1];\n out[2] = x * a[2];\n out[3] = y * a[3];\n out[4] = y * a[4];\n out[5] = y * a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n return out;\n}\n/**\n * Creates a matrix from a vector translation\n * This is equivalent to (but much faster than):\n *\n * mat3.identity(dest);\n * mat3.translate(dest, dest, vec);\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyVec2} v Translation vector\n * @returns {mat3} out\n */\n\nfunction fromTranslation(out, v) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 1;\n out[5] = 0;\n out[6] = v[0];\n out[7] = v[1];\n out[8] = 1;\n return out;\n}\n/**\n * Creates a matrix from a given angle\n * This is equivalent to (but much faster than):\n *\n * mat3.identity(dest);\n * mat3.rotate(dest, dest, rad);\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat3} out\n */\n\nfunction fromRotation(out, rad) {\n var s = Math.sin(rad),\n c = Math.cos(rad);\n out[0] = c;\n out[1] = s;\n out[2] = 0;\n out[3] = -s;\n out[4] = c;\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 1;\n return out;\n}\n/**\n * Creates a matrix from a vector scaling\n * This is equivalent to (but much faster than):\n *\n * mat3.identity(dest);\n * mat3.scale(dest, dest, vec);\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyVec2} v Scaling vector\n * @returns {mat3} out\n */\n\nfunction fromScaling(out, v) {\n out[0] = v[0];\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = v[1];\n out[5] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 1;\n return out;\n}\n/**\n * Copies the values from a mat2d into a mat3\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat2d} a the matrix to copy\n * @returns {mat3} out\n **/\n\nfunction fromMat2d(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = 0;\n out[3] = a[2];\n out[4] = a[3];\n out[5] = 0;\n out[6] = a[4];\n out[7] = a[5];\n out[8] = 1;\n return out;\n}\n/**\n * Calculates a 3x3 matrix from the given quaternion\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyQuat} q Quaternion to create matrix from\n *\n * @returns {mat3} out\n */\n\nfunction fromQuat(out, q) {\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var yx = y * x2;\n var yy = y * y2;\n var zx = z * x2;\n var zy = z * y2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n out[0] = 1 - yy - zz;\n out[3] = yx - wz;\n out[6] = zx + wy;\n out[1] = yx + wz;\n out[4] = 1 - xx - zz;\n out[7] = zy - wx;\n out[2] = zx - wy;\n out[5] = zy + wx;\n out[8] = 1 - xx - yy;\n return out;\n}\n/**\n * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix\n *\n * @param {mat3} out mat3 receiving operation result\n * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from\n *\n * @returns {mat3} out\n */\n\nfunction normalFromMat4(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b00 = a00 * a11 - a01 * a10;\n var b01 = a00 * a12 - a02 * a10;\n var b02 = a00 * a13 - a03 * a10;\n var b03 = a01 * a12 - a02 * a11;\n var b04 = a01 * a13 - a03 * a11;\n var b05 = a02 * a13 - a03 * a12;\n var b06 = a20 * a31 - a21 * a30;\n var b07 = a20 * a32 - a22 * a30;\n var b08 = a20 * a33 - a23 * a30;\n var b09 = a21 * a32 - a22 * a31;\n var b10 = a21 * a33 - a23 * a31;\n var b11 = a22 * a33 - a23 * a32; // Calculate the determinant\n\n var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n\n det = 1.0 / det;\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n return out;\n}\n/**\n * Generates a 2D projection matrix with the given bounds\n *\n * @param {mat3} out mat3 frustum matrix will be written into\n * @param {number} width Width of your gl context\n * @param {number} height Height of gl context\n * @returns {mat3} out\n */\n\nfunction projection(out, width, height) {\n out[0] = 2 / width;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = -2 / height;\n out[5] = 0;\n out[6] = -1;\n out[7] = 1;\n out[8] = 1;\n return out;\n}\n/**\n * Returns a string representation of a mat3\n *\n * @param {ReadonlyMat3} a matrix to represent as a string\n * @returns {String} string representation of the matrix\n */\n\nfunction str(a) {\n return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")";\n}\n/**\n * Returns Frobenius norm of a mat3\n *\n * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of\n * @returns {Number} Frobenius norm\n */\n\nfunction frob(a) {\n return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);\n}\n/**\n * Adds two mat3\'s\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\n\nfunction add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n out[3] = a[3] + b[3];\n out[4] = a[4] + b[4];\n out[5] = a[5] + b[5];\n out[6] = a[6] + b[6];\n out[7] = a[7] + b[7];\n out[8] = a[8] + b[8];\n return out;\n}\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @returns {mat3} out\n */\n\nfunction subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n out[3] = a[3] - b[3];\n out[4] = a[4] - b[4];\n out[5] = a[5] - b[5];\n out[6] = a[6] - b[6];\n out[7] = a[7] - b[7];\n out[8] = a[8] - b[8];\n return out;\n}\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat3} out the receiving matrix\n * @param {ReadonlyMat3} a the matrix to scale\n * @param {Number} b amount to scale the matrix\'s elements by\n * @returns {mat3} out\n */\n\nfunction multiplyScalar(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n out[3] = a[3] * b;\n out[4] = a[4] * b;\n out[5] = a[5] * b;\n out[6] = a[6] * b;\n out[7] = a[7] * b;\n out[8] = a[8] * b;\n return out;\n}\n/**\n * Adds two mat3\'s after multiplying each element of the second operand by a scalar value.\n *\n * @param {mat3} out the receiving vector\n * @param {ReadonlyMat3} a the first operand\n * @param {ReadonlyMat3} b the second operand\n * @param {Number} scale the amount to scale b\'s elements by before adding\n * @returns {mat3} out\n */\n\nfunction multiplyScalarAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n out[3] = a[3] + b[3] * scale;\n out[4] = a[4] + b[4] * scale;\n out[5] = a[5] + b[5] * scale;\n out[6] = a[6] + b[6] * scale;\n out[7] = a[7] + b[7] * scale;\n out[8] = a[8] + b[8] * scale;\n return out;\n}\n/**\n * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyMat3} a The first matrix.\n * @param {ReadonlyMat3} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\n\nfunction exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8];\n}\n/**\n * Returns whether or not the matrices have approximately the same elements in the same position.\n *\n * @param {ReadonlyMat3} a The first matrix.\n * @param {ReadonlyMat3} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\n\nfunction equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3],\n a4 = a[4],\n a5 = a[5],\n a6 = a[6],\n a7 = a[7],\n a8 = a[8];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3],\n b4 = b[4],\n b5 = b[5],\n b6 = b[6],\n b7 = b[7],\n b8 = b[8];\n return Math.abs(a0 - b0) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a8), Math.abs(b8));\n}\n/**\n * Alias for {@link mat3.multiply}\n * @function\n */\n\nvar mul = multiply;\n/**\n * Alias for {@link mat3.subtract}\n * @function\n */\n\nvar sub = subtract;\n// CONCATENATED MODULE: ./node_modules/gl-matrix/esm/mat4.js\n\n/**\n * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied.\n * @module mat4\n */\n\n/**\n * Creates a new identity mat4\n *\n * @returns {mat4} a new 4x4 matrix\n */\n\nfunction mat4_create() {\n var out = new common["a" /* ARRAY_TYPE */](16);\n\n if (common["a" /* ARRAY_TYPE */] != Float32Array) {\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n }\n\n out[0] = 1;\n out[5] = 1;\n out[10] = 1;\n out[15] = 1;\n return out;\n}\n/**\n * Creates a new mat4 initialized with values from an existing matrix\n *\n * @param {ReadonlyMat4} a matrix to clone\n * @returns {mat4} a new 4x4 matrix\n */\n\nfunction mat4_clone(a) {\n var out = new common["a" /* ARRAY_TYPE */](16);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n out[9] = a[9];\n out[10] = a[10];\n out[11] = a[11];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n return out;\n}\n/**\n * Copy the values from one mat4 to another\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\n\nfunction mat4_copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[8] = a[8];\n out[9] = a[9];\n out[10] = a[10];\n out[11] = a[11];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n return out;\n}\n/**\n * Create a new mat4 with the given values\n *\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m03 Component in column 0, row 3 position (index 3)\n * @param {Number} m10 Component in column 1, row 0 position (index 4)\n * @param {Number} m11 Component in column 1, row 1 position (index 5)\n * @param {Number} m12 Component in column 1, row 2 position (index 6)\n * @param {Number} m13 Component in column 1, row 3 position (index 7)\n * @param {Number} m20 Component in column 2, row 0 position (index 8)\n * @param {Number} m21 Component in column 2, row 1 position (index 9)\n * @param {Number} m22 Component in column 2, row 2 position (index 10)\n * @param {Number} m23 Component in column 2, row 3 position (index 11)\n * @param {Number} m30 Component in column 3, row 0 position (index 12)\n * @param {Number} m31 Component in column 3, row 1 position (index 13)\n * @param {Number} m32 Component in column 3, row 2 position (index 14)\n * @param {Number} m33 Component in column 3, row 3 position (index 15)\n * @returns {mat4} A new mat4\n */\n\nfunction mat4_fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n var out = new common["a" /* ARRAY_TYPE */](16);\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m03;\n out[4] = m10;\n out[5] = m11;\n out[6] = m12;\n out[7] = m13;\n out[8] = m20;\n out[9] = m21;\n out[10] = m22;\n out[11] = m23;\n out[12] = m30;\n out[13] = m31;\n out[14] = m32;\n out[15] = m33;\n return out;\n}\n/**\n * Set the components of a mat4 to the given values\n *\n * @param {mat4} out the receiving matrix\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m03 Component in column 0, row 3 position (index 3)\n * @param {Number} m10 Component in column 1, row 0 position (index 4)\n * @param {Number} m11 Component in column 1, row 1 position (index 5)\n * @param {Number} m12 Component in column 1, row 2 position (index 6)\n * @param {Number} m13 Component in column 1, row 3 position (index 7)\n * @param {Number} m20 Component in column 2, row 0 position (index 8)\n * @param {Number} m21 Component in column 2, row 1 position (index 9)\n * @param {Number} m22 Component in column 2, row 2 position (index 10)\n * @param {Number} m23 Component in column 2, row 3 position (index 11)\n * @param {Number} m30 Component in column 3, row 0 position (index 12)\n * @param {Number} m31 Component in column 3, row 1 position (index 13)\n * @param {Number} m32 Component in column 3, row 2 position (index 14)\n * @param {Number} m33 Component in column 3, row 3 position (index 15)\n * @returns {mat4} out\n */\n\nfunction mat4_set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n out[0] = m00;\n out[1] = m01;\n out[2] = m02;\n out[3] = m03;\n out[4] = m10;\n out[5] = m11;\n out[6] = m12;\n out[7] = m13;\n out[8] = m20;\n out[9] = m21;\n out[10] = m22;\n out[11] = m23;\n out[12] = m30;\n out[13] = m31;\n out[14] = m32;\n out[15] = m33;\n return out;\n}\n/**\n * Set a mat4 to the identity matrix\n *\n * @param {mat4} out the receiving matrix\n * @returns {mat4} out\n */\n\nfunction mat4_identity(out) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Transpose the values of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\n\nfunction mat4_transpose(out, a) {\n // If we are transposing ourselves we can skip a few steps but have to cache some values\n if (out === a) {\n var a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a12 = a[6],\n a13 = a[7];\n var a23 = a[11];\n out[1] = a[4];\n out[2] = a[8];\n out[3] = a[12];\n out[4] = a01;\n out[6] = a[9];\n out[7] = a[13];\n out[8] = a02;\n out[9] = a12;\n out[11] = a[14];\n out[12] = a03;\n out[13] = a13;\n out[14] = a23;\n } else {\n out[0] = a[0];\n out[1] = a[4];\n out[2] = a[8];\n out[3] = a[12];\n out[4] = a[1];\n out[5] = a[5];\n out[6] = a[9];\n out[7] = a[13];\n out[8] = a[2];\n out[9] = a[6];\n out[10] = a[10];\n out[11] = a[14];\n out[12] = a[3];\n out[13] = a[7];\n out[14] = a[11];\n out[15] = a[15];\n }\n\n return out;\n}\n/**\n * Inverts a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\n\nfunction mat4_invert(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b00 = a00 * a11 - a01 * a10;\n var b01 = a00 * a12 - a02 * a10;\n var b02 = a00 * a13 - a03 * a10;\n var b03 = a01 * a12 - a02 * a11;\n var b04 = a01 * a13 - a03 * a11;\n var b05 = a02 * a13 - a03 * a12;\n var b06 = a20 * a31 - a21 * a30;\n var b07 = a20 * a32 - a22 * a30;\n var b08 = a20 * a33 - a23 * a30;\n var b09 = a21 * a32 - a22 * a31;\n var b10 = a21 * a33 - a23 * a31;\n var b11 = a22 * a33 - a23 * a32; // Calculate the determinant\n\n var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n\n det = 1.0 / det;\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n return out;\n}\n/**\n * Calculates the adjugate of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\n\nfunction mat4_adjoint(out, a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);\n out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));\n out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);\n out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));\n out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));\n out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);\n out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));\n out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);\n out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);\n out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));\n out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);\n out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));\n out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));\n out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);\n out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));\n out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);\n return out;\n}\n/**\n * Calculates the determinant of a mat4\n *\n * @param {ReadonlyMat4} a the source matrix\n * @returns {Number} determinant of a\n */\n\nfunction mat4_determinant(a) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15];\n var b00 = a00 * a11 - a01 * a10;\n var b01 = a00 * a12 - a02 * a10;\n var b02 = a00 * a13 - a03 * a10;\n var b03 = a01 * a12 - a02 * a11;\n var b04 = a01 * a13 - a03 * a11;\n var b05 = a02 * a13 - a03 * a12;\n var b06 = a20 * a31 - a21 * a30;\n var b07 = a20 * a32 - a22 * a30;\n var b08 = a20 * a33 - a23 * a30;\n var b09 = a21 * a32 - a22 * a31;\n var b10 = a21 * a33 - a23 * a31;\n var b11 = a22 * a33 - a23 * a32; // Calculate the determinant\n\n return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n}\n/**\n * Multiplies two mat4s\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\n\nfunction mat4_multiply(out, a, b) {\n var a00 = a[0],\n a01 = a[1],\n a02 = a[2],\n a03 = a[3];\n var a10 = a[4],\n a11 = a[5],\n a12 = a[6],\n a13 = a[7];\n var a20 = a[8],\n a21 = a[9],\n a22 = a[10],\n a23 = a[11];\n var a30 = a[12],\n a31 = a[13],\n a32 = a[14],\n a33 = a[15]; // Cache only the current line of the second matrix\n\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3];\n out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n b0 = b[4];\n b1 = b[5];\n b2 = b[6];\n b3 = b[7];\n out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n b0 = b[8];\n b1 = b[9];\n b2 = b[10];\n b3 = b[11];\n out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n b0 = b[12];\n b1 = b[13];\n b2 = b[14];\n b3 = b[15];\n out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n return out;\n}\n/**\n * Translate a mat4 by the given vector\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to translate\n * @param {ReadonlyVec3} v vector to translate by\n * @returns {mat4} out\n */\n\nfunction mat4_translate(out, a, v) {\n var x = v[0],\n y = v[1],\n z = v[2];\n var a00, a01, a02, a03;\n var a10, a11, a12, a13;\n var a20, a21, a22, a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0];\n a01 = a[1];\n a02 = a[2];\n a03 = a[3];\n a10 = a[4];\n a11 = a[5];\n a12 = a[6];\n a13 = a[7];\n a20 = a[8];\n a21 = a[9];\n a22 = a[10];\n a23 = a[11];\n out[0] = a00;\n out[1] = a01;\n out[2] = a02;\n out[3] = a03;\n out[4] = a10;\n out[5] = a11;\n out[6] = a12;\n out[7] = a13;\n out[8] = a20;\n out[9] = a21;\n out[10] = a22;\n out[11] = a23;\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n}\n/**\n * Scales the mat4 by the dimensions in the given vec3 not using vectorization\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to scale\n * @param {ReadonlyVec3} v the vec3 to scale the matrix by\n * @returns {mat4} out\n **/\n\nfunction mat4_scale(out, a, v) {\n var x = v[0],\n y = v[1],\n z = v[2];\n out[0] = a[0] * x;\n out[1] = a[1] * x;\n out[2] = a[2] * x;\n out[3] = a[3] * x;\n out[4] = a[4] * y;\n out[5] = a[5] * y;\n out[6] = a[6] * y;\n out[7] = a[7] * y;\n out[8] = a[8] * z;\n out[9] = a[9] * z;\n out[10] = a[10] * z;\n out[11] = a[11] * z;\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n return out;\n}\n/**\n * Rotates a mat4 by the given angle around the given axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @param {ReadonlyVec3} axis the axis to rotate around\n * @returns {mat4} out\n */\n\nfunction mat4_rotate(out, a, rad, axis) {\n var x = axis[0],\n y = axis[1],\n z = axis[2];\n var len = Math.hypot(x, y, z);\n var s, c, t;\n var a00, a01, a02, a03;\n var a10, a11, a12, a13;\n var a20, a21, a22, a23;\n var b00, b01, b02;\n var b10, b11, b12;\n var b20, b21, b22;\n\n if (len < common["b" /* EPSILON */]) {\n return null;\n }\n\n len = 1 / len;\n x *= len;\n y *= len;\n z *= len;\n s = Math.sin(rad);\n c = Math.cos(rad);\n t = 1 - c;\n a00 = a[0];\n a01 = a[1];\n a02 = a[2];\n a03 = a[3];\n a10 = a[4];\n a11 = a[5];\n a12 = a[6];\n a13 = a[7];\n a20 = a[8];\n a21 = a[9];\n a22 = a[10];\n a23 = a[11]; // Construct the elements of the rotation matrix\n\n b00 = x * x * t + c;\n b01 = y * x * t + z * s;\n b02 = z * x * t - y * s;\n b10 = x * y * t - z * s;\n b11 = y * y * t + c;\n b12 = z * y * t + x * s;\n b20 = x * z * t + y * s;\n b21 = y * z * t - x * s;\n b22 = z * z * t + c; // Perform rotation-specific matrix multiplication\n\n out[0] = a00 * b00 + a10 * b01 + a20 * b02;\n out[1] = a01 * b00 + a11 * b01 + a21 * b02;\n out[2] = a02 * b00 + a12 * b01 + a22 * b02;\n out[3] = a03 * b00 + a13 * b01 + a23 * b02;\n out[4] = a00 * b10 + a10 * b11 + a20 * b12;\n out[5] = a01 * b10 + a11 * b11 + a21 * b12;\n out[6] = a02 * b10 + a12 * b11 + a22 * b12;\n out[7] = a03 * b10 + a13 * b11 + a23 * b12;\n out[8] = a00 * b20 + a10 * b21 + a20 * b22;\n out[9] = a01 * b20 + a11 * b21 + a21 * b22;\n out[10] = a02 * b20 + a12 * b21 + a22 * b22;\n out[11] = a03 * b20 + a13 * b21 + a23 * b22;\n\n if (a !== out) {\n // If the source and destination differ, copy the unchanged last row\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n }\n\n return out;\n}\n/**\n * Rotates a matrix by the given angle around the X axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\n\nfunction rotateX(out, a, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n var a10 = a[4];\n var a11 = a[5];\n var a12 = a[6];\n var a13 = a[7];\n var a20 = a[8];\n var a21 = a[9];\n var a22 = a[10];\n var a23 = a[11];\n\n if (a !== out) {\n // If the source and destination differ, copy the unchanged rows\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n } // Perform axis-specific matrix multiplication\n\n\n out[4] = a10 * c + a20 * s;\n out[5] = a11 * c + a21 * s;\n out[6] = a12 * c + a22 * s;\n out[7] = a13 * c + a23 * s;\n out[8] = a20 * c - a10 * s;\n out[9] = a21 * c - a11 * s;\n out[10] = a22 * c - a12 * s;\n out[11] = a23 * c - a13 * s;\n return out;\n}\n/**\n * Rotates a matrix by the given angle around the Y axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\n\nfunction rotateY(out, a, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a03 = a[3];\n var a20 = a[8];\n var a21 = a[9];\n var a22 = a[10];\n var a23 = a[11];\n\n if (a !== out) {\n // If the source and destination differ, copy the unchanged rows\n out[4] = a[4];\n out[5] = a[5];\n out[6] = a[6];\n out[7] = a[7];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n } // Perform axis-specific matrix multiplication\n\n\n out[0] = a00 * c - a20 * s;\n out[1] = a01 * c - a21 * s;\n out[2] = a02 * c - a22 * s;\n out[3] = a03 * c - a23 * s;\n out[8] = a00 * s + a20 * c;\n out[9] = a01 * s + a21 * c;\n out[10] = a02 * s + a22 * c;\n out[11] = a03 * s + a23 * c;\n return out;\n}\n/**\n * Rotates a matrix by the given angle around the Z axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\n\nfunction rotateZ(out, a, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad);\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a03 = a[3];\n var a10 = a[4];\n var a11 = a[5];\n var a12 = a[6];\n var a13 = a[7];\n\n if (a !== out) {\n // If the source and destination differ, copy the unchanged last row\n out[8] = a[8];\n out[9] = a[9];\n out[10] = a[10];\n out[11] = a[11];\n out[12] = a[12];\n out[13] = a[13];\n out[14] = a[14];\n out[15] = a[15];\n } // Perform axis-specific matrix multiplication\n\n\n out[0] = a00 * c + a10 * s;\n out[1] = a01 * c + a11 * s;\n out[2] = a02 * c + a12 * s;\n out[3] = a03 * c + a13 * s;\n out[4] = a10 * c - a00 * s;\n out[5] = a11 * c - a01 * s;\n out[6] = a12 * c - a02 * s;\n out[7] = a13 * c - a03 * s;\n return out;\n}\n/**\n * Creates a matrix from a vector translation\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, dest, vec);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyVec3} v Translation vector\n * @returns {mat4} out\n */\n\nfunction mat4_fromTranslation(out, v) {\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from a vector scaling\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.scale(dest, dest, vec);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyVec3} v Scaling vector\n * @returns {mat4} out\n */\n\nfunction mat4_fromScaling(out, v) {\n out[0] = v[0];\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = v[1];\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = v[2];\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from a given angle around a given axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotate(dest, dest, rad, axis);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @param {ReadonlyVec3} axis the axis to rotate around\n * @returns {mat4} out\n */\n\nfunction mat4_fromRotation(out, rad, axis) {\n var x = axis[0],\n y = axis[1],\n z = axis[2];\n var len = Math.hypot(x, y, z);\n var s, c, t;\n\n if (len < common["b" /* EPSILON */]) {\n return null;\n }\n\n len = 1 / len;\n x *= len;\n y *= len;\n z *= len;\n s = Math.sin(rad);\n c = Math.cos(rad);\n t = 1 - c; // Perform rotation-specific matrix multiplication\n\n out[0] = x * x * t + c;\n out[1] = y * x * t + z * s;\n out[2] = z * x * t - y * s;\n out[3] = 0;\n out[4] = x * y * t - z * s;\n out[5] = y * y * t + c;\n out[6] = z * y * t + x * s;\n out[7] = 0;\n out[8] = x * z * t + y * s;\n out[9] = y * z * t - x * s;\n out[10] = z * z * t + c;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from the given angle around the X axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotateX(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\n\nfunction fromXRotation(out, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad); // Perform axis-specific matrix multiplication\n\n out[0] = 1;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = c;\n out[6] = s;\n out[7] = 0;\n out[8] = 0;\n out[9] = -s;\n out[10] = c;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from the given angle around the Y axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotateY(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\n\nfunction fromYRotation(out, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad); // Perform axis-specific matrix multiplication\n\n out[0] = c;\n out[1] = 0;\n out[2] = -s;\n out[3] = 0;\n out[4] = 0;\n out[5] = 1;\n out[6] = 0;\n out[7] = 0;\n out[8] = s;\n out[9] = 0;\n out[10] = c;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from the given angle around the Z axis\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.rotateZ(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\n\nfunction fromZRotation(out, rad) {\n var s = Math.sin(rad);\n var c = Math.cos(rad); // Perform axis-specific matrix multiplication\n\n out[0] = c;\n out[1] = s;\n out[2] = 0;\n out[3] = 0;\n out[4] = -s;\n out[5] = c;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 1;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from a quaternion rotation and vector translation\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, vec);\n * let quatMat = mat4.create();\n * quat4.toMat4(quat, quatMat);\n * mat4.multiply(dest, quatMat);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat4} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @returns {mat4} out\n */\n\nfunction fromRotationTranslation(out, q, v) {\n // Quaternion math\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var xy = x * y2;\n var xz = x * z2;\n var yy = y * y2;\n var yz = y * z2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n return out;\n}\n/**\n * Creates a new mat4 from a dual quat.\n *\n * @param {mat4} out Matrix\n * @param {ReadonlyQuat2} a Dual Quaternion\n * @returns {mat4} mat4 receiving operation result\n */\n\nfunction fromQuat2(out, a) {\n var translation = new common["a" /* ARRAY_TYPE */](3);\n var bx = -a[0],\n by = -a[1],\n bz = -a[2],\n bw = a[3],\n ax = a[4],\n ay = a[5],\n az = a[6],\n aw = a[7];\n var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense\n\n if (magnitude > 0) {\n translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;\n translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;\n translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;\n } else {\n translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;\n translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;\n translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;\n }\n\n fromRotationTranslation(out, a, translation);\n return out;\n}\n/**\n * Returns the translation vector component of a transformation\n * matrix. If a matrix is built with fromRotationTranslation,\n * the returned vector will be the same as the translation vector\n * originally supplied.\n * @param {vec3} out Vector to receive translation component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\n\nfunction getTranslation(out, mat) {\n out[0] = mat[12];\n out[1] = mat[13];\n out[2] = mat[14];\n return out;\n}\n/**\n * Returns the scaling factor component of a transformation\n * matrix. If a matrix is built with fromRotationTranslationScale\n * with a normalized Quaternion paramter, the returned vector will be\n * the same as the scaling vector\n * originally supplied.\n * @param {vec3} out Vector to receive scaling factor component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\n\nfunction getScaling(out, mat) {\n var m11 = mat[0];\n var m12 = mat[1];\n var m13 = mat[2];\n var m21 = mat[4];\n var m22 = mat[5];\n var m23 = mat[6];\n var m31 = mat[8];\n var m32 = mat[9];\n var m33 = mat[10];\n out[0] = Math.hypot(m11, m12, m13);\n out[1] = Math.hypot(m21, m22, m23);\n out[2] = Math.hypot(m31, m32, m33);\n return out;\n}\n/**\n * Returns a quaternion representing the rotational component\n * of a transformation matrix. If a matrix is built with\n * fromRotationTranslation, the returned quaternion will be the\n * same as the quaternion originally supplied.\n * @param {quat} out Quaternion to receive the rotation component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {quat} out\n */\n\nfunction getRotation(out, mat) {\n var scaling = new common["a" /* ARRAY_TYPE */](3);\n getScaling(scaling, mat);\n var is1 = 1 / scaling[0];\n var is2 = 1 / scaling[1];\n var is3 = 1 / scaling[2];\n var sm11 = mat[0] * is1;\n var sm12 = mat[1] * is2;\n var sm13 = mat[2] * is3;\n var sm21 = mat[4] * is1;\n var sm22 = mat[5] * is2;\n var sm23 = mat[6] * is3;\n var sm31 = mat[8] * is1;\n var sm32 = mat[9] * is2;\n var sm33 = mat[10] * is3;\n var trace = sm11 + sm22 + sm33;\n var S = 0;\n\n if (trace > 0) {\n S = Math.sqrt(trace + 1.0) * 2;\n out[3] = 0.25 * S;\n out[0] = (sm23 - sm32) / S;\n out[1] = (sm31 - sm13) / S;\n out[2] = (sm12 - sm21) / S;\n } else if (sm11 > sm22 && sm11 > sm33) {\n S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;\n out[3] = (sm23 - sm32) / S;\n out[0] = 0.25 * S;\n out[1] = (sm12 + sm21) / S;\n out[2] = (sm31 + sm13) / S;\n } else if (sm22 > sm33) {\n S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;\n out[3] = (sm31 - sm13) / S;\n out[0] = (sm12 + sm21) / S;\n out[1] = 0.25 * S;\n out[2] = (sm23 + sm32) / S;\n } else {\n S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;\n out[3] = (sm12 - sm21) / S;\n out[0] = (sm31 + sm13) / S;\n out[1] = (sm23 + sm32) / S;\n out[2] = 0.25 * S;\n }\n\n return out;\n}\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, vec);\n * let quatMat = mat4.create();\n * quat4.toMat4(quat, quatMat);\n * mat4.multiply(dest, quatMat);\n * mat4.scale(dest, scale)\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat4} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @param {ReadonlyVec3} s Scaling vector\n * @returns {mat4} out\n */\n\nfunction fromRotationTranslationScale(out, q, v, s) {\n // Quaternion math\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var xy = x * y2;\n var xz = x * z2;\n var yy = y * y2;\n var yz = y * z2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n var sx = s[0];\n var sy = s[1];\n var sz = s[2];\n out[0] = (1 - (yy + zz)) * sx;\n out[1] = (xy + wz) * sx;\n out[2] = (xz - wy) * sx;\n out[3] = 0;\n out[4] = (xy - wz) * sy;\n out[5] = (1 - (xx + zz)) * sy;\n out[6] = (yz + wx) * sy;\n out[7] = 0;\n out[8] = (xz + wy) * sz;\n out[9] = (yz - wx) * sz;\n out[10] = (1 - (xx + yy)) * sz;\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n return out;\n}\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin\n * This is equivalent to (but much faster than):\n *\n * mat4.identity(dest);\n * mat4.translate(dest, vec);\n * mat4.translate(dest, origin);\n * let quatMat = mat4.create();\n * quat4.toMat4(quat, quatMat);\n * mat4.multiply(dest, quatMat);\n * mat4.scale(dest, scale)\n * mat4.translate(dest, negativeOrigin);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat4} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @param {ReadonlyVec3} s Scaling vector\n * @param {ReadonlyVec3} o The origin vector around which to scale and rotate\n * @returns {mat4} out\n */\n\nfunction fromRotationTranslationScaleOrigin(out, q, v, s, o) {\n // Quaternion math\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var xy = x * y2;\n var xz = x * z2;\n var yy = y * y2;\n var yz = y * z2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n var sx = s[0];\n var sy = s[1];\n var sz = s[2];\n var ox = o[0];\n var oy = o[1];\n var oz = o[2];\n var out0 = (1 - (yy + zz)) * sx;\n var out1 = (xy + wz) * sx;\n var out2 = (xz - wy) * sx;\n var out4 = (xy - wz) * sy;\n var out5 = (1 - (xx + zz)) * sy;\n var out6 = (yz + wx) * sy;\n var out8 = (xz + wy) * sz;\n var out9 = (yz - wx) * sz;\n var out10 = (1 - (xx + yy)) * sz;\n out[0] = out0;\n out[1] = out1;\n out[2] = out2;\n out[3] = 0;\n out[4] = out4;\n out[5] = out5;\n out[6] = out6;\n out[7] = 0;\n out[8] = out8;\n out[9] = out9;\n out[10] = out10;\n out[11] = 0;\n out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);\n out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);\n out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);\n out[15] = 1;\n return out;\n}\n/**\n * Calculates a 4x4 matrix from the given quaternion\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyQuat} q Quaternion to create matrix from\n *\n * @returns {mat4} out\n */\n\nfunction mat4_fromQuat(out, q) {\n var x = q[0],\n y = q[1],\n z = q[2],\n w = q[3];\n var x2 = x + x;\n var y2 = y + y;\n var z2 = z + z;\n var xx = x * x2;\n var yx = y * x2;\n var yy = y * y2;\n var zx = z * x2;\n var zy = z * y2;\n var zz = z * z2;\n var wx = w * x2;\n var wy = w * y2;\n var wz = w * z2;\n out[0] = 1 - yy - zz;\n out[1] = yx + wz;\n out[2] = zx - wy;\n out[3] = 0;\n out[4] = yx - wz;\n out[5] = 1 - xx - zz;\n out[6] = zy + wx;\n out[7] = 0;\n out[8] = zx + wy;\n out[9] = zy - wx;\n out[10] = 1 - xx - yy;\n out[11] = 0;\n out[12] = 0;\n out[13] = 0;\n out[14] = 0;\n out[15] = 1;\n return out;\n}\n/**\n * Generates a frustum matrix with the given bounds\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {Number} left Left bound of the frustum\n * @param {Number} right Right bound of the frustum\n * @param {Number} bottom Bottom bound of the frustum\n * @param {Number} top Top bound of the frustum\n * @param {Number} near Near bound of the frustum\n * @param {Number} far Far bound of the frustum\n * @returns {mat4} out\n */\n\nfunction frustum(out, left, right, bottom, top, near, far) {\n var rl = 1 / (right - left);\n var tb = 1 / (top - bottom);\n var nf = 1 / (near - far);\n out[0] = near * 2 * rl;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = near * 2 * tb;\n out[6] = 0;\n out[7] = 0;\n out[8] = (right + left) * rl;\n out[9] = (top + bottom) * tb;\n out[10] = (far + near) * nf;\n out[11] = -1;\n out[12] = 0;\n out[13] = 0;\n out[14] = far * near * 2 * nf;\n out[15] = 0;\n return out;\n}\n/**\n * Generates a perspective projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],\n * which matches WebGL/OpenGL\'s clip volume.\n * Passing null/undefined/no value for far will generate infinite projection matrix.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum, can be null or Infinity\n * @returns {mat4} out\n */\n\nfunction perspectiveNO(out, fovy, aspect, near, far) {\n var f = 1.0 / Math.tan(fovy / 2),\n nf;\n out[0] = f / aspect;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = f;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[11] = -1;\n out[12] = 0;\n out[13] = 0;\n out[15] = 0;\n\n if (far != null && far !== Infinity) {\n nf = 1 / (near - far);\n out[10] = (far + near) * nf;\n out[14] = 2 * far * near * nf;\n } else {\n out[10] = -1;\n out[14] = -2 * near;\n }\n\n return out;\n}\n/**\n * Alias for {@link mat4.perspectiveNO}\n * @function\n */\n\nvar perspective = perspectiveNO;\n/**\n * Generates a perspective projection matrix suitable for WebGPU with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],\n * which matches WebGPU/Vulkan/DirectX/Metal\'s clip volume.\n * Passing null/undefined/no value for far will generate infinite projection matrix.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum, can be null or Infinity\n * @returns {mat4} out\n */\n\nfunction perspectiveZO(out, fovy, aspect, near, far) {\n var f = 1.0 / Math.tan(fovy / 2),\n nf;\n out[0] = f / aspect;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = f;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[11] = -1;\n out[12] = 0;\n out[13] = 0;\n out[15] = 0;\n\n if (far != null && far !== Infinity) {\n nf = 1 / (near - far);\n out[10] = far * nf;\n out[14] = far * near * nf;\n } else {\n out[10] = -1;\n out[14] = -near;\n }\n\n return out;\n}\n/**\n * Generates a perspective projection matrix with the given field of view.\n * This is primarily useful for generating projection matrices to be used\n * with the still experiemental WebVR API.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\n\nfunction perspectiveFromFieldOfView(out, fov, near, far) {\n var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);\n var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);\n var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);\n var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);\n var xScale = 2.0 / (leftTan + rightTan);\n var yScale = 2.0 / (upTan + downTan);\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = (upTan - downTan) * yScale * 0.5;\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = far * near / (near - far);\n out[15] = 0.0;\n return out;\n}\n/**\n * Generates a orthogonal projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],\n * which matches WebGL/OpenGL\'s clip volume.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\n\nfunction orthoNO(out, left, right, bottom, top, near, far) {\n var lr = 1 / (left - right);\n var bt = 1 / (bottom - top);\n var nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n}\n/**\n * Alias for {@link mat4.orthoNO}\n * @function\n */\n\nvar ortho = orthoNO;\n/**\n * Generates a orthogonal projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],\n * which matches WebGPU/Vulkan/DirectX/Metal\'s clip volume.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\n\nfunction orthoZO(out, left, right, bottom, top, near, far) {\n var lr = 1 / (left - right);\n var bt = 1 / (bottom - top);\n var nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = near * nf;\n out[15] = 1;\n return out;\n}\n/**\n * Generates a look-at matrix with the given eye position, focal point, and up axis.\n * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {ReadonlyVec3} eye Position of the viewer\n * @param {ReadonlyVec3} center Point the viewer is looking at\n * @param {ReadonlyVec3} up vec3 pointing up\n * @returns {mat4} out\n */\n\nfunction lookAt(out, eye, center, up) {\n var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;\n var eyex = eye[0];\n var eyey = eye[1];\n var eyez = eye[2];\n var upx = up[0];\n var upy = up[1];\n var upz = up[2];\n var centerx = center[0];\n var centery = center[1];\n var centerz = center[2];\n\n if (Math.abs(eyex - centerx) < common["b" /* EPSILON */] && Math.abs(eyey - centery) < common["b" /* EPSILON */] && Math.abs(eyez - centerz) < common["b" /* EPSILON */]) {\n return mat4_identity(out);\n }\n\n z0 = eyex - centerx;\n z1 = eyey - centery;\n z2 = eyez - centerz;\n len = 1 / Math.hypot(z0, z1, z2);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n x0 = upy * z2 - upz * z1;\n x1 = upz * z0 - upx * z2;\n x2 = upx * z1 - upy * z0;\n len = Math.hypot(x0, x1, x2);\n\n if (!len) {\n x0 = 0;\n x1 = 0;\n x2 = 0;\n } else {\n len = 1 / len;\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n\n y0 = z1 * x2 - z2 * x1;\n y1 = z2 * x0 - z0 * x2;\n y2 = z0 * x1 - z1 * x0;\n len = Math.hypot(y0, y1, y2);\n\n if (!len) {\n y0 = 0;\n y1 = 0;\n y2 = 0;\n } else {\n len = 1 / len;\n y0 *= len;\n y1 *= len;\n y2 *= len;\n }\n\n out[0] = x0;\n out[1] = y0;\n out[2] = z0;\n out[3] = 0;\n out[4] = x1;\n out[5] = y1;\n out[6] = z1;\n out[7] = 0;\n out[8] = x2;\n out[9] = y2;\n out[10] = z2;\n out[11] = 0;\n out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);\n out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);\n out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);\n out[15] = 1;\n return out;\n}\n/**\n * Generates a matrix that makes something look at something else.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {ReadonlyVec3} eye Position of the viewer\n * @param {ReadonlyVec3} center Point the viewer is looking at\n * @param {ReadonlyVec3} up vec3 pointing up\n * @returns {mat4} out\n */\n\nfunction targetTo(out, eye, target, up) {\n var eyex = eye[0],\n eyey = eye[1],\n eyez = eye[2],\n upx = up[0],\n upy = up[1],\n upz = up[2];\n var z0 = eyex - target[0],\n z1 = eyey - target[1],\n z2 = eyez - target[2];\n var len = z0 * z0 + z1 * z1 + z2 * z2;\n\n if (len > 0) {\n len = 1 / Math.sqrt(len);\n z0 *= len;\n z1 *= len;\n z2 *= len;\n }\n\n var x0 = upy * z2 - upz * z1,\n x1 = upz * z0 - upx * z2,\n x2 = upx * z1 - upy * z0;\n len = x0 * x0 + x1 * x1 + x2 * x2;\n\n if (len > 0) {\n len = 1 / Math.sqrt(len);\n x0 *= len;\n x1 *= len;\n x2 *= len;\n }\n\n out[0] = x0;\n out[1] = x1;\n out[2] = x2;\n out[3] = 0;\n out[4] = z1 * x2 - z2 * x1;\n out[5] = z2 * x0 - z0 * x2;\n out[6] = z0 * x1 - z1 * x0;\n out[7] = 0;\n out[8] = z0;\n out[9] = z1;\n out[10] = z2;\n out[11] = 0;\n out[12] = eyex;\n out[13] = eyey;\n out[14] = eyez;\n out[15] = 1;\n return out;\n}\n/**\n * Returns a string representation of a mat4\n *\n * @param {ReadonlyMat4} a matrix to represent as a string\n * @returns {String} string representation of the matrix\n */\n\nfunction mat4_str(a) {\n return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")";\n}\n/**\n * Returns Frobenius norm of a mat4\n *\n * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of\n * @returns {Number} Frobenius norm\n */\n\nfunction mat4_frob(a) {\n return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);\n}\n/**\n * Adds two mat4\'s\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\n\nfunction mat4_add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n out[3] = a[3] + b[3];\n out[4] = a[4] + b[4];\n out[5] = a[5] + b[5];\n out[6] = a[6] + b[6];\n out[7] = a[7] + b[7];\n out[8] = a[8] + b[8];\n out[9] = a[9] + b[9];\n out[10] = a[10] + b[10];\n out[11] = a[11] + b[11];\n out[12] = a[12] + b[12];\n out[13] = a[13] + b[13];\n out[14] = a[14] + b[14];\n out[15] = a[15] + b[15];\n return out;\n}\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\n\nfunction mat4_subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n out[3] = a[3] - b[3];\n out[4] = a[4] - b[4];\n out[5] = a[5] - b[5];\n out[6] = a[6] - b[6];\n out[7] = a[7] - b[7];\n out[8] = a[8] - b[8];\n out[9] = a[9] - b[9];\n out[10] = a[10] - b[10];\n out[11] = a[11] - b[11];\n out[12] = a[12] - b[12];\n out[13] = a[13] - b[13];\n out[14] = a[14] - b[14];\n out[15] = a[15] - b[15];\n return out;\n}\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to scale\n * @param {Number} b amount to scale the matrix\'s elements by\n * @returns {mat4} out\n */\n\nfunction mat4_multiplyScalar(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n out[3] = a[3] * b;\n out[4] = a[4] * b;\n out[5] = a[5] * b;\n out[6] = a[6] * b;\n out[7] = a[7] * b;\n out[8] = a[8] * b;\n out[9] = a[9] * b;\n out[10] = a[10] * b;\n out[11] = a[11] * b;\n out[12] = a[12] * b;\n out[13] = a[13] * b;\n out[14] = a[14] * b;\n out[15] = a[15] * b;\n return out;\n}\n/**\n * Adds two mat4\'s after multiplying each element of the second operand by a scalar value.\n *\n * @param {mat4} out the receiving vector\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @param {Number} scale the amount to scale b\'s elements by before adding\n * @returns {mat4} out\n */\n\nfunction mat4_multiplyScalarAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n out[3] = a[3] + b[3] * scale;\n out[4] = a[4] + b[4] * scale;\n out[5] = a[5] + b[5] * scale;\n out[6] = a[6] + b[6] * scale;\n out[7] = a[7] + b[7] * scale;\n out[8] = a[8] + b[8] * scale;\n out[9] = a[9] + b[9] * scale;\n out[10] = a[10] + b[10] * scale;\n out[11] = a[11] + b[11] * scale;\n out[12] = a[12] + b[12] * scale;\n out[13] = a[13] + b[13] * scale;\n out[14] = a[14] + b[14] * scale;\n out[15] = a[15] + b[15] * scale;\n return out;\n}\n/**\n * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyMat4} a The first matrix.\n * @param {ReadonlyMat4} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\n\nfunction mat4_exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];\n}\n/**\n * Returns whether or not the matrices have approximately the same elements in the same position.\n *\n * @param {ReadonlyMat4} a The first matrix.\n * @param {ReadonlyMat4} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\n\nfunction mat4_equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3];\n var a4 = a[4],\n a5 = a[5],\n a6 = a[6],\n a7 = a[7];\n var a8 = a[8],\n a9 = a[9],\n a10 = a[10],\n a11 = a[11];\n var a12 = a[12],\n a13 = a[13],\n a14 = a[14],\n a15 = a[15];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3];\n var b4 = b[4],\n b5 = b[5],\n b6 = b[6],\n b7 = b[7];\n var b8 = b[8],\n b9 = b[9],\n b10 = b[10],\n b11 = b[11];\n var b12 = b[12],\n b13 = b[13],\n b14 = b[14],\n b15 = b[15];\n return Math.abs(a0 - b0) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a15), Math.abs(b15));\n}\n/**\n * Alias for {@link mat4.multiply}\n * @function\n */\n\nvar mat4_mul = mat4_multiply;\n/**\n * Alias for {@link mat4.subtract}\n * @function\n */\n\nvar mat4_sub = mat4_subtract;\n// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/vec3.js\nvar vec3 = __webpack_require__(39);\n\n// CONCATENATED MODULE: ./node_modules/gl-matrix/esm/vec4.js\n\n/**\n * 4 Dimensional Vector\n * @module vec4\n */\n\n/**\n * Creates a new, empty vec4\n *\n * @returns {vec4} a new 4D vector\n */\n\nfunction vec4_create() {\n var out = new common["a" /* ARRAY_TYPE */](4);\n\n if (common["a" /* ARRAY_TYPE */] != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n }\n\n return out;\n}\n/**\n * Creates a new vec4 initialized with values from an existing vector\n *\n * @param {ReadonlyVec4} a vector to clone\n * @returns {vec4} a new 4D vector\n */\n\nfunction vec4_clone(a) {\n var out = new common["a" /* ARRAY_TYPE */](4);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n return out;\n}\n/**\n * Creates a new vec4 initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {vec4} a new 4D vector\n */\n\nfunction vec4_fromValues(x, y, z, w) {\n var out = new common["a" /* ARRAY_TYPE */](4);\n out[0] = x;\n out[1] = y;\n out[2] = z;\n out[3] = w;\n return out;\n}\n/**\n * Copy the values from one vec4 to another\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the source vector\n * @returns {vec4} out\n */\n\nfunction vec4_copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n out[3] = a[3];\n return out;\n}\n/**\n * Set the components of a vec4 to the given values\n *\n * @param {vec4} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {vec4} out\n */\n\nfunction vec4_set(out, x, y, z, w) {\n out[0] = x;\n out[1] = y;\n out[2] = z;\n out[3] = w;\n return out;\n}\n/**\n * Adds two vec4\'s\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\n\nfunction vec4_add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n out[3] = a[3] + b[3];\n return out;\n}\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\n\nfunction vec4_subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n out[3] = a[3] - b[3];\n return out;\n}\n/**\n * Multiplies two vec4\'s\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\n\nfunction vec4_multiply(out, a, b) {\n out[0] = a[0] * b[0];\n out[1] = a[1] * b[1];\n out[2] = a[2] * b[2];\n out[3] = a[3] * b[3];\n return out;\n}\n/**\n * Divides two vec4\'s\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\n\nfunction divide(out, a, b) {\n out[0] = a[0] / b[0];\n out[1] = a[1] / b[1];\n out[2] = a[2] / b[2];\n out[3] = a[3] / b[3];\n return out;\n}\n/**\n * Math.ceil the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to ceil\n * @returns {vec4} out\n */\n\nfunction ceil(out, a) {\n out[0] = Math.ceil(a[0]);\n out[1] = Math.ceil(a[1]);\n out[2] = Math.ceil(a[2]);\n out[3] = Math.ceil(a[3]);\n return out;\n}\n/**\n * Math.floor the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to floor\n * @returns {vec4} out\n */\n\nfunction floor(out, a) {\n out[0] = Math.floor(a[0]);\n out[1] = Math.floor(a[1]);\n out[2] = Math.floor(a[2]);\n out[3] = Math.floor(a[3]);\n return out;\n}\n/**\n * Returns the minimum of two vec4\'s\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\n\nfunction min(out, a, b) {\n out[0] = Math.min(a[0], b[0]);\n out[1] = Math.min(a[1], b[1]);\n out[2] = Math.min(a[2], b[2]);\n out[3] = Math.min(a[3], b[3]);\n return out;\n}\n/**\n * Returns the maximum of two vec4\'s\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {vec4} out\n */\n\nfunction max(out, a, b) {\n out[0] = Math.max(a[0], b[0]);\n out[1] = Math.max(a[1], b[1]);\n out[2] = Math.max(a[2], b[2]);\n out[3] = Math.max(a[3], b[3]);\n return out;\n}\n/**\n * Math.round the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to round\n * @returns {vec4} out\n */\n\nfunction round(out, a) {\n out[0] = Math.round(a[0]);\n out[1] = Math.round(a[1]);\n out[2] = Math.round(a[2]);\n out[3] = Math.round(a[3]);\n return out;\n}\n/**\n * Scales a vec4 by a scalar number\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec4} out\n */\n\nfunction vec4_scale(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n out[3] = a[3] * b;\n return out;\n}\n/**\n * Adds two vec4\'s after scaling the second operand by a scalar value\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @param {Number} scale the amount to scale b by before adding\n * @returns {vec4} out\n */\n\nfunction scaleAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n out[3] = a[3] + b[3] * scale;\n return out;\n}\n/**\n * Calculates the euclidian distance between two vec4\'s\n *\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {Number} distance between a and b\n */\n\nfunction distance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n var w = b[3] - a[3];\n return Math.hypot(x, y, z, w);\n}\n/**\n * Calculates the squared euclidian distance between two vec4\'s\n *\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {Number} squared distance between a and b\n */\n\nfunction squaredDistance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n var w = b[3] - a[3];\n return x * x + y * y + z * z + w * w;\n}\n/**\n * Calculates the length of a vec4\n *\n * @param {ReadonlyVec4} a vector to calculate length of\n * @returns {Number} length of a\n */\n\nfunction vec4_length(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var w = a[3];\n return Math.hypot(x, y, z, w);\n}\n/**\n * Calculates the squared length of a vec4\n *\n * @param {ReadonlyVec4} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\n\nfunction squaredLength(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var w = a[3];\n return x * x + y * y + z * z + w * w;\n}\n/**\n * Negates the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to negate\n * @returns {vec4} out\n */\n\nfunction negate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n out[2] = -a[2];\n out[3] = -a[3];\n return out;\n}\n/**\n * Returns the inverse of the components of a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to invert\n * @returns {vec4} out\n */\n\nfunction inverse(out, a) {\n out[0] = 1.0 / a[0];\n out[1] = 1.0 / a[1];\n out[2] = 1.0 / a[2];\n out[3] = 1.0 / a[3];\n return out;\n}\n/**\n * Normalize a vec4\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a vector to normalize\n * @returns {vec4} out\n */\n\nfunction normalize(out, a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var w = a[3];\n var len = x * x + y * y + z * z + w * w;\n\n if (len > 0) {\n len = 1 / Math.sqrt(len);\n }\n\n out[0] = x * len;\n out[1] = y * len;\n out[2] = z * len;\n out[3] = w * len;\n return out;\n}\n/**\n * Calculates the dot product of two vec4\'s\n *\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @returns {Number} dot product of a and b\n */\n\nfunction vec4_dot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];\n}\n/**\n * Returns the cross-product of three vectors in a 4-dimensional space\n *\n * @param {ReadonlyVec4} result the receiving vector\n * @param {ReadonlyVec4} U the first vector\n * @param {ReadonlyVec4} V the second vector\n * @param {ReadonlyVec4} W the third vector\n * @returns {vec4} result\n */\n\nfunction cross(out, u, v, w) {\n var A = v[0] * w[1] - v[1] * w[0],\n B = v[0] * w[2] - v[2] * w[0],\n C = v[0] * w[3] - v[3] * w[0],\n D = v[1] * w[2] - v[2] * w[1],\n E = v[1] * w[3] - v[3] * w[1],\n F = v[2] * w[3] - v[3] * w[2];\n var G = u[0];\n var H = u[1];\n var I = u[2];\n var J = u[3];\n out[0] = H * F - I * E + J * D;\n out[1] = -(G * F) + I * C - J * B;\n out[2] = G * E - H * C + J * A;\n out[3] = -(G * D) + H * B - I * A;\n return out;\n}\n/**\n * Performs a linear interpolation between two vec4\'s\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the first operand\n * @param {ReadonlyVec4} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec4} out\n */\n\nfunction lerp(out, a, b, t) {\n var ax = a[0];\n var ay = a[1];\n var az = a[2];\n var aw = a[3];\n out[0] = ax + t * (b[0] - ax);\n out[1] = ay + t * (b[1] - ay);\n out[2] = az + t * (b[2] - az);\n out[3] = aw + t * (b[3] - aw);\n return out;\n}\n/**\n * Generates a random vector with the given scale\n *\n * @param {vec4} out the receiving vector\n * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned\n * @returns {vec4} out\n */\n\nfunction random(out, scale) {\n scale = scale || 1.0; // Marsaglia, George. Choosing a Point from the Surface of a\n // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646.\n // http://projecteuclid.org/euclid.aoms/1177692644;\n\n var v1, v2, v3, v4;\n var s1, s2;\n\n do {\n v1 = common["c" /* RANDOM */]() * 2 - 1;\n v2 = common["c" /* RANDOM */]() * 2 - 1;\n s1 = v1 * v1 + v2 * v2;\n } while (s1 >= 1);\n\n do {\n v3 = common["c" /* RANDOM */]() * 2 - 1;\n v4 = common["c" /* RANDOM */]() * 2 - 1;\n s2 = v3 * v3 + v4 * v4;\n } while (s2 >= 1);\n\n var d = Math.sqrt((1 - s1) / s2);\n out[0] = scale * v1;\n out[1] = scale * v2;\n out[2] = scale * v3 * d;\n out[3] = scale * v4 * d;\n return out;\n}\n/**\n * Transforms the vec4 with a mat4.\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec4} out\n */\n\nfunction transformMat4(out, a, m) {\n var x = a[0],\n y = a[1],\n z = a[2],\n w = a[3];\n out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;\n out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;\n out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;\n out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;\n return out;\n}\n/**\n * Transforms the vec4 with a quat\n *\n * @param {vec4} out the receiving vector\n * @param {ReadonlyVec4} a the vector to transform\n * @param {ReadonlyQuat} q quaternion to transform with\n * @returns {vec4} out\n */\n\nfunction transformQuat(out, a, q) {\n var x = a[0],\n y = a[1],\n z = a[2];\n var qx = q[0],\n qy = q[1],\n qz = q[2],\n qw = q[3]; // calculate quat * vec\n\n var ix = qw * x + qy * z - qz * y;\n var iy = qw * y + qz * x - qx * z;\n var iz = qw * z + qx * y - qy * x;\n var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat\n\n out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;\n out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;\n out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;\n out[3] = a[3];\n return out;\n}\n/**\n * Set the components of a vec4 to zero\n *\n * @param {vec4} out the receiving vector\n * @returns {vec4} out\n */\n\nfunction zero(out) {\n out[0] = 0.0;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n return out;\n}\n/**\n * Returns a string representation of a vector\n *\n * @param {ReadonlyVec4} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\n\nfunction vec4_str(a) {\n return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";\n}\n/**\n * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyVec4} a The first vector.\n * @param {ReadonlyVec4} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\n\nfunction vec4_exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];\n}\n/**\n * Returns whether or not the vectors have approximately the same elements in the same position.\n *\n * @param {ReadonlyVec4} a The first vector.\n * @param {ReadonlyVec4} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\n\nfunction vec4_equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2],\n b3 = b[3];\n return Math.abs(a0 - b0) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= common["b" /* EPSILON */] * Math.max(1.0, Math.abs(a3), Math.abs(b3));\n}\n/**\n * Alias for {@link vec4.subtract}\n * @function\n */\n\nvar vec4_sub = vec4_subtract;\n/**\n * Alias for {@link vec4.multiply}\n * @function\n */\n\nvar vec4_mul = vec4_multiply;\n/**\n * Alias for {@link vec4.divide}\n * @function\n */\n\nvar div = divide;\n/**\n * Alias for {@link vec4.distance}\n * @function\n */\n\nvar dist = distance;\n/**\n * Alias for {@link vec4.squaredDistance}\n * @function\n */\n\nvar sqrDist = squaredDistance;\n/**\n * Alias for {@link vec4.length}\n * @function\n */\n\nvar vec4_len = vec4_length;\n/**\n * Alias for {@link vec4.squaredLength}\n * @function\n */\n\nvar sqrLen = squaredLength;\n/**\n * Perform some operation over an array of vec4s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\n\nvar forEach = function () {\n var vec = vec4_create();\n return function (a, stride, offset, count, fn, arg) {\n var i, l;\n\n if (!stride) {\n stride = 4;\n }\n\n if (!offset) {\n offset = 0;\n }\n\n if (count) {\n l = Math.min(count * stride + offset, a.length);\n } else {\n l = a.length;\n }\n\n for (i = offset; i < l; i += stride) {\n vec[0] = a[i];\n vec[1] = a[i + 1];\n vec[2] = a[i + 2];\n vec[3] = a[i + 3];\n fn(vec, vec, arg);\n a[i] = vec[0];\n a[i + 1] = vec[1];\n a[i + 2] = vec[2];\n a[i + 3] = vec[3];\n }\n\n return a;\n };\n}();\n// CONCATENATED MODULE: ./node_modules/gl-matrix/esm/quat.js\n\n\n\n\n/**\n * Quaternion\n * @module quat\n */\n\n/**\n * Creates a new identity quat\n *\n * @returns {quat} a new quaternion\n */\n\nfunction quat_create() {\n var out = new common["a" /* ARRAY_TYPE */](4);\n\n if (common["a" /* ARRAY_TYPE */] != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n }\n\n out[3] = 1;\n return out;\n}\n/**\n * Set a quat to the identity quaternion\n *\n * @param {quat} out the receiving quaternion\n * @returns {quat} out\n */\n\nfunction quat_identity(out) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n out[3] = 1;\n return out;\n}\n/**\n * Sets a quat from the given angle and rotation axis,\n * then returns it.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyVec3} axis the axis around which to rotate\n * @param {Number} rad the angle in radians\n * @returns {quat} out\n **/\n\nfunction setAxisAngle(out, axis, rad) {\n rad = rad * 0.5;\n var s = Math.sin(rad);\n out[0] = s * axis[0];\n out[1] = s * axis[1];\n out[2] = s * axis[2];\n out[3] = Math.cos(rad);\n return out;\n}\n/**\n * Gets the rotation axis and angle for a given\n * quaternion. If a quaternion is created with\n * setAxisAngle, this method will return the same\n * values as providied in the original parameter list\n * OR functionally equivalent values.\n * Example: The quaternion formed by axis [0, 0, 1] and\n * angle -90 is the same as the quaternion formed by\n * [0, 0, 1] and 270. This method favors the latter.\n * @param {vec3} out_axis Vector receiving the axis of rotation\n * @param {ReadonlyQuat} q Quaternion to be decomposed\n * @return {Number} Angle, in radians, of the rotation\n */\n\nfunction getAxisAngle(out_axis, q) {\n var rad = Math.acos(q[3]) * 2.0;\n var s = Math.sin(rad / 2.0);\n\n if (s > common["b" /* EPSILON */]) {\n out_axis[0] = q[0] / s;\n out_axis[1] = q[1] / s;\n out_axis[2] = q[2] / s;\n } else {\n // If s is zero, return any axis (no rotation - axis does not matter)\n out_axis[0] = 1;\n out_axis[1] = 0;\n out_axis[2] = 0;\n }\n\n return rad;\n}\n/**\n * Gets the angular distance between two unit quaternions\n *\n * @param {ReadonlyQuat} a Origin unit quaternion\n * @param {ReadonlyQuat} b Destination unit quaternion\n * @return {Number} Angle, in radians, between the two quaternions\n */\n\nfunction getAngle(a, b) {\n var dotproduct = quat_dot(a, b);\n return Math.acos(2 * dotproduct * dotproduct - 1);\n}\n/**\n * Multiplies two quat\'s\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @returns {quat} out\n */\n\nfunction quat_multiply(out, a, b) {\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bx = b[0],\n by = b[1],\n bz = b[2],\n bw = b[3];\n out[0] = ax * bw + aw * bx + ay * bz - az * by;\n out[1] = ay * bw + aw * by + az * bx - ax * bz;\n out[2] = az * bw + aw * bz + ax * by - ay * bx;\n out[3] = aw * bw - ax * bx - ay * by - az * bz;\n return out;\n}\n/**\n * Rotates a quaternion by the given angle about the X axis\n *\n * @param {quat} out quat receiving operation result\n * @param {ReadonlyQuat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\n\nfunction quat_rotateX(out, a, rad) {\n rad *= 0.5;\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bx = Math.sin(rad),\n bw = Math.cos(rad);\n out[0] = ax * bw + aw * bx;\n out[1] = ay * bw + az * bx;\n out[2] = az * bw - ay * bx;\n out[3] = aw * bw - ax * bx;\n return out;\n}\n/**\n * Rotates a quaternion by the given angle about the Y axis\n *\n * @param {quat} out quat receiving operation result\n * @param {ReadonlyQuat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\n\nfunction quat_rotateY(out, a, rad) {\n rad *= 0.5;\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var by = Math.sin(rad),\n bw = Math.cos(rad);\n out[0] = ax * bw - az * by;\n out[1] = ay * bw + aw * by;\n out[2] = az * bw + ax * by;\n out[3] = aw * bw - ay * by;\n return out;\n}\n/**\n * Rotates a quaternion by the given angle about the Z axis\n *\n * @param {quat} out quat receiving operation result\n * @param {ReadonlyQuat} a quat to rotate\n * @param {number} rad angle (in radians) to rotate\n * @returns {quat} out\n */\n\nfunction quat_rotateZ(out, a, rad) {\n rad *= 0.5;\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bz = Math.sin(rad),\n bw = Math.cos(rad);\n out[0] = ax * bw + ay * bz;\n out[1] = ay * bw - ax * bz;\n out[2] = az * bw + aw * bz;\n out[3] = aw * bw - az * bz;\n return out;\n}\n/**\n * Calculates the W component of a quat from the X, Y, and Z components.\n * Assumes that quaternion is 1 unit in length.\n * Any existing W component will be ignored.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate W component of\n * @returns {quat} out\n */\n\nfunction calculateW(out, a) {\n var x = a[0],\n y = a[1],\n z = a[2];\n out[0] = x;\n out[1] = y;\n out[2] = z;\n out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));\n return out;\n}\n/**\n * Calculate the exponential of a unit quaternion.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate the exponential of\n * @returns {quat} out\n */\n\nfunction exp(out, a) {\n var x = a[0],\n y = a[1],\n z = a[2],\n w = a[3];\n var r = Math.sqrt(x * x + y * y + z * z);\n var et = Math.exp(w);\n var s = r > 0 ? et * Math.sin(r) / r : 0;\n out[0] = x * s;\n out[1] = y * s;\n out[2] = z * s;\n out[3] = et * Math.cos(r);\n return out;\n}\n/**\n * Calculate the natural logarithm of a unit quaternion.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate the exponential of\n * @returns {quat} out\n */\n\nfunction ln(out, a) {\n var x = a[0],\n y = a[1],\n z = a[2],\n w = a[3];\n var r = Math.sqrt(x * x + y * y + z * z);\n var t = r > 0 ? Math.atan2(r, w) / r : 0;\n out[0] = x * t;\n out[1] = y * t;\n out[2] = z * t;\n out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w);\n return out;\n}\n/**\n * Calculate the scalar power of a unit quaternion.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate the exponential of\n * @param {Number} b amount to scale the quaternion by\n * @returns {quat} out\n */\n\nfunction pow(out, a, b) {\n ln(out, a);\n quat_scale(out, out, b);\n exp(out, out);\n return out;\n}\n/**\n * Performs a spherical linear interpolation between two quat\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {quat} out\n */\n\nfunction slerp(out, a, b, t) {\n // benchmarks:\n // http://jsperf.com/quaternion-slerp-implementations\n var ax = a[0],\n ay = a[1],\n az = a[2],\n aw = a[3];\n var bx = b[0],\n by = b[1],\n bz = b[2],\n bw = b[3];\n var omega, cosom, sinom, scale0, scale1; // calc cosine\n\n cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary)\n\n if (cosom < 0.0) {\n cosom = -cosom;\n bx = -bx;\n by = -by;\n bz = -bz;\n bw = -bw;\n } // calculate coefficients\n\n\n if (1.0 - cosom > common["b" /* EPSILON */]) {\n // standard case (slerp)\n omega = Math.acos(cosom);\n sinom = Math.sin(omega);\n scale0 = Math.sin((1.0 - t) * omega) / sinom;\n scale1 = Math.sin(t * omega) / sinom;\n } else {\n // "from" and "to" quaternions are very close\n // ... so we can do a linear interpolation\n scale0 = 1.0 - t;\n scale1 = t;\n } // calculate final values\n\n\n out[0] = scale0 * ax + scale1 * bx;\n out[1] = scale0 * ay + scale1 * by;\n out[2] = scale0 * az + scale1 * bz;\n out[3] = scale0 * aw + scale1 * bw;\n return out;\n}\n/**\n * Generates a random unit quaternion\n *\n * @param {quat} out the receiving quaternion\n * @returns {quat} out\n */\n\nfunction quat_random(out) {\n // Implementation of http://planning.cs.uiuc.edu/node198.html\n // TODO: Calling random 3 times is probably not the fastest solution\n var u1 = common["c" /* RANDOM */]();\n var u2 = common["c" /* RANDOM */]();\n var u3 = common["c" /* RANDOM */]();\n var sqrt1MinusU1 = Math.sqrt(1 - u1);\n var sqrtU1 = Math.sqrt(u1);\n out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2);\n out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2);\n out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3);\n out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3);\n return out;\n}\n/**\n * Calculates the inverse of a quat\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate inverse of\n * @returns {quat} out\n */\n\nfunction quat_invert(out, a) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2],\n a3 = a[3];\n var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;\n var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0\n\n out[0] = -a0 * invDot;\n out[1] = -a1 * invDot;\n out[2] = -a2 * invDot;\n out[3] = a3 * invDot;\n return out;\n}\n/**\n * Calculates the conjugate of a quat\n * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quat to calculate conjugate of\n * @returns {quat} out\n */\n\nfunction conjugate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n out[2] = -a[2];\n out[3] = a[3];\n return out;\n}\n/**\n * Creates a quaternion from the given 3x3 rotation matrix.\n *\n * NOTE: The resultant quaternion is not normalized, so you should be sure\n * to renormalize the quaternion yourself where necessary.\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyMat3} m rotation matrix\n * @returns {quat} out\n * @function\n */\n\nfunction fromMat3(out, m) {\n // Algorithm in Ken Shoemake\'s article in 1987 SIGGRAPH course notes\n // article "Quaternion Calculus and Fast Animation".\n var fTrace = m[0] + m[4] + m[8];\n var fRoot;\n\n if (fTrace > 0.0) {\n // |w| > 1/2, may as well choose w > 1/2\n fRoot = Math.sqrt(fTrace + 1.0); // 2w\n\n out[3] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot; // 1/(4w)\n\n out[0] = (m[5] - m[7]) * fRoot;\n out[1] = (m[6] - m[2]) * fRoot;\n out[2] = (m[1] - m[3]) * fRoot;\n } else {\n // |w| <= 1/2\n var i = 0;\n if (m[4] > m[0]) i = 1;\n if (m[8] > m[i * 3 + i]) i = 2;\n var j = (i + 1) % 3;\n var k = (i + 2) % 3;\n fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);\n out[i] = 0.5 * fRoot;\n fRoot = 0.5 / fRoot;\n out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;\n out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;\n out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;\n }\n\n return out;\n}\n/**\n * Creates a quaternion from the given euler angle x, y, z.\n *\n * @param {quat} out the receiving quaternion\n * @param {x} Angle to rotate around X axis in degrees.\n * @param {y} Angle to rotate around Y axis in degrees.\n * @param {z} Angle to rotate around Z axis in degrees.\n * @returns {quat} out\n * @function\n */\n\nfunction fromEuler(out, x, y, z) {\n var halfToRad = 0.5 * Math.PI / 180.0;\n x *= halfToRad;\n y *= halfToRad;\n z *= halfToRad;\n var sx = Math.sin(x);\n var cx = Math.cos(x);\n var sy = Math.sin(y);\n var cy = Math.cos(y);\n var sz = Math.sin(z);\n var cz = Math.cos(z);\n out[0] = sx * cy * cz - cx * sy * sz;\n out[1] = cx * sy * cz + sx * cy * sz;\n out[2] = cx * cy * sz - sx * sy * cz;\n out[3] = cx * cy * cz + sx * sy * sz;\n return out;\n}\n/**\n * Returns a string representation of a quatenion\n *\n * @param {ReadonlyQuat} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\n\nfunction quat_str(a) {\n return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")";\n}\n/**\n * Creates a new quat initialized with values from an existing quaternion\n *\n * @param {ReadonlyQuat} a quaternion to clone\n * @returns {quat} a new quaternion\n * @function\n */\n\nvar quat_clone = vec4_clone;\n/**\n * Creates a new quat initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {quat} a new quaternion\n * @function\n */\n\nvar quat_fromValues = vec4_fromValues;\n/**\n * Copy the values from one quat to another\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the source quaternion\n * @returns {quat} out\n * @function\n */\n\nvar quat_copy = vec4_copy;\n/**\n * Set the components of a quat to the given values\n *\n * @param {quat} out the receiving quaternion\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @param {Number} w W component\n * @returns {quat} out\n * @function\n */\n\nvar quat_set = vec4_set;\n/**\n * Adds two quat\'s\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @returns {quat} out\n * @function\n */\n\nvar quat_add = vec4_add;\n/**\n * Alias for {@link quat.multiply}\n * @function\n */\n\nvar quat_mul = quat_multiply;\n/**\n * Scales a quat by a scalar number\n *\n * @param {quat} out the receiving vector\n * @param {ReadonlyQuat} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {quat} out\n * @function\n */\n\nvar quat_scale = vec4_scale;\n/**\n * Calculates the dot product of two quat\'s\n *\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @returns {Number} dot product of a and b\n * @function\n */\n\nvar quat_dot = vec4_dot;\n/**\n * Performs a linear interpolation between two quat\'s\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {quat} out\n * @function\n */\n\nvar quat_lerp = lerp;\n/**\n * Calculates the length of a quat\n *\n * @param {ReadonlyQuat} a vector to calculate length of\n * @returns {Number} length of a\n */\n\nvar quat_length = vec4_length;\n/**\n * Alias for {@link quat.length}\n * @function\n */\n\nvar quat_len = quat_length;\n/**\n * Calculates the squared length of a quat\n *\n * @param {ReadonlyQuat} a vector to calculate squared length of\n * @returns {Number} squared length of a\n * @function\n */\n\nvar quat_squaredLength = squaredLength;\n/**\n * Alias for {@link quat.squaredLength}\n * @function\n */\n\nvar quat_sqrLen = quat_squaredLength;\n/**\n * Normalize a quat\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a quaternion to normalize\n * @returns {quat} out\n * @function\n */\n\nvar quat_normalize = normalize;\n/**\n * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyQuat} a The first quaternion.\n * @param {ReadonlyQuat} b The second quaternion.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\n\nvar quat_exactEquals = vec4_exactEquals;\n/**\n * Returns whether or not the quaternions have approximately the same elements in the same position.\n *\n * @param {ReadonlyQuat} a The first vector.\n * @param {ReadonlyQuat} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\n\nvar quat_equals = vec4_equals;\n/**\n * Sets a quaternion to represent the shortest rotation from one\n * vector to another.\n *\n * Both vectors are assumed to be unit length.\n *\n * @param {quat} out the receiving quaternion.\n * @param {ReadonlyVec3} a the initial vector\n * @param {ReadonlyVec3} b the destination vector\n * @returns {quat} out\n */\n\nvar rotationTo = function () {\n var tmpvec3 = vec3["create"]();\n var xUnitVec3 = vec3["fromValues"](1, 0, 0);\n var yUnitVec3 = vec3["fromValues"](0, 1, 0);\n return function (out, a, b) {\n var dot = vec3["dot"](a, b);\n\n if (dot < -0.999999) {\n vec3["cross"](tmpvec3, xUnitVec3, a);\n if (vec3["len"](tmpvec3) < 0.000001) vec3["cross"](tmpvec3, yUnitVec3, a);\n vec3["normalize"](tmpvec3, tmpvec3);\n setAxisAngle(out, tmpvec3, Math.PI);\n return out;\n } else if (dot > 0.999999) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n out[3] = 1;\n return out;\n } else {\n vec3["cross"](tmpvec3, a, b);\n out[0] = tmpvec3[0];\n out[1] = tmpvec3[1];\n out[2] = tmpvec3[2];\n out[3] = 1 + dot;\n return quat_normalize(out, out);\n }\n };\n}();\n/**\n * Performs a spherical linear interpolation with two control points\n *\n * @param {quat} out the receiving quaternion\n * @param {ReadonlyQuat} a the first operand\n * @param {ReadonlyQuat} b the second operand\n * @param {ReadonlyQuat} c the third operand\n * @param {ReadonlyQuat} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {quat} out\n */\n\nvar sqlerp = function () {\n var temp1 = quat_create();\n var temp2 = quat_create();\n return function (out, a, b, c, d, t) {\n slerp(temp1, a, d, t);\n slerp(temp2, b, c, t);\n slerp(out, temp1, temp2, 2 * t * (1 - t));\n return out;\n };\n}();\n/**\n * Sets the specified quaternion with values corresponding to the given\n * axes. Each axis is a vec3 and is expected to be unit length and\n * perpendicular to all other specified axes.\n *\n * @param {ReadonlyVec3} view the vector representing the viewing direction\n * @param {ReadonlyVec3} right the vector representing the local "right" direction\n * @param {ReadonlyVec3} up the vector representing the local "up" direction\n * @returns {quat} out\n */\n\nvar setAxes = function () {\n var matr = create();\n return function (out, view, right, up) {\n matr[0] = right[0];\n matr[3] = right[1];\n matr[6] = right[2];\n matr[1] = up[0];\n matr[4] = up[1];\n matr[7] = up[2];\n matr[2] = -view[0];\n matr[5] = -view[1];\n matr[8] = -view[2];\n return quat_normalize(out, fromMat3(out, matr));\n };\n}();\n// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/vec2.js\nvar vec2 = __webpack_require__(81);\n\n// CONCATENATED MODULE: ./node_modules/gl-matrix/esm/index.js\n\n\n\n\n\n\n\n\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS9tYXQzLmpzPzFmMDUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9lc20vbWF0NC5qcz82NWExIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9nbC1tYXRyaXgvZXNtL3ZlYzQuanM/NmU1ZiIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS9xdWF0LmpzPzkyNTkiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2dsLW1hdHJpeC9lc20vaW5kZXguanM/MjBlNyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLEtBQUs7QUFDbEI7O0FBRU87QUFDUCxnQkFBZ0IsNEJBQW1COztBQUVuQyxNQUFNLDRCQUFtQjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCLFdBQVcsYUFBYTtBQUN4QixhQUFhLEtBQUs7QUFDbEI7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxhQUFhO0FBQ3hCLGFBQWEsS0FBSztBQUNsQjs7QUFFTztBQUNQLGdCQUFnQiw0QkFBbUI7QUFDbkM7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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxhQUFhO0FBQ3hCLGFBQWEsS0FBSztBQUNsQjs7QUFFTyxTQUFTLGNBQVM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxhQUFhO0FBQ3hCLGFBQWEsS0FBSztBQUNsQjs7QUFFTyxTQUFTLFdBQU07QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDOztBQUVsQzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxhQUFhO0FBQ3hCLGFBQWEsS0FBSztBQUNsQjs7QUFFTyxTQUFTLFlBQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsS0FBSztBQUNsQjs7QUFFTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixhQUFhLEtBQUs7QUFDbEI7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsS0FBSztBQUNsQjs7QUFFTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtB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QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLE1BQU0sYUFBVTtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsY0FBUztBQUN0QjtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLFdBQVcsS0FBSztBQUNoQixXQUFXLGFBQWE7QUFDeEIsV0FBVyxhQUFhO0FBQ3hCLFdBQVcsYUFBYTtBQUN4QixXQUFXLGFBQWE7QUFDeEIsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsS0FBSztBQUNsQjs7QUFFTztBQUNQLGNBQWMsV0FBTTtBQUNwQixjQUFjLFdBQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGFBQWE7QUFDeEIsV0FBVyxhQUFhO0FBQ3hCLFdBQVcsYUFBYTtBQUN4QixhQUFhLEtBQUs7QUFDbEI7O0FBRU87QUFDUCxhQUFhLE1BQVc7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGNBQVM7QUFDcEI7QUFDQSxDQUFDLEc7Ozs7O0FDcnNCdUM7QUFDTjtBQUNFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0U7QUFDRjtBQUNBO0FBQ0EiLCJmaWxlIjoiMi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdsTWF0cml4IGZyb20gXCIuL2NvbW1vbi5qc1wiO1xuLyoqXG4gKiAzeDMgTWF0cml4XG4gKiBAbW9kdWxlIG1hdDNcbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0M1xuICpcbiAqIEByZXR1cm5zIHttYXQzfSBhIG5ldyAzeDMgbWF0cml4XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDkpO1xuXG4gIGlmIChnbE1hdHJpeC5BUlJBWV9UWVBFICE9IEZsb2F0MzJBcnJheSkge1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs1XSA9IDA7XG4gICAgb3V0WzZdID0gMDtcbiAgICBvdXRbN10gPSAwO1xuICB9XG5cbiAgb3V0WzBdID0gMTtcbiAgb3V0WzRdID0gMTtcbiAgb3V0WzhdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ29waWVzIHRoZSB1cHBlci1sZWZ0IDN4MyB2YWx1ZXMgaW50byB0aGUgZ2l2ZW4gbWF0My5cbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIDN4MyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhICAgdGhlIHNvdXJjZSA0eDQgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21NYXQ0KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzRdO1xuICBvdXRbNF0gPSBhWzVdO1xuICBvdXRbNV0gPSBhWzZdO1xuICBvdXRbNl0gPSBhWzhdO1xuICBvdXRbN10gPSBhWzldO1xuICBvdXRbOF0gPSBhWzEwXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBtYXQzIGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgbWF0cml4XG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgbWF0cml4IHRvIGNsb25lXG4gKiBAcmV0dXJucyB7bWF0M30gYSBuZXcgM3gzIG1hdHJpeFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShhKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg5KTtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgb3V0WzNdID0gYVszXTtcbiAgb3V0WzRdID0gYVs0XTtcbiAgb3V0WzVdID0gYVs1XTtcbiAgb3V0WzZdID0gYVs2XTtcbiAgb3V0WzddID0gYVs3XTtcbiAgb3V0WzhdID0gYVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIG1hdDMgdG8gYW5vdGhlclxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICBvdXRbOF0gPSBhWzhdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgbWF0MyB3aXRoIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbTAwIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDAgcG9zaXRpb24gKGluZGV4IDApXG4gKiBAcGFyYW0ge051bWJlcn0gbTAxIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDEgcG9zaXRpb24gKGluZGV4IDEpXG4gKiBAcGFyYW0ge051bWJlcn0gbTAyIENvbXBvbmVudCBpbiBjb2x1bW4gMCwgcm93IDIgcG9zaXRpb24gKGluZGV4IDIpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEwIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDAgcG9zaXRpb24gKGluZGV4IDMpXG4gKiBAcGFyYW0ge051bWJlcn0gbTExIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDEgcG9zaXRpb24gKGluZGV4IDQpXG4gKiBAcGFyYW0ge051bWJlcn0gbTEyIENvbXBvbmVudCBpbiBjb2x1bW4gMSwgcm93IDIgcG9zaXRpb24gKGluZGV4IDUpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIwIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDAgcG9zaXRpb24gKGluZGV4IDYpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIxIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDEgcG9zaXRpb24gKGluZGV4IDcpXG4gKiBAcGFyYW0ge051bWJlcn0gbTIyIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDIgcG9zaXRpb24gKGluZGV4IDgpXG4gKiBAcmV0dXJucyB7bWF0M30gQSBuZXcgbWF0M1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tVmFsdWVzKG0wMCwgbTAxLCBtMDIsIG0xMCwgbTExLCBtMTIsIG0yMCwgbTIxLCBtMjIpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDkpO1xuICBvdXRbMF0gPSBtMDA7XG4gIG91dFsxXSA9IG0wMTtcbiAgb3V0WzJdID0gbTAyO1xuICBvdXRbM10gPSBtMTA7XG4gIG91dFs0XSA9IG0xMTtcbiAgb3V0WzVdID0gbTEyO1xuICBvdXRbNl0gPSBtMjA7XG4gIG91dFs3XSA9IG0yMTtcbiAgb3V0WzhdID0gbTIyO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBtYXQzIHRvIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMCBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAwKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMSBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAxIHBvc2l0aW9uIChpbmRleCAxKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0wMiBDb21wb25lbnQgaW4gY29sdW1uIDAsIHJvdyAyIHBvc2l0aW9uIChpbmRleCAyKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMCBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAzKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMSBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAxIHBvc2l0aW9uIChpbmRleCA0KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0xMiBDb21wb25lbnQgaW4gY29sdW1uIDEsIHJvdyAyIHBvc2l0aW9uIChpbmRleCA1KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMCBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAwIHBvc2l0aW9uIChpbmRleCA2KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMSBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAxIHBvc2l0aW9uIChpbmRleCA3KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0yMiBDb21wb25lbnQgaW4gY29sdW1uIDIsIHJvdyAyIHBvc2l0aW9uIChpbmRleCA4KVxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXQob3V0LCBtMDAsIG0wMSwgbTAyLCBtMTAsIG0xMSwgbTEyLCBtMjAsIG0yMSwgbTIyKSB7XG4gIG91dFswXSA9IG0wMDtcbiAgb3V0WzFdID0gbTAxO1xuICBvdXRbMl0gPSBtMDI7XG4gIG91dFszXSA9IG0xMDtcbiAgb3V0WzRdID0gbTExO1xuICBvdXRbNV0gPSBtMTI7XG4gIG91dFs2XSA9IG0yMDtcbiAgb3V0WzddID0gbTIxO1xuICBvdXRbOF0gPSBtMjI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCBhIG1hdDMgdG8gdGhlIGlkZW50aXR5IG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KG91dCkge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAxO1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBUcmFuc3Bvc2UgdGhlIHZhbHVlcyBvZiBhIG1hdDNcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNwb3NlKG91dCwgYSkge1xuICAvLyBJZiB3ZSBhcmUgdHJhbnNwb3Npbmcgb3Vyc2VsdmVzIHdlIGNhbiBza2lwIGEgZmV3IHN0ZXBzIGJ1dCBoYXZlIHRvIGNhY2hlIHNvbWUgdmFsdWVzXG4gIGlmIChvdXQgPT09IGEpIHtcbiAgICB2YXIgYTAxID0gYVsxXSxcbiAgICAgICAgYTAyID0gYVsyXSxcbiAgICAgICAgYTEyID0gYVs1XTtcbiAgICBvdXRbMV0gPSBhWzNdO1xuICAgIG91dFsyXSA9IGFbNl07XG4gICAgb3V0WzNdID0gYTAxO1xuICAgIG91dFs1XSA9IGFbN107XG4gICAgb3V0WzZdID0gYTAyO1xuICAgIG91dFs3XSA9IGExMjtcbiAgfSBlbHNlIHtcbiAgICBvdXRbMF0gPSBhWzBdO1xuICAgIG91dFsxXSA9IGFbM107XG4gICAgb3V0WzJdID0gYVs2XTtcbiAgICBvdXRbM10gPSBhWzFdO1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs3XTtcbiAgICBvdXRbNl0gPSBhWzJdO1xuICAgIG91dFs3XSA9IGFbNV07XG4gICAgb3V0WzhdID0gYVs4XTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEludmVydHMgYSBtYXQzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVydChvdXQsIGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXTtcbiAgdmFyIGExMCA9IGFbM10sXG4gICAgICBhMTEgPSBhWzRdLFxuICAgICAgYTEyID0gYVs1XTtcbiAgdmFyIGEyMCA9IGFbNl0sXG4gICAgICBhMjEgPSBhWzddLFxuICAgICAgYTIyID0gYVs4XTtcbiAgdmFyIGIwMSA9IGEyMiAqIGExMSAtIGExMiAqIGEyMTtcbiAgdmFyIGIxMSA9IC1hMjIgKiBhMTAgKyBhMTIgKiBhMjA7XG4gIHZhciBiMjEgPSBhMjEgKiBhMTAgLSBhMTEgKiBhMjA7IC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcblxuICB2YXIgZGV0ID0gYTAwICogYjAxICsgYTAxICogYjExICsgYTAyICogYjIxO1xuXG4gIGlmICghZGV0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkZXQgPSAxLjAgLyBkZXQ7XG4gIG91dFswXSA9IGIwMSAqIGRldDtcbiAgb3V0WzFdID0gKC1hMjIgKiBhMDEgKyBhMDIgKiBhMjEpICogZGV0O1xuICBvdXRbMl0gPSAoYTEyICogYTAxIC0gYTAyICogYTExKSAqIGRldDtcbiAgb3V0WzNdID0gYjExICogZGV0O1xuICBvdXRbNF0gPSAoYTIyICogYTAwIC0gYTAyICogYTIwKSAqIGRldDtcbiAgb3V0WzVdID0gKC1hMTIgKiBhMDAgKyBhMDIgKiBhMTApICogZGV0O1xuICBvdXRbNl0gPSBiMjEgKiBkZXQ7XG4gIG91dFs3XSA9ICgtYTIxICogYTAwICsgYTAxICogYTIwKSAqIGRldDtcbiAgb3V0WzhdID0gKGExMSAqIGEwMCAtIGEwMSAqIGExMCkgKiBkZXQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGFkanVnYXRlIG9mIGEgbWF0M1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGpvaW50KG91dCwgYSkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdO1xuICB2YXIgYTEwID0gYVszXSxcbiAgICAgIGExMSA9IGFbNF0sXG4gICAgICBhMTIgPSBhWzVdO1xuICB2YXIgYTIwID0gYVs2XSxcbiAgICAgIGEyMSA9IGFbN10sXG4gICAgICBhMjIgPSBhWzhdO1xuICBvdXRbMF0gPSBhMTEgKiBhMjIgLSBhMTIgKiBhMjE7XG4gIG91dFsxXSA9IGEwMiAqIGEyMSAtIGEwMSAqIGEyMjtcbiAgb3V0WzJdID0gYTAxICogYTEyIC0gYTAyICogYTExO1xuICBvdXRbM10gPSBhMTIgKiBhMjAgLSBhMTAgKiBhMjI7XG4gIG91dFs0XSA9IGEwMCAqIGEyMiAtIGEwMiAqIGEyMDtcbiAgb3V0WzVdID0gYTAyICogYTEwIC0gYTAwICogYTEyO1xuICBvdXRbNl0gPSBhMTAgKiBhMjEgLSBhMTEgKiBhMjA7XG4gIG91dFs3XSA9IGEwMSAqIGEyMCAtIGEwMCAqIGEyMTtcbiAgb3V0WzhdID0gYTAwICogYTExIC0gYTAxICogYTEwO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBkZXRlcm1pbmFudCBvZiBhIG1hdDNcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge051bWJlcn0gZGV0ZXJtaW5hbnQgb2YgYVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlcm1pbmFudChhKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl07XG4gIHZhciBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV07XG4gIHZhciBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF07XG4gIHJldHVybiBhMDAgKiAoYTIyICogYTExIC0gYTEyICogYTIxKSArIGEwMSAqICgtYTIyICogYTEwICsgYTEyICogYTIwKSArIGEwMiAqIChhMjEgKiBhMTAgLSBhMTEgKiBhMjApO1xufVxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBtYXQzJ3NcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aXBseShvdXQsIGEsIGIpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXTtcbiAgdmFyIGExMCA9IGFbM10sXG4gICAgICBhMTEgPSBhWzRdLFxuICAgICAgYTEyID0gYVs1XTtcbiAgdmFyIGEyMCA9IGFbNl0sXG4gICAgICBhMjEgPSBhWzddLFxuICAgICAgYTIyID0gYVs4XTtcbiAgdmFyIGIwMCA9IGJbMF0sXG4gICAgICBiMDEgPSBiWzFdLFxuICAgICAgYjAyID0gYlsyXTtcbiAgdmFyIGIxMCA9IGJbM10sXG4gICAgICBiMTEgPSBiWzRdLFxuICAgICAgYjEyID0gYls1XTtcbiAgdmFyIGIyMCA9IGJbNl0sXG4gICAgICBiMjEgPSBiWzddLFxuICAgICAgYjIyID0gYls4XTtcbiAgb3V0WzBdID0gYjAwICogYTAwICsgYjAxICogYTEwICsgYjAyICogYTIwO1xuICBvdXRbMV0gPSBiMDAgKiBhMDEgKyBiMDEgKiBhMTEgKyBiMDIgKiBhMjE7XG4gIG91dFsyXSA9IGIwMCAqIGEwMiArIGIwMSAqIGExMiArIGIwMiAqIGEyMjtcbiAgb3V0WzNdID0gYjEwICogYTAwICsgYjExICogYTEwICsgYjEyICogYTIwO1xuICBvdXRbNF0gPSBiMTAgKiBhMDEgKyBiMTEgKiBhMTEgKyBiMTIgKiBhMjE7XG4gIG91dFs1XSA9IGIxMCAqIGEwMiArIGIxMSAqIGExMiArIGIxMiAqIGEyMjtcbiAgb3V0WzZdID0gYjIwICogYTAwICsgYjIxICogYTEwICsgYjIyICogYTIwO1xuICBvdXRbN10gPSBiMjAgKiBhMDEgKyBiMjEgKiBhMTEgKyBiMjIgKiBhMjE7XG4gIG91dFs4XSA9IGIyMCAqIGEwMiArIGIyMSAqIGExMiArIGIyMiAqIGEyMjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNsYXRlIGEgbWF0MyBieSB0aGUgZ2l2ZW4gdmVjdG9yXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBtYXRyaXggdG8gdHJhbnNsYXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjMn0gdiB2ZWN0b3IgdG8gdHJhbnNsYXRlIGJ5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGExMCA9IGFbM10sXG4gICAgICBhMTEgPSBhWzRdLFxuICAgICAgYTEyID0gYVs1XSxcbiAgICAgIGEyMCA9IGFbNl0sXG4gICAgICBhMjEgPSBhWzddLFxuICAgICAgYTIyID0gYVs4XSxcbiAgICAgIHggPSB2WzBdLFxuICAgICAgeSA9IHZbMV07XG4gIG91dFswXSA9IGEwMDtcbiAgb3V0WzFdID0gYTAxO1xuICBvdXRbMl0gPSBhMDI7XG4gIG91dFszXSA9IGExMDtcbiAgb3V0WzRdID0gYTExO1xuICBvdXRbNV0gPSBhMTI7XG4gIG91dFs2XSA9IHggKiBhMDAgKyB5ICogYTEwICsgYTIwO1xuICBvdXRbN10gPSB4ICogYTAxICsgeSAqIGExMSArIGEyMTtcbiAgb3V0WzhdID0geCAqIGEwMiArIHkgKiBhMTIgKyBhMjI7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBtYXQzIGJ5IHRoZSBnaXZlbiBhbmdsZVxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKG91dCwgYSwgcmFkKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMTAgPSBhWzNdLFxuICAgICAgYTExID0gYVs0XSxcbiAgICAgIGExMiA9IGFbNV0sXG4gICAgICBhMjAgPSBhWzZdLFxuICAgICAgYTIxID0gYVs3XSxcbiAgICAgIGEyMiA9IGFbOF0sXG4gICAgICBzID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGMgPSBNYXRoLmNvcyhyYWQpO1xuICBvdXRbMF0gPSBjICogYTAwICsgcyAqIGExMDtcbiAgb3V0WzFdID0gYyAqIGEwMSArIHMgKiBhMTE7XG4gIG91dFsyXSA9IGMgKiBhMDIgKyBzICogYTEyO1xuICBvdXRbM10gPSBjICogYTEwIC0gcyAqIGEwMDtcbiAgb3V0WzRdID0gYyAqIGExMSAtIHMgKiBhMDE7XG4gIG91dFs1XSA9IGMgKiBhMTIgLSBzICogYTAyO1xuICBvdXRbNl0gPSBhMjA7XG4gIG91dFs3XSA9IGEyMTtcbiAgb3V0WzhdID0gYTIyO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTY2FsZXMgdGhlIG1hdDMgYnkgdGhlIGRpbWVuc2lvbnMgaW4gdGhlIGdpdmVuIHZlYzJcbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IHRoZSB2ZWMyIHRvIHNjYWxlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgdikge1xuICB2YXIgeCA9IHZbMF0sXG4gICAgICB5ID0gdlsxXTtcbiAgb3V0WzBdID0geCAqIGFbMF07XG4gIG91dFsxXSA9IHggKiBhWzFdO1xuICBvdXRbMl0gPSB4ICogYVsyXTtcbiAgb3V0WzNdID0geSAqIGFbM107XG4gIG91dFs0XSA9IHkgKiBhWzRdO1xuICBvdXRbNV0gPSB5ICogYVs1XTtcbiAgb3V0WzZdID0gYVs2XTtcbiAgb3V0WzddID0gYVs3XTtcbiAgb3V0WzhdID0gYVs4XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIHRyYW5zbGF0aW9uXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQzLnRyYW5zbGF0ZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMyfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tVHJhbnNsYXRpb24ob3V0LCB2KSB7XG4gIG91dFswXSA9IDE7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IDE7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IHZbMF07XG4gIG91dFs3XSA9IHZbMV07XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIGdpdmVuIGFuZ2xlXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQzLnJvdGF0ZShkZXN0LCBkZXN0LCByYWQpO1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Sb3RhdGlvbihvdXQsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCksXG4gICAgICBjID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYztcbiAgb3V0WzFdID0gcztcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gLXM7XG4gIG91dFs0XSA9IGM7XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciBzY2FsaW5nXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0My5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQzLnNjYWxlKGRlc3QsIGRlc3QsIHZlYyk7XG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgbWF0MyByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVZlYzJ9IHYgU2NhbGluZyB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVNjYWxpbmcob3V0LCB2KSB7XG4gIG91dFswXSA9IHZbMF07XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IHZbMV07XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIGZyb20gYSBtYXQyZCBpbnRvIGEgbWF0M1xuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0MmR9IGEgdGhlIG1hdHJpeCB0byBjb3B5XG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKiovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tTWF0MmQob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IGFbMl07XG4gIG91dFs0XSA9IGFbM107XG4gIG91dFs1XSA9IDA7XG4gIG91dFs2XSA9IGFbNF07XG4gIG91dFs3XSA9IGFbNV07XG4gIG91dFs4XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgYSAzeDMgbWF0cml4IGZyb20gdGhlIGdpdmVuIHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCBtYXQzIHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBRdWF0ZXJuaW9uIHRvIGNyZWF0ZSBtYXRyaXggZnJvbVxuICpcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVF1YXQob3V0LCBxKSB7XG4gIHZhciB4ID0gcVswXSxcbiAgICAgIHkgPSBxWzFdLFxuICAgICAgeiA9IHFbMl0sXG4gICAgICB3ID0gcVszXTtcbiAgdmFyIHgyID0geCArIHg7XG4gIHZhciB5MiA9IHkgKyB5O1xuICB2YXIgejIgPSB6ICsgejtcbiAgdmFyIHh4ID0geCAqIHgyO1xuICB2YXIgeXggPSB5ICogeDI7XG4gIHZhciB5eSA9IHkgKiB5MjtcbiAgdmFyIHp4ID0geiAqIHgyO1xuICB2YXIgenkgPSB6ICogeTI7XG4gIHZhciB6eiA9IHogKiB6MjtcbiAgdmFyIHd4ID0gdyAqIHgyO1xuICB2YXIgd3kgPSB3ICogeTI7XG4gIHZhciB3eiA9IHcgKiB6MjtcbiAgb3V0WzBdID0gMSAtIHl5IC0geno7XG4gIG91dFszXSA9IHl4IC0gd3o7XG4gIG91dFs2XSA9IHp4ICsgd3k7XG4gIG91dFsxXSA9IHl4ICsgd3o7XG4gIG91dFs0XSA9IDEgLSB4eCAtIHp6O1xuICBvdXRbN10gPSB6eSAtIHd4O1xuICBvdXRbMl0gPSB6eCAtIHd5O1xuICBvdXRbNV0gPSB6eSArIHd4O1xuICBvdXRbOF0gPSAxIC0geHggLSB5eTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyBhIDN4MyBub3JtYWwgbWF0cml4ICh0cmFuc3Bvc2UgaW52ZXJzZSkgZnJvbSB0aGUgNHg0IG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IG1hdDMgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIE1hdDQgdG8gZGVyaXZlIHRoZSBub3JtYWwgbWF0cml4IGZyb21cbiAqXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbEZyb21NYXQ0KG91dCwgYSkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdLFxuICAgICAgYTAzID0gYVszXTtcbiAgdmFyIGExMCA9IGFbNF0sXG4gICAgICBhMTEgPSBhWzVdLFxuICAgICAgYTEyID0gYVs2XSxcbiAgICAgIGExMyA9IGFbN107XG4gIHZhciBhMjAgPSBhWzhdLFxuICAgICAgYTIxID0gYVs5XSxcbiAgICAgIGEyMiA9IGFbMTBdLFxuICAgICAgYTIzID0gYVsxMV07XG4gIHZhciBhMzAgPSBhWzEyXSxcbiAgICAgIGEzMSA9IGFbMTNdLFxuICAgICAgYTMyID0gYVsxNF0sXG4gICAgICBhMzMgPSBhWzE1XTtcbiAgdmFyIGIwMCA9IGEwMCAqIGExMSAtIGEwMSAqIGExMDtcbiAgdmFyIGIwMSA9IGEwMCAqIGExMiAtIGEwMiAqIGExMDtcbiAgdmFyIGIwMiA9IGEwMCAqIGExMyAtIGEwMyAqIGExMDtcbiAgdmFyIGIwMyA9IGEwMSAqIGExMiAtIGEwMiAqIGExMTtcbiAgdmFyIGIwNCA9IGEwMSAqIGExMyAtIGEwMyAqIGExMTtcbiAgdmFyIGIwNSA9IGEwMiAqIGExMyAtIGEwMyAqIGExMjtcbiAgdmFyIGIwNiA9IGEyMCAqIGEzMSAtIGEyMSAqIGEzMDtcbiAgdmFyIGIwNyA9IGEyMCAqIGEzMiAtIGEyMiAqIGEzMDtcbiAgdmFyIGIwOCA9IGEyMCAqIGEzMyAtIGEyMyAqIGEzMDtcbiAgdmFyIGIwOSA9IGEyMSAqIGEzMiAtIGEyMiAqIGEzMTtcbiAgdmFyIGIxMCA9IGEyMSAqIGEzMyAtIGEyMyAqIGEzMTtcbiAgdmFyIGIxMSA9IGEyMiAqIGEzMyAtIGEyMyAqIGEzMjsgLy8gQ2FsY3VsYXRlIHRoZSBkZXRlcm1pbmFudFxuXG4gIHZhciBkZXQgPSBiMDAgKiBiMTEgLSBiMDEgKiBiMTAgKyBiMDIgKiBiMDkgKyBiMDMgKiBiMDggLSBiMDQgKiBiMDcgKyBiMDUgKiBiMDY7XG5cbiAgaWYgKCFkZXQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGRldCA9IDEuMCAvIGRldDtcbiAgb3V0WzBdID0gKGExMSAqIGIxMSAtIGExMiAqIGIxMCArIGExMyAqIGIwOSkgKiBkZXQ7XG4gIG91dFsxXSA9IChhMTIgKiBiMDggLSBhMTAgKiBiMTEgLSBhMTMgKiBiMDcpICogZGV0O1xuICBvdXRbMl0gPSAoYTEwICogYjEwIC0gYTExICogYjA4ICsgYTEzICogYjA2KSAqIGRldDtcbiAgb3V0WzNdID0gKGEwMiAqIGIxMCAtIGEwMSAqIGIxMSAtIGEwMyAqIGIwOSkgKiBkZXQ7XG4gIG91dFs0XSA9IChhMDAgKiBiMTEgLSBhMDIgKiBiMDggKyBhMDMgKiBiMDcpICogZGV0O1xuICBvdXRbNV0gPSAoYTAxICogYjA4IC0gYTAwICogYjEwIC0gYTAzICogYjA2KSAqIGRldDtcbiAgb3V0WzZdID0gKGEzMSAqIGIwNSAtIGEzMiAqIGIwNCArIGEzMyAqIGIwMykgKiBkZXQ7XG4gIG91dFs3XSA9IChhMzIgKiBiMDIgLSBhMzAgKiBiMDUgLSBhMzMgKiBiMDEpICogZGV0O1xuICBvdXRbOF0gPSAoYTMwICogYjA0IC0gYTMxICogYjAyICsgYTMzICogYjAwKSAqIGRldDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgMkQgcHJvamVjdGlvbiBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgbWF0MyBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFdpZHRoIG9mIHlvdXIgZ2wgY29udGV4dFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCBIZWlnaHQgb2YgZ2wgY29udGV4dFxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwcm9qZWN0aW9uKG91dCwgd2lkdGgsIGhlaWdodCkge1xuICBvdXRbMF0gPSAyIC8gd2lkdGg7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IC0yIC8gaGVpZ2h0O1xuICBvdXRbNV0gPSAwO1xuICBvdXRbNl0gPSAtMTtcbiAgb3V0WzddID0gMTtcbiAgb3V0WzhdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG1hdDNcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSBtYXRyaXggdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1hdHJpeFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJtYXQzKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIsIFwiICsgYVszXSArIFwiLCBcIiArIGFbNF0gKyBcIiwgXCIgKyBhWzVdICsgXCIsIFwiICsgYVs2XSArIFwiLCBcIiArIGFbN10gKyBcIiwgXCIgKyBhWzhdICsgXCIpXCI7XG59XG4vKipcbiAqIFJldHVybnMgRnJvYmVuaXVzIG5vcm0gb2YgYSBtYXQzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIG1hdHJpeCB0byBjYWxjdWxhdGUgRnJvYmVuaXVzIG5vcm0gb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IEZyb2Jlbml1cyBub3JtXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb2IoYSkge1xuICByZXR1cm4gTWF0aC5oeXBvdChhWzBdLCBhWzFdLCBhWzJdLCBhWzNdLCBhWzRdLCBhWzVdLCBhWzZdLCBhWzddLCBhWzhdKTtcbn1cbi8qKlxuICogQWRkcyB0d28gbWF0MydzXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHttYXQzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdO1xuICBvdXRbM10gPSBhWzNdICsgYlszXTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gKyBiWzVdO1xuICBvdXRbNl0gPSBhWzZdICsgYls2XTtcbiAgb3V0WzddID0gYVs3XSArIGJbN107XG4gIG91dFs4XSA9IGFbOF0gKyBiWzhdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTdWJ0cmFjdHMgbWF0cml4IGIgZnJvbSBtYXRyaXggYVxuICpcbiAqIEBwYXJhbSB7bWF0M30gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLSBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC0gYlszXTtcbiAgb3V0WzRdID0gYVs0XSAtIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gLSBiWzVdO1xuICBvdXRbNl0gPSBhWzZdIC0gYls2XTtcbiAgb3V0WzddID0gYVs3XSAtIGJbN107XG4gIG91dFs4XSA9IGFbOF0gLSBiWzhdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBNdWx0aXBseSBlYWNoIGVsZW1lbnQgb2YgdGhlIG1hdHJpeCBieSBhIHNjYWxhci5cbiAqXG4gKiBAcGFyYW0ge21hdDN9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGEgdGhlIG1hdHJpeCB0byBzY2FsZVxuICogQHBhcmFtIHtOdW1iZXJ9IGIgYW1vdW50IHRvIHNjYWxlIHRoZSBtYXRyaXgncyBlbGVtZW50cyBieVxuICogQHJldHVybnMge21hdDN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aXBseVNjYWxhcihvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAqIGI7XG4gIG91dFsxXSA9IGFbMV0gKiBiO1xuICBvdXRbMl0gPSBhWzJdICogYjtcbiAgb3V0WzNdID0gYVszXSAqIGI7XG4gIG91dFs0XSA9IGFbNF0gKiBiO1xuICBvdXRbNV0gPSBhWzVdICogYjtcbiAgb3V0WzZdID0gYVs2XSAqIGI7XG4gIG91dFs3XSA9IGFbN10gKiBiO1xuICBvdXRbOF0gPSBhWzhdICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWRkcyB0d28gbWF0MydzIGFmdGVyIG11bHRpcGx5aW5nIGVhY2ggZWxlbWVudCBvZiB0aGUgc2Vjb25kIG9wZXJhbmQgYnkgYSBzY2FsYXIgdmFsdWUuXG4gKlxuICogQHBhcmFtIHttYXQzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIncyBlbGVtZW50cyBieSBiZWZvcmUgYWRkaW5nXG4gKiBAcmV0dXJucyB7bWF0M30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyQW5kQWRkKG91dCwgYSwgYiwgc2NhbGUpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF0gKiBzY2FsZTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV0gKiBzY2FsZTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl0gKiBzY2FsZTtcbiAgb3V0WzNdID0gYVszXSArIGJbM10gKiBzY2FsZTtcbiAgb3V0WzRdID0gYVs0XSArIGJbNF0gKiBzY2FsZTtcbiAgb3V0WzVdID0gYVs1XSArIGJbNV0gKiBzY2FsZTtcbiAgb3V0WzZdID0gYVs2XSArIGJbNl0gKiBzY2FsZTtcbiAgb3V0WzddID0gYVs3XSArIGJbN10gKiBzY2FsZTtcbiAgb3V0WzhdID0gYVs4XSArIGJbOF0gKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgbWF0cmljZXMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQzfSBhIFRoZSBmaXJzdCBtYXRyaXguXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYiBUaGUgc2Vjb25kIG1hdHJpeC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBtYXRyaWNlcyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhhY3RFcXVhbHMoYSwgYikge1xuICByZXR1cm4gYVswXSA9PT0gYlswXSAmJiBhWzFdID09PSBiWzFdICYmIGFbMl0gPT09IGJbMl0gJiYgYVszXSA9PT0gYlszXSAmJiBhWzRdID09PSBiWzRdICYmIGFbNV0gPT09IGJbNV0gJiYgYVs2XSA9PT0gYls2XSAmJiBhWzddID09PSBiWzddICYmIGFbOF0gPT09IGJbOF07XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIG1hdHJpY2VzIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gYSBUaGUgZmlyc3QgbWF0cml4LlxuICogQHBhcmFtIHtSZWFkb25seU1hdDN9IGIgVGhlIHNlY29uZCBtYXRyaXguXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWF0cmljZXMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl0sXG4gICAgICBhMyA9IGFbM10sXG4gICAgICBhNCA9IGFbNF0sXG4gICAgICBhNSA9IGFbNV0sXG4gICAgICBhNiA9IGFbNl0sXG4gICAgICBhNyA9IGFbN10sXG4gICAgICBhOCA9IGFbOF07XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl0sXG4gICAgICBiMyA9IGJbM10sXG4gICAgICBiNCA9IGJbNF0sXG4gICAgICBiNSA9IGJbNV0sXG4gICAgICBiNiA9IGJbNl0sXG4gICAgICBiNyA9IGJbN10sXG4gICAgICBiOCA9IGJbOF07XG4gIHJldHVybiBNYXRoLmFicyhhMCAtIGIwKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMCksIE1hdGguYWJzKGIwKSkgJiYgTWF0aC5hYnMoYTEgLSBiMSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEpLCBNYXRoLmFicyhiMSkpICYmIE1hdGguYWJzKGEyIC0gYjIpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEyKSwgTWF0aC5hYnMoYjIpKSAmJiBNYXRoLmFicyhhMyAtIGIzKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMyksIE1hdGguYWJzKGIzKSkgJiYgTWF0aC5hYnMoYTQgLSBiNCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTQpLCBNYXRoLmFicyhiNCkpICYmIE1hdGguYWJzKGE1IC0gYjUpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE1KSwgTWF0aC5hYnMoYjUpKSAmJiBNYXRoLmFicyhhNiAtIGI2KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNiksIE1hdGguYWJzKGI2KSkgJiYgTWF0aC5hYnMoYTcgLSBiNykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTcpLCBNYXRoLmFicyhiNykpICYmIE1hdGguYWJzKGE4IC0gYjgpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE4KSwgTWF0aC5hYnMoYjgpKTtcbn1cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQzLm11bHRpcGx5fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBtdWwgPSBtdWx0aXBseTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQzLnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzdWIgPSBzdWJ0cmFjdDsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbi8qKlxuICogNHg0IE1hdHJpeDxicj5Gb3JtYXQ6IGNvbHVtbi1tYWpvciwgd2hlbiB0eXBlZCBvdXQgaXQgbG9va3MgbGlrZSByb3ctbWFqb3I8YnI+VGhlIG1hdHJpY2VzIGFyZSBiZWluZyBwb3N0IG11bHRpcGxpZWQuXG4gKiBAbW9kdWxlIG1hdDRcbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgaWRlbnRpdHkgbWF0NFxuICpcbiAqIEByZXR1cm5zIHttYXQ0fSBhIG5ldyA0eDQgbWF0cml4XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDE2KTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMV0gPSAwO1xuICAgIG91dFsyXSA9IDA7XG4gICAgb3V0WzNdID0gMDtcbiAgICBvdXRbNF0gPSAwO1xuICAgIG91dFs2XSA9IDA7XG4gICAgb3V0WzddID0gMDtcbiAgICBvdXRbOF0gPSAwO1xuICAgIG91dFs5XSA9IDA7XG4gICAgb3V0WzExXSA9IDA7XG4gICAgb3V0WzEyXSA9IDA7XG4gICAgb3V0WzEzXSA9IDA7XG4gICAgb3V0WzE0XSA9IDA7XG4gIH1cblxuICBvdXRbMF0gPSAxO1xuICBvdXRbNV0gPSAxO1xuICBvdXRbMTBdID0gMTtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbWF0NCBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIG1hdHJpeFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIG1hdHJpeCB0byBjbG9uZVxuICogQHJldHVybnMge21hdDR9IGEgbmV3IDR4NCBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoYSkge1xuICB2YXIgb3V0ID0gbmV3IGdsTWF0cml4LkFSUkFZX1RZUEUoMTYpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICBvdXRbNF0gPSBhWzRdO1xuICBvdXRbNV0gPSBhWzVdO1xuICBvdXRbNl0gPSBhWzZdO1xuICBvdXRbN10gPSBhWzddO1xuICBvdXRbOF0gPSBhWzhdO1xuICBvdXRbOV0gPSBhWzldO1xuICBvdXRbMTBdID0gYVsxMF07XG4gIG91dFsxMV0gPSBhWzExXTtcbiAgb3V0WzEyXSA9IGFbMTJdO1xuICBvdXRbMTNdID0gYVsxM107XG4gIG91dFsxNF0gPSBhWzE0XTtcbiAgb3V0WzE1XSA9IGFbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDb3B5IHRoZSB2YWx1ZXMgZnJvbSBvbmUgbWF0NCB0byBhbm90aGVyXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvcHkob3V0LCBhKSB7XG4gIG91dFswXSA9IGFbMF07XG4gIG91dFsxXSA9IGFbMV07XG4gIG91dFsyXSA9IGFbMl07XG4gIG91dFszXSA9IGFbM107XG4gIG91dFs0XSA9IGFbNF07XG4gIG91dFs1XSA9IGFbNV07XG4gIG91dFs2XSA9IGFbNl07XG4gIG91dFs3XSA9IGFbN107XG4gIG91dFs4XSA9IGFbOF07XG4gIG91dFs5XSA9IGFbOV07XG4gIG91dFsxMF0gPSBhWzEwXTtcbiAgb3V0WzExXSA9IGFbMTFdO1xuICBvdXRbMTJdID0gYVsxMl07XG4gIG91dFsxM10gPSBhWzEzXTtcbiAgb3V0WzE0XSA9IGFbMTRdO1xuICBvdXRbMTVdID0gYVsxNV07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBtYXQ0IHdpdGggdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDAgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDEgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDIgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDMgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggMylcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTAgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggNClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTEgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggNSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTIgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggNilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTMgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggNylcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjAgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggOClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjEgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggOSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjIgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMTApXG4gKiBAcGFyYW0ge051bWJlcn0gbTIzIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDMgcG9zaXRpb24gKGluZGV4IDExKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0zMCBDb21wb25lbnQgaW4gY29sdW1uIDMsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAxMilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzEgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMTMpXG4gKiBAcGFyYW0ge051bWJlcn0gbTMyIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDIgcG9zaXRpb24gKGluZGV4IDE0KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0zMyBDb21wb25lbnQgaW4gY29sdW1uIDMsIHJvdyAzIHBvc2l0aW9uIChpbmRleCAxNSlcbiAqIEByZXR1cm5zIHttYXQ0fSBBIG5ldyBtYXQ0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21WYWx1ZXMobTAwLCBtMDEsIG0wMiwgbTAzLCBtMTAsIG0xMSwgbTEyLCBtMTMsIG0yMCwgbTIxLCBtMjIsIG0yMywgbTMwLCBtMzEsIG0zMiwgbTMzKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgxNik7XG4gIG91dFswXSA9IG0wMDtcbiAgb3V0WzFdID0gbTAxO1xuICBvdXRbMl0gPSBtMDI7XG4gIG91dFszXSA9IG0wMztcbiAgb3V0WzRdID0gbTEwO1xuICBvdXRbNV0gPSBtMTE7XG4gIG91dFs2XSA9IG0xMjtcbiAgb3V0WzddID0gbTEzO1xuICBvdXRbOF0gPSBtMjA7XG4gIG91dFs5XSA9IG0yMTtcbiAgb3V0WzEwXSA9IG0yMjtcbiAgb3V0WzExXSA9IG0yMztcbiAgb3V0WzEyXSA9IG0zMDtcbiAgb3V0WzEzXSA9IG0zMTtcbiAgb3V0WzE0XSA9IG0zMjtcbiAgb3V0WzE1XSA9IG0zMztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU2V0IHRoZSBjb21wb25lbnRzIG9mIGEgbWF0NCB0byB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDAgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggMClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDEgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDIgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMDMgQ29tcG9uZW50IGluIGNvbHVtbiAwLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggMylcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTAgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggNClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTEgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggNSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTIgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggNilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMTMgQ29tcG9uZW50IGluIGNvbHVtbiAxLCByb3cgMyBwb3NpdGlvbiAoaW5kZXggNylcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjAgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMCBwb3NpdGlvbiAoaW5kZXggOClcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjEgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggOSlcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMjIgQ29tcG9uZW50IGluIGNvbHVtbiAyLCByb3cgMiBwb3NpdGlvbiAoaW5kZXggMTApXG4gKiBAcGFyYW0ge051bWJlcn0gbTIzIENvbXBvbmVudCBpbiBjb2x1bW4gMiwgcm93IDMgcG9zaXRpb24gKGluZGV4IDExKVxuICogQHBhcmFtIHtOdW1iZXJ9IG0zMCBDb21wb25lbnQgaW4gY29sdW1uIDMsIHJvdyAwIHBvc2l0aW9uIChpbmRleCAxMilcbiAqIEBwYXJhbSB7TnVtYmVyfSBtMzEgQ29tcG9uZW50IGluIGNvbHVtbiAzLCByb3cgMSBwb3NpdGlvbiAoaW5kZXggMTMpXG4gKiBAcGFyYW0ge051bWJlcn0gbTMyIENvbXBvbmVudCBpbiBjb2x1bW4gMywgcm93IDIgcG9zaXRpb24gKGluZGV4IDE0KVxuICogQHBhcmFtIHtOdW1iZXJ9IG0zMyBDb21wb25lbnQgaW4gY29sdW1uIDMsIHJvdyAzIHBvc2l0aW9uIChpbmRleCAxNSlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0KG91dCwgbTAwLCBtMDEsIG0wMiwgbTAzLCBtMTAsIG0xMSwgbTEyLCBtMTMsIG0yMCwgbTIxLCBtMjIsIG0yMywgbTMwLCBtMzEsIG0zMiwgbTMzKSB7XG4gIG91dFswXSA9IG0wMDtcbiAgb3V0WzFdID0gbTAxO1xuICBvdXRbMl0gPSBtMDI7XG4gIG91dFszXSA9IG0wMztcbiAgb3V0WzRdID0gbTEwO1xuICBvdXRbNV0gPSBtMTE7XG4gIG91dFs2XSA9IG0xMjtcbiAgb3V0WzddID0gbTEzO1xuICBvdXRbOF0gPSBtMjA7XG4gIG91dFs5XSA9IG0yMTtcbiAgb3V0WzEwXSA9IG0yMjtcbiAgb3V0WzExXSA9IG0yMztcbiAgb3V0WzEyXSA9IG0zMDtcbiAgb3V0WzEzXSA9IG0zMTtcbiAgb3V0WzE0XSA9IG0zMjtcbiAgb3V0WzE1XSA9IG0zMztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU2V0IGEgbWF0NCB0byB0aGUgaWRlbnRpdHkgbWF0cml4XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHkob3V0KSB7XG4gIG91dFswXSA9IDE7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IDE7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDA7XG4gIG91dFs5XSA9IDA7XG4gIG91dFsxMF0gPSAxO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zcG9zZSB0aGUgdmFsdWVzIG9mIGEgbWF0NFxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgc291cmNlIG1hdHJpeFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2Uob3V0LCBhKSB7XG4gIC8vIElmIHdlIGFyZSB0cmFuc3Bvc2luZyBvdXJzZWx2ZXMgd2UgY2FuIHNraXAgYSBmZXcgc3RlcHMgYnV0IGhhdmUgdG8gY2FjaGUgc29tZSB2YWx1ZXNcbiAgaWYgKG91dCA9PT0gYSkge1xuICAgIHZhciBhMDEgPSBhWzFdLFxuICAgICAgICBhMDIgPSBhWzJdLFxuICAgICAgICBhMDMgPSBhWzNdO1xuICAgIHZhciBhMTIgPSBhWzZdLFxuICAgICAgICBhMTMgPSBhWzddO1xuICAgIHZhciBhMjMgPSBhWzExXTtcbiAgICBvdXRbMV0gPSBhWzRdO1xuICAgIG91dFsyXSA9IGFbOF07XG4gICAgb3V0WzNdID0gYVsxMl07XG4gICAgb3V0WzRdID0gYTAxO1xuICAgIG91dFs2XSA9IGFbOV07XG4gICAgb3V0WzddID0gYVsxM107XG4gICAgb3V0WzhdID0gYTAyO1xuICAgIG91dFs5XSA9IGExMjtcbiAgICBvdXRbMTFdID0gYVsxNF07XG4gICAgb3V0WzEyXSA9IGEwMztcbiAgICBvdXRbMTNdID0gYTEzO1xuICAgIG91dFsxNF0gPSBhMjM7XG4gIH0gZWxzZSB7XG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzRdO1xuICAgIG91dFsyXSA9IGFbOF07XG4gICAgb3V0WzNdID0gYVsxMl07XG4gICAgb3V0WzRdID0gYVsxXTtcbiAgICBvdXRbNV0gPSBhWzVdO1xuICAgIG91dFs2XSA9IGFbOV07XG4gICAgb3V0WzddID0gYVsxM107XG4gICAgb3V0WzhdID0gYVsyXTtcbiAgICBvdXRbOV0gPSBhWzZdO1xuICAgIG91dFsxMF0gPSBhWzEwXTtcbiAgICBvdXRbMTFdID0gYVsxNF07XG4gICAgb3V0WzEyXSA9IGFbM107XG4gICAgb3V0WzEzXSA9IGFbN107XG4gICAgb3V0WzE0XSA9IGFbMTFdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEludmVydHMgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBzb3VyY2UgbWF0cml4XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVydChvdXQsIGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdLFxuICAgICAgYTExID0gYVs1XSxcbiAgICAgIGExMiA9IGFbNl0sXG4gICAgICBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XSxcbiAgICAgIGEyMSA9IGFbOV0sXG4gICAgICBhMjIgPSBhWzEwXSxcbiAgICAgIGEyMyA9IGFbMTFdO1xuICB2YXIgYTMwID0gYVsxMl0sXG4gICAgICBhMzEgPSBhWzEzXSxcbiAgICAgIGEzMiA9IGFbMTRdLFxuICAgICAgYTMzID0gYVsxNV07XG4gIHZhciBiMDAgPSBhMDAgKiBhMTEgLSBhMDEgKiBhMTA7XG4gIHZhciBiMDEgPSBhMDAgKiBhMTIgLSBhMDIgKiBhMTA7XG4gIHZhciBiMDIgPSBhMDAgKiBhMTMgLSBhMDMgKiBhMTA7XG4gIHZhciBiMDMgPSBhMDEgKiBhMTIgLSBhMDIgKiBhMTE7XG4gIHZhciBiMDQgPSBhMDEgKiBhMTMgLSBhMDMgKiBhMTE7XG4gIHZhciBiMDUgPSBhMDIgKiBhMTMgLSBhMDMgKiBhMTI7XG4gIHZhciBiMDYgPSBhMjAgKiBhMzEgLSBhMjEgKiBhMzA7XG4gIHZhciBiMDcgPSBhMjAgKiBhMzIgLSBhMjIgKiBhMzA7XG4gIHZhciBiMDggPSBhMjAgKiBhMzMgLSBhMjMgKiBhMzA7XG4gIHZhciBiMDkgPSBhMjEgKiBhMzIgLSBhMjIgKiBhMzE7XG4gIHZhciBiMTAgPSBhMjEgKiBhMzMgLSBhMjMgKiBhMzE7XG4gIHZhciBiMTEgPSBhMjIgKiBhMzMgLSBhMjMgKiBhMzI7IC8vIENhbGN1bGF0ZSB0aGUgZGV0ZXJtaW5hbnRcblxuICB2YXIgZGV0ID0gYjAwICogYjExIC0gYjAxICogYjEwICsgYjAyICogYjA5ICsgYjAzICogYjA4IC0gYjA0ICogYjA3ICsgYjA1ICogYjA2O1xuXG4gIGlmICghZGV0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkZXQgPSAxLjAgLyBkZXQ7XG4gIG91dFswXSA9IChhMTEgKiBiMTEgLSBhMTIgKiBiMTAgKyBhMTMgKiBiMDkpICogZGV0O1xuICBvdXRbMV0gPSAoYTAyICogYjEwIC0gYTAxICogYjExIC0gYTAzICogYjA5KSAqIGRldDtcbiAgb3V0WzJdID0gKGEzMSAqIGIwNSAtIGEzMiAqIGIwNCArIGEzMyAqIGIwMykgKiBkZXQ7XG4gIG91dFszXSA9IChhMjIgKiBiMDQgLSBhMjEgKiBiMDUgLSBhMjMgKiBiMDMpICogZGV0O1xuICBvdXRbNF0gPSAoYTEyICogYjA4IC0gYTEwICogYjExIC0gYTEzICogYjA3KSAqIGRldDtcbiAgb3V0WzVdID0gKGEwMCAqIGIxMSAtIGEwMiAqIGIwOCArIGEwMyAqIGIwNykgKiBkZXQ7XG4gIG91dFs2XSA9IChhMzIgKiBiMDIgLSBhMzAgKiBiMDUgLSBhMzMgKiBiMDEpICogZGV0O1xuICBvdXRbN10gPSAoYTIwICogYjA1IC0gYTIyICogYjAyICsgYTIzICogYjAxKSAqIGRldDtcbiAgb3V0WzhdID0gKGExMCAqIGIxMCAtIGExMSAqIGIwOCArIGExMyAqIGIwNikgKiBkZXQ7XG4gIG91dFs5XSA9IChhMDEgKiBiMDggLSBhMDAgKiBiMTAgLSBhMDMgKiBiMDYpICogZGV0O1xuICBvdXRbMTBdID0gKGEzMCAqIGIwNCAtIGEzMSAqIGIwMiArIGEzMyAqIGIwMCkgKiBkZXQ7XG4gIG91dFsxMV0gPSAoYTIxICogYjAyIC0gYTIwICogYjA0IC0gYTIzICogYjAwKSAqIGRldDtcbiAgb3V0WzEyXSA9IChhMTEgKiBiMDcgLSBhMTAgKiBiMDkgLSBhMTIgKiBiMDYpICogZGV0O1xuICBvdXRbMTNdID0gKGEwMCAqIGIwOSAtIGEwMSAqIGIwNyArIGEwMiAqIGIwNikgKiBkZXQ7XG4gIG91dFsxNF0gPSAoYTMxICogYjAxIC0gYTMwICogYjAzIC0gYTMyICogYjAwKSAqIGRldDtcbiAgb3V0WzE1XSA9IChhMjAgKiBiMDMgLSBhMjEgKiBiMDEgKyBhMjIgKiBiMDApICogZGV0O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBhZGp1Z2F0ZSBvZiBhIG1hdDRcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRqb2ludChvdXQsIGEpIHtcbiAgdmFyIGEwMCA9IGFbMF0sXG4gICAgICBhMDEgPSBhWzFdLFxuICAgICAgYTAyID0gYVsyXSxcbiAgICAgIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdLFxuICAgICAgYTExID0gYVs1XSxcbiAgICAgIGExMiA9IGFbNl0sXG4gICAgICBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XSxcbiAgICAgIGEyMSA9IGFbOV0sXG4gICAgICBhMjIgPSBhWzEwXSxcbiAgICAgIGEyMyA9IGFbMTFdO1xuICB2YXIgYTMwID0gYVsxMl0sXG4gICAgICBhMzEgPSBhWzEzXSxcbiAgICAgIGEzMiA9IGFbMTRdLFxuICAgICAgYTMzID0gYVsxNV07XG4gIG91dFswXSA9IGExMSAqIChhMjIgKiBhMzMgLSBhMjMgKiBhMzIpIC0gYTIxICogKGExMiAqIGEzMyAtIGExMyAqIGEzMikgKyBhMzEgKiAoYTEyICogYTIzIC0gYTEzICogYTIyKTtcbiAgb3V0WzFdID0gLShhMDEgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMSAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMxICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMikpO1xuICBvdXRbMl0gPSBhMDEgKiAoYTEyICogYTMzIC0gYTEzICogYTMyKSAtIGExMSAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMxICogKGEwMiAqIGExMyAtIGEwMyAqIGExMik7XG4gIG91dFszXSA9IC0oYTAxICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikgLSBhMTEgKiAoYTAyICogYTIzIC0gYTAzICogYTIyKSArIGEyMSAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpKTtcbiAgb3V0WzRdID0gLShhMTAgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMCAqIChhMTIgKiBhMzMgLSBhMTMgKiBhMzIpICsgYTMwICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikpO1xuICBvdXRbNV0gPSBhMDAgKiAoYTIyICogYTMzIC0gYTIzICogYTMyKSAtIGEyMCAqIChhMDIgKiBhMzMgLSBhMDMgKiBhMzIpICsgYTMwICogKGEwMiAqIGEyMyAtIGEwMyAqIGEyMik7XG4gIG91dFs2XSA9IC0oYTAwICogKGExMiAqIGEzMyAtIGExMyAqIGEzMikgLSBhMTAgKiAoYTAyICogYTMzIC0gYTAzICogYTMyKSArIGEzMCAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpKTtcbiAgb3V0WzddID0gYTAwICogKGExMiAqIGEyMyAtIGExMyAqIGEyMikgLSBhMTAgKiAoYTAyICogYTIzIC0gYTAzICogYTIyKSArIGEyMCAqIChhMDIgKiBhMTMgLSBhMDMgKiBhMTIpO1xuICBvdXRbOF0gPSBhMTAgKiAoYTIxICogYTMzIC0gYTIzICogYTMxKSAtIGEyMCAqIChhMTEgKiBhMzMgLSBhMTMgKiBhMzEpICsgYTMwICogKGExMSAqIGEyMyAtIGExMyAqIGEyMSk7XG4gIG91dFs5XSA9IC0oYTAwICogKGEyMSAqIGEzMyAtIGEyMyAqIGEzMSkgLSBhMjAgKiAoYTAxICogYTMzIC0gYTAzICogYTMxKSArIGEzMCAqIChhMDEgKiBhMjMgLSBhMDMgKiBhMjEpKTtcbiAgb3V0WzEwXSA9IGEwMCAqIChhMTEgKiBhMzMgLSBhMTMgKiBhMzEpIC0gYTEwICogKGEwMSAqIGEzMyAtIGEwMyAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTEzIC0gYTAzICogYTExKTtcbiAgb3V0WzExXSA9IC0oYTAwICogKGExMSAqIGEyMyAtIGExMyAqIGEyMSkgLSBhMTAgKiAoYTAxICogYTIzIC0gYTAzICogYTIxKSArIGEyMCAqIChhMDEgKiBhMTMgLSBhMDMgKiBhMTEpKTtcbiAgb3V0WzEyXSA9IC0oYTEwICogKGEyMSAqIGEzMiAtIGEyMiAqIGEzMSkgLSBhMjAgKiAoYTExICogYTMyIC0gYTEyICogYTMxKSArIGEzMCAqIChhMTEgKiBhMjIgLSBhMTIgKiBhMjEpKTtcbiAgb3V0WzEzXSA9IGEwMCAqIChhMjEgKiBhMzIgLSBhMjIgKiBhMzEpIC0gYTIwICogKGEwMSAqIGEzMiAtIGEwMiAqIGEzMSkgKyBhMzAgKiAoYTAxICogYTIyIC0gYTAyICogYTIxKTtcbiAgb3V0WzE0XSA9IC0oYTAwICogKGExMSAqIGEzMiAtIGExMiAqIGEzMSkgLSBhMTAgKiAoYTAxICogYTMyIC0gYTAyICogYTMxKSArIGEzMCAqIChhMDEgKiBhMTIgLSBhMDIgKiBhMTEpKTtcbiAgb3V0WzE1XSA9IGEwMCAqIChhMTEgKiBhMjIgLSBhMTIgKiBhMjEpIC0gYTEwICogKGEwMSAqIGEyMiAtIGEwMiAqIGEyMSkgKyBhMjAgKiAoYTAxICogYTEyIC0gYTAyICogYTExKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZGV0ZXJtaW5hbnQgb2YgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIHNvdXJjZSBtYXRyaXhcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRldGVybWluYW50IG9mIGFcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGV0ZXJtaW5hbnQoYSkge1xuICB2YXIgYTAwID0gYVswXSxcbiAgICAgIGEwMSA9IGFbMV0sXG4gICAgICBhMDIgPSBhWzJdLFxuICAgICAgYTAzID0gYVszXTtcbiAgdmFyIGExMCA9IGFbNF0sXG4gICAgICBhMTEgPSBhWzVdLFxuICAgICAgYTEyID0gYVs2XSxcbiAgICAgIGExMyA9IGFbN107XG4gIHZhciBhMjAgPSBhWzhdLFxuICAgICAgYTIxID0gYVs5XSxcbiAgICAgIGEyMiA9IGFbMTBdLFxuICAgICAgYTIzID0gYVsxMV07XG4gIHZhciBhMzAgPSBhWzEyXSxcbiAgICAgIGEzMSA9IGFbMTNdLFxuICAgICAgYTMyID0gYVsxNF0sXG4gICAgICBhMzMgPSBhWzE1XTtcbiAgdmFyIGIwMCA9IGEwMCAqIGExMSAtIGEwMSAqIGExMDtcbiAgdmFyIGIwMSA9IGEwMCAqIGExMiAtIGEwMiAqIGExMDtcbiAgdmFyIGIwMiA9IGEwMCAqIGExMyAtIGEwMyAqIGExMDtcbiAgdmFyIGIwMyA9IGEwMSAqIGExMiAtIGEwMiAqIGExMTtcbiAgdmFyIGIwNCA9IGEwMSAqIGExMyAtIGEwMyAqIGExMTtcbiAgdmFyIGIwNSA9IGEwMiAqIGExMyAtIGEwMyAqIGExMjtcbiAgdmFyIGIwNiA9IGEyMCAqIGEzMSAtIGEyMSAqIGEzMDtcbiAgdmFyIGIwNyA9IGEyMCAqIGEzMiAtIGEyMiAqIGEzMDtcbiAgdmFyIGIwOCA9IGEyMCAqIGEzMyAtIGEyMyAqIGEzMDtcbiAgdmFyIGIwOSA9IGEyMSAqIGEzMiAtIGEyMiAqIGEzMTtcbiAgdmFyIGIxMCA9IGEyMSAqIGEzMyAtIGEyMyAqIGEzMTtcbiAgdmFyIGIxMSA9IGEyMiAqIGEzMyAtIGEyMyAqIGEzMjsgLy8gQ2FsY3VsYXRlIHRoZSBkZXRlcm1pbmFudFxuXG4gIHJldHVybiBiMDAgKiBiMTEgLSBiMDEgKiBiMTAgKyBiMDIgKiBiMDkgKyBiMDMgKiBiMDggLSBiMDQgKiBiMDcgKyBiMDUgKiBiMDY7XG59XG4vKipcbiAqIE11bHRpcGxpZXMgdHdvIG1hdDRzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIHZhciBhMDAgPSBhWzBdLFxuICAgICAgYTAxID0gYVsxXSxcbiAgICAgIGEwMiA9IGFbMl0sXG4gICAgICBhMDMgPSBhWzNdO1xuICB2YXIgYTEwID0gYVs0XSxcbiAgICAgIGExMSA9IGFbNV0sXG4gICAgICBhMTIgPSBhWzZdLFxuICAgICAgYTEzID0gYVs3XTtcbiAgdmFyIGEyMCA9IGFbOF0sXG4gICAgICBhMjEgPSBhWzldLFxuICAgICAgYTIyID0gYVsxMF0sXG4gICAgICBhMjMgPSBhWzExXTtcbiAgdmFyIGEzMCA9IGFbMTJdLFxuICAgICAgYTMxID0gYVsxM10sXG4gICAgICBhMzIgPSBhWzE0XSxcbiAgICAgIGEzMyA9IGFbMTVdOyAvLyBDYWNoZSBvbmx5IHRoZSBjdXJyZW50IGxpbmUgb2YgdGhlIHNlY29uZCBtYXRyaXhcblxuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdO1xuICBvdXRbMF0gPSBiMCAqIGEwMCArIGIxICogYTEwICsgYjIgKiBhMjAgKyBiMyAqIGEzMDtcbiAgb3V0WzFdID0gYjAgKiBhMDEgKyBiMSAqIGExMSArIGIyICogYTIxICsgYjMgKiBhMzE7XG4gIG91dFsyXSA9IGIwICogYTAyICsgYjEgKiBhMTIgKyBiMiAqIGEyMiArIGIzICogYTMyO1xuICBvdXRbM10gPSBiMCAqIGEwMyArIGIxICogYTEzICsgYjIgKiBhMjMgKyBiMyAqIGEzMztcbiAgYjAgPSBiWzRdO1xuICBiMSA9IGJbNV07XG4gIGIyID0gYls2XTtcbiAgYjMgPSBiWzddO1xuICBvdXRbNF0gPSBiMCAqIGEwMCArIGIxICogYTEwICsgYjIgKiBhMjAgKyBiMyAqIGEzMDtcbiAgb3V0WzVdID0gYjAgKiBhMDEgKyBiMSAqIGExMSArIGIyICogYTIxICsgYjMgKiBhMzE7XG4gIG91dFs2XSA9IGIwICogYTAyICsgYjEgKiBhMTIgKyBiMiAqIGEyMiArIGIzICogYTMyO1xuICBvdXRbN10gPSBiMCAqIGEwMyArIGIxICogYTEzICsgYjIgKiBhMjMgKyBiMyAqIGEzMztcbiAgYjAgPSBiWzhdO1xuICBiMSA9IGJbOV07XG4gIGIyID0gYlsxMF07XG4gIGIzID0gYlsxMV07XG4gIG91dFs4XSA9IGIwICogYTAwICsgYjEgKiBhMTAgKyBiMiAqIGEyMCArIGIzICogYTMwO1xuICBvdXRbOV0gPSBiMCAqIGEwMSArIGIxICogYTExICsgYjIgKiBhMjEgKyBiMyAqIGEzMTtcbiAgb3V0WzEwXSA9IGIwICogYTAyICsgYjEgKiBhMTIgKyBiMiAqIGEyMiArIGIzICogYTMyO1xuICBvdXRbMTFdID0gYjAgKiBhMDMgKyBiMSAqIGExMyArIGIyICogYTIzICsgYjMgKiBhMzM7XG4gIGIwID0gYlsxMl07XG4gIGIxID0gYlsxM107XG4gIGIyID0gYlsxNF07XG4gIGIzID0gYlsxNV07XG4gIG91dFsxMl0gPSBiMCAqIGEwMCArIGIxICogYTEwICsgYjIgKiBhMjAgKyBiMyAqIGEzMDtcbiAgb3V0WzEzXSA9IGIwICogYTAxICsgYjEgKiBhMTEgKyBiMiAqIGEyMSArIGIzICogYTMxO1xuICBvdXRbMTRdID0gYjAgKiBhMDIgKyBiMSAqIGExMiArIGIyICogYTIyICsgYjMgKiBhMzI7XG4gIG91dFsxNV0gPSBiMCAqIGEwMyArIGIxICogYTEzICsgYjIgKiBhMjMgKyBiMyAqIGEzMztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNsYXRlIGEgbWF0NCBieSB0aGUgZ2l2ZW4gdmVjdG9yXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBtYXRyaXggdG8gdHJhbnNsYXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiB2ZWN0b3IgdG8gdHJhbnNsYXRlIGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgdmFyIHggPSB2WzBdLFxuICAgICAgeSA9IHZbMV0sXG4gICAgICB6ID0gdlsyXTtcbiAgdmFyIGEwMCwgYTAxLCBhMDIsIGEwMztcbiAgdmFyIGExMCwgYTExLCBhMTIsIGExMztcbiAgdmFyIGEyMCwgYTIxLCBhMjIsIGEyMztcblxuICBpZiAoYSA9PT0gb3V0KSB7XG4gICAgb3V0WzEyXSA9IGFbMF0gKiB4ICsgYVs0XSAqIHkgKyBhWzhdICogeiArIGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzFdICogeCArIGFbNV0gKiB5ICsgYVs5XSAqIHogKyBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsyXSAqIHggKyBhWzZdICogeSArIGFbMTBdICogeiArIGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzNdICogeCArIGFbN10gKiB5ICsgYVsxMV0gKiB6ICsgYVsxNV07XG4gIH0gZWxzZSB7XG4gICAgYTAwID0gYVswXTtcbiAgICBhMDEgPSBhWzFdO1xuICAgIGEwMiA9IGFbMl07XG4gICAgYTAzID0gYVszXTtcbiAgICBhMTAgPSBhWzRdO1xuICAgIGExMSA9IGFbNV07XG4gICAgYTEyID0gYVs2XTtcbiAgICBhMTMgPSBhWzddO1xuICAgIGEyMCA9IGFbOF07XG4gICAgYTIxID0gYVs5XTtcbiAgICBhMjIgPSBhWzEwXTtcbiAgICBhMjMgPSBhWzExXTtcbiAgICBvdXRbMF0gPSBhMDA7XG4gICAgb3V0WzFdID0gYTAxO1xuICAgIG91dFsyXSA9IGEwMjtcbiAgICBvdXRbM10gPSBhMDM7XG4gICAgb3V0WzRdID0gYTEwO1xuICAgIG91dFs1XSA9IGExMTtcbiAgICBvdXRbNl0gPSBhMTI7XG4gICAgb3V0WzddID0gYTEzO1xuICAgIG91dFs4XSA9IGEyMDtcbiAgICBvdXRbOV0gPSBhMjE7XG4gICAgb3V0WzEwXSA9IGEyMjtcbiAgICBvdXRbMTFdID0gYTIzO1xuICAgIG91dFsxMl0gPSBhMDAgKiB4ICsgYTEwICogeSArIGEyMCAqIHogKyBhWzEyXTtcbiAgICBvdXRbMTNdID0gYTAxICogeCArIGExMSAqIHkgKyBhMjEgKiB6ICsgYVsxM107XG4gICAgb3V0WzE0XSA9IGEwMiAqIHggKyBhMTIgKiB5ICsgYTIyICogeiArIGFbMTRdO1xuICAgIG91dFsxNV0gPSBhMDMgKiB4ICsgYTEzICogeSArIGEyMyAqIHogKyBhWzE1XTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNjYWxlcyB0aGUgbWF0NCBieSB0aGUgZGltZW5zaW9ucyBpbiB0aGUgZ2l2ZW4gdmVjMyBub3QgdXNpbmcgdmVjdG9yaXphdGlvblxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHNjYWxlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiB0aGUgdmVjMyB0byBzY2FsZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKiovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShvdXQsIGEsIHYpIHtcbiAgdmFyIHggPSB2WzBdLFxuICAgICAgeSA9IHZbMV0sXG4gICAgICB6ID0gdlsyXTtcbiAgb3V0WzBdID0gYVswXSAqIHg7XG4gIG91dFsxXSA9IGFbMV0gKiB4O1xuICBvdXRbMl0gPSBhWzJdICogeDtcbiAgb3V0WzNdID0gYVszXSAqIHg7XG4gIG91dFs0XSA9IGFbNF0gKiB5O1xuICBvdXRbNV0gPSBhWzVdICogeTtcbiAgb3V0WzZdID0gYVs2XSAqIHk7XG4gIG91dFs3XSA9IGFbN10gKiB5O1xuICBvdXRbOF0gPSBhWzhdICogejtcbiAgb3V0WzldID0gYVs5XSAqIHo7XG4gIG91dFsxMF0gPSBhWzEwXSAqIHo7XG4gIG91dFsxMV0gPSBhWzExXSAqIHo7XG4gIG91dFsxMl0gPSBhWzEyXTtcbiAgb3V0WzEzXSA9IGFbMTNdO1xuICBvdXRbMTRdID0gYVsxNF07XG4gIG91dFsxNV0gPSBhWzE1XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIG1hdDQgYnkgdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgZ2l2ZW4gYXhpc1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBheGlzIHRoZSBheGlzIHRvIHJvdGF0ZSBhcm91bmRcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKG91dCwgYSwgcmFkLCBheGlzKSB7XG4gIHZhciB4ID0gYXhpc1swXSxcbiAgICAgIHkgPSBheGlzWzFdLFxuICAgICAgeiA9IGF4aXNbMl07XG4gIHZhciBsZW4gPSBNYXRoLmh5cG90KHgsIHksIHopO1xuICB2YXIgcywgYywgdDtcbiAgdmFyIGEwMCwgYTAxLCBhMDIsIGEwMztcbiAgdmFyIGExMCwgYTExLCBhMTIsIGExMztcbiAgdmFyIGEyMCwgYTIxLCBhMjIsIGEyMztcbiAgdmFyIGIwMCwgYjAxLCBiMDI7XG4gIHZhciBiMTAsIGIxMSwgYjEyO1xuICB2YXIgYjIwLCBiMjEsIGIyMjtcblxuICBpZiAobGVuIDwgZ2xNYXRyaXguRVBTSUxPTikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbGVuID0gMSAvIGxlbjtcbiAgeCAqPSBsZW47XG4gIHkgKj0gbGVuO1xuICB6ICo9IGxlbjtcbiAgcyA9IE1hdGguc2luKHJhZCk7XG4gIGMgPSBNYXRoLmNvcyhyYWQpO1xuICB0ID0gMSAtIGM7XG4gIGEwMCA9IGFbMF07XG4gIGEwMSA9IGFbMV07XG4gIGEwMiA9IGFbMl07XG4gIGEwMyA9IGFbM107XG4gIGExMCA9IGFbNF07XG4gIGExMSA9IGFbNV07XG4gIGExMiA9IGFbNl07XG4gIGExMyA9IGFbN107XG4gIGEyMCA9IGFbOF07XG4gIGEyMSA9IGFbOV07XG4gIGEyMiA9IGFbMTBdO1xuICBhMjMgPSBhWzExXTsgLy8gQ29uc3RydWN0IHRoZSBlbGVtZW50cyBvZiB0aGUgcm90YXRpb24gbWF0cml4XG5cbiAgYjAwID0geCAqIHggKiB0ICsgYztcbiAgYjAxID0geSAqIHggKiB0ICsgeiAqIHM7XG4gIGIwMiA9IHogKiB4ICogdCAtIHkgKiBzO1xuICBiMTAgPSB4ICogeSAqIHQgLSB6ICogcztcbiAgYjExID0geSAqIHkgKiB0ICsgYztcbiAgYjEyID0geiAqIHkgKiB0ICsgeCAqIHM7XG4gIGIyMCA9IHggKiB6ICogdCArIHkgKiBzO1xuICBiMjEgPSB5ICogeiAqIHQgLSB4ICogcztcbiAgYjIyID0geiAqIHogKiB0ICsgYzsgLy8gUGVyZm9ybSByb3RhdGlvbi1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuICBvdXRbMF0gPSBhMDAgKiBiMDAgKyBhMTAgKiBiMDEgKyBhMjAgKiBiMDI7XG4gIG91dFsxXSA9IGEwMSAqIGIwMCArIGExMSAqIGIwMSArIGEyMSAqIGIwMjtcbiAgb3V0WzJdID0gYTAyICogYjAwICsgYTEyICogYjAxICsgYTIyICogYjAyO1xuICBvdXRbM10gPSBhMDMgKiBiMDAgKyBhMTMgKiBiMDEgKyBhMjMgKiBiMDI7XG4gIG91dFs0XSA9IGEwMCAqIGIxMCArIGExMCAqIGIxMSArIGEyMCAqIGIxMjtcbiAgb3V0WzVdID0gYTAxICogYjEwICsgYTExICogYjExICsgYTIxICogYjEyO1xuICBvdXRbNl0gPSBhMDIgKiBiMTAgKyBhMTIgKiBiMTEgKyBhMjIgKiBiMTI7XG4gIG91dFs3XSA9IGEwMyAqIGIxMCArIGExMyAqIGIxMSArIGEyMyAqIGIxMjtcbiAgb3V0WzhdID0gYTAwICogYjIwICsgYTEwICogYjIxICsgYTIwICogYjIyO1xuICBvdXRbOV0gPSBhMDEgKiBiMjAgKyBhMTEgKiBiMjEgKyBhMjEgKiBiMjI7XG4gIG91dFsxMF0gPSBhMDIgKiBiMjAgKyBhMTIgKiBiMjEgKyBhMjIgKiBiMjI7XG4gIG91dFsxMV0gPSBhMDMgKiBiMjAgKyBhMTMgKiBiMjEgKyBhMjMgKiBiMjI7XG5cbiAgaWYgKGEgIT09IG91dCkge1xuICAgIC8vIElmIHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIGRpZmZlciwgY29weSB0aGUgdW5jaGFuZ2VkIGxhc3Qgcm93XG4gICAgb3V0WzEyXSA9IGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbMTVdO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIG1hdHJpeCBieSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBYIGF4aXNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIG1hdHJpeCB0byByb3RhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVgob3V0LCBhLCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7XG4gIHZhciBhMTAgPSBhWzRdO1xuICB2YXIgYTExID0gYVs1XTtcbiAgdmFyIGExMiA9IGFbNl07XG4gIHZhciBhMTMgPSBhWzddO1xuICB2YXIgYTIwID0gYVs4XTtcbiAgdmFyIGEyMSA9IGFbOV07XG4gIHZhciBhMjIgPSBhWzEwXTtcbiAgdmFyIGEyMyA9IGFbMTFdO1xuXG4gIGlmIChhICE9PSBvdXQpIHtcbiAgICAvLyBJZiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkaWZmZXIsIGNvcHkgdGhlIHVuY2hhbmdlZCByb3dzXG4gICAgb3V0WzBdID0gYVswXTtcbiAgICBvdXRbMV0gPSBhWzFdO1xuICAgIG91dFsyXSA9IGFbMl07XG4gICAgb3V0WzNdID0gYVszXTtcbiAgICBvdXRbMTJdID0gYVsxMl07XG4gICAgb3V0WzEzXSA9IGFbMTNdO1xuICAgIG91dFsxNF0gPSBhWzE0XTtcbiAgICBvdXRbMTVdID0gYVsxNV07XG4gIH0gLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG5cbiAgb3V0WzRdID0gYTEwICogYyArIGEyMCAqIHM7XG4gIG91dFs1XSA9IGExMSAqIGMgKyBhMjEgKiBzO1xuICBvdXRbNl0gPSBhMTIgKiBjICsgYTIyICogcztcbiAgb3V0WzddID0gYTEzICogYyArIGEyMyAqIHM7XG4gIG91dFs4XSA9IGEyMCAqIGMgLSBhMTAgKiBzO1xuICBvdXRbOV0gPSBhMjEgKiBjIC0gYTExICogcztcbiAgb3V0WzEwXSA9IGEyMiAqIGMgLSBhMTIgKiBzO1xuICBvdXRbMTFdID0gYTIzICogYyAtIGExMyAqIHM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBtYXRyaXggYnkgdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWSBheGlzXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBtYXRyaXggdG8gcm90YXRlXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVZKG91dCwgYSwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpO1xuICB2YXIgYTAwID0gYVswXTtcbiAgdmFyIGEwMSA9IGFbMV07XG4gIHZhciBhMDIgPSBhWzJdO1xuICB2YXIgYTAzID0gYVszXTtcbiAgdmFyIGEyMCA9IGFbOF07XG4gIHZhciBhMjEgPSBhWzldO1xuICB2YXIgYTIyID0gYVsxMF07XG4gIHZhciBhMjMgPSBhWzExXTtcblxuICBpZiAoYSAhPT0gb3V0KSB7XG4gICAgLy8gSWYgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gZGlmZmVyLCBjb3B5IHRoZSB1bmNoYW5nZWQgcm93c1xuICAgIG91dFs0XSA9IGFbNF07XG4gICAgb3V0WzVdID0gYVs1XTtcbiAgICBvdXRbNl0gPSBhWzZdO1xuICAgIG91dFs3XSA9IGFbN107XG4gICAgb3V0WzEyXSA9IGFbMTJdO1xuICAgIG91dFsxM10gPSBhWzEzXTtcbiAgICBvdXRbMTRdID0gYVsxNF07XG4gICAgb3V0WzE1XSA9IGFbMTVdO1xuICB9IC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuXG4gIG91dFswXSA9IGEwMCAqIGMgLSBhMjAgKiBzO1xuICBvdXRbMV0gPSBhMDEgKiBjIC0gYTIxICogcztcbiAgb3V0WzJdID0gYTAyICogYyAtIGEyMiAqIHM7XG4gIG91dFszXSA9IGEwMyAqIGMgLSBhMjMgKiBzO1xuICBvdXRbOF0gPSBhMDAgKiBzICsgYTIwICogYztcbiAgb3V0WzldID0gYTAxICogcyArIGEyMSAqIGM7XG4gIG91dFsxMF0gPSBhMDIgKiBzICsgYTIyICogYztcbiAgb3V0WzExXSA9IGEwMyAqIHMgKyBhMjMgKiBjO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgbWF0cml4IGJ5IHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFogYXhpc1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWihvdXQsIGEsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTtcbiAgdmFyIGEwMCA9IGFbMF07XG4gIHZhciBhMDEgPSBhWzFdO1xuICB2YXIgYTAyID0gYVsyXTtcbiAgdmFyIGEwMyA9IGFbM107XG4gIHZhciBhMTAgPSBhWzRdO1xuICB2YXIgYTExID0gYVs1XTtcbiAgdmFyIGExMiA9IGFbNl07XG4gIHZhciBhMTMgPSBhWzddO1xuXG4gIGlmIChhICE9PSBvdXQpIHtcbiAgICAvLyBJZiB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBkaWZmZXIsIGNvcHkgdGhlIHVuY2hhbmdlZCBsYXN0IHJvd1xuICAgIG91dFs4XSA9IGFbOF07XG4gICAgb3V0WzldID0gYVs5XTtcbiAgICBvdXRbMTBdID0gYVsxMF07XG4gICAgb3V0WzExXSA9IGFbMTFdO1xuICAgIG91dFsxMl0gPSBhWzEyXTtcbiAgICBvdXRbMTNdID0gYVsxM107XG4gICAgb3V0WzE0XSA9IGFbMTRdO1xuICAgIG91dFsxNV0gPSBhWzE1XTtcbiAgfSAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cblxuICBvdXRbMF0gPSBhMDAgKiBjICsgYTEwICogcztcbiAgb3V0WzFdID0gYTAxICogYyArIGExMSAqIHM7XG4gIG91dFsyXSA9IGEwMiAqIGMgKyBhMTIgKiBzO1xuICBvdXRbM10gPSBhMDMgKiBjICsgYTEzICogcztcbiAgb3V0WzRdID0gYTEwICogYyAtIGEwMCAqIHM7XG4gIG91dFs1XSA9IGExMSAqIGMgLSBhMDEgKiBzO1xuICBvdXRbNl0gPSBhMTIgKiBjIC0gYTAyICogcztcbiAgb3V0WzddID0gYTEzICogYyAtIGEwMyAqIHM7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHZlY3RvciB0cmFuc2xhdGlvblxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgZGVzdCwgdmVjKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVRyYW5zbGF0aW9uKG91dCwgdikge1xuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAxO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gMTtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSB2WzBdO1xuICBvdXRbMTNdID0gdlsxXTtcbiAgb3V0WzE0XSA9IHZbMl07XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSB2ZWN0b3Igc2NhbGluZ1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC5zY2FsZShkZXN0LCBkZXN0LCB2ZWMpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB2IFNjYWxpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21TY2FsaW5nKG91dCwgdikge1xuICBvdXRbMF0gPSB2WzBdO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSB2WzFdO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gdlsyXTtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBnaXZlbiBhbmdsZSBhcm91bmQgYSBnaXZlbiBheGlzXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnJvdGF0ZShkZXN0LCBkZXN0LCByYWQsIGF4aXMpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYXhpcyB0aGUgYXhpcyB0byByb3RhdGUgYXJvdW5kXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Sb3RhdGlvbihvdXQsIHJhZCwgYXhpcykge1xuICB2YXIgeCA9IGF4aXNbMF0sXG4gICAgICB5ID0gYXhpc1sxXSxcbiAgICAgIHogPSBheGlzWzJdO1xuICB2YXIgbGVuID0gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbiAgdmFyIHMsIGMsIHQ7XG5cbiAgaWYgKGxlbiA8IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxlbiA9IDEgLyBsZW47XG4gIHggKj0gbGVuO1xuICB5ICo9IGxlbjtcbiAgeiAqPSBsZW47XG4gIHMgPSBNYXRoLnNpbihyYWQpO1xuICBjID0gTWF0aC5jb3MocmFkKTtcbiAgdCA9IDEgLSBjOyAvLyBQZXJmb3JtIHJvdGF0aW9uLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG4gIG91dFswXSA9IHggKiB4ICogdCArIGM7XG4gIG91dFsxXSA9IHkgKiB4ICogdCArIHogKiBzO1xuICBvdXRbMl0gPSB6ICogeCAqIHQgLSB5ICogcztcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0geCAqIHkgKiB0IC0geiAqIHM7XG4gIG91dFs1XSA9IHkgKiB5ICogdCArIGM7XG4gIG91dFs2XSA9IHogKiB5ICogdCArIHggKiBzO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSB4ICogeiAqIHQgKyB5ICogcztcbiAgb3V0WzldID0geSAqIHogKiB0IC0geCAqIHM7XG4gIG91dFsxMF0gPSB6ICogeiAqIHQgKyBjO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSB0aGUgZ2l2ZW4gYW5nbGUgYXJvdW5kIHRoZSBYIGF4aXNcbiAqIFRoaXMgaXMgZXF1aXZhbGVudCB0byAoYnV0IG11Y2ggZmFzdGVyIHRoYW4pOlxuICpcbiAqICAgICBtYXQ0LmlkZW50aXR5KGRlc3QpO1xuICogICAgIG1hdDQucm90YXRlWChkZXN0LCBkZXN0LCByYWQpO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgdGhlIGFuZ2xlIHRvIHJvdGF0ZSB0aGUgbWF0cml4IGJ5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21YUm90YXRpb24ob3V0LCByYWQpIHtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICB2YXIgYyA9IE1hdGguY29zKHJhZCk7IC8vIFBlcmZvcm0gYXhpcy1zcGVjaWZpYyBtYXRyaXggbXVsdGlwbGljYXRpb25cblxuICBvdXRbMF0gPSAxO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSBjO1xuICBvdXRbNl0gPSBzO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAtcztcbiAgb3V0WzEwXSA9IGM7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gMDtcbiAgb3V0WzEzXSA9IDA7XG4gIG91dFsxNF0gPSAwO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIHRoZSBnaXZlbiBhbmdsZSBhcm91bmQgdGhlIFkgYXhpc1xuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC5yb3RhdGVZKGRlc3QsIGRlc3QsIHJhZCk7XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgdG8gcm90YXRlIHRoZSBtYXRyaXggYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVlSb3RhdGlvbihvdXQsIHJhZCkge1xuICB2YXIgcyA9IE1hdGguc2luKHJhZCk7XG4gIHZhciBjID0gTWF0aC5jb3MocmFkKTsgLy8gUGVyZm9ybSBheGlzLXNwZWNpZmljIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuXG4gIG91dFswXSA9IGM7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IC1zO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAxO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSBzO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gYztcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gdGhlIGdpdmVuIGFuZ2xlIGFyb3VuZCB0aGUgWiBheGlzXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnJvdGF0ZVooZGVzdCwgZGVzdCwgcmFkKTtcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIHRoZSBhbmdsZSB0byByb3RhdGUgdGhlIG1hdHJpeCBieVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tWlJvdGF0aW9uKG91dCwgcmFkKSB7XG4gIHZhciBzID0gTWF0aC5zaW4ocmFkKTtcbiAgdmFyIGMgPSBNYXRoLmNvcyhyYWQpOyAvLyBQZXJmb3JtIGF4aXMtc3BlY2lmaWMgbWF0cml4IG11bHRpcGxpY2F0aW9uXG5cbiAgb3V0WzBdID0gYztcbiAgb3V0WzFdID0gcztcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gLXM7XG4gIG91dFs1XSA9IGM7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDA7XG4gIG91dFs5XSA9IDA7XG4gIG91dFsxMF0gPSAxO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gMDtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZnJvbSBhIHF1YXRlcm5pb24gcm90YXRpb24gYW5kIHZlY3RvciB0cmFuc2xhdGlvblxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgdmVjKTtcbiAqICAgICBsZXQgcXVhdE1hdCA9IG1hdDQuY3JlYXRlKCk7XG4gKiAgICAgcXVhdDQudG9NYXQ0KHF1YXQsIHF1YXRNYXQpO1xuICogICAgIG1hdDQubXVsdGlwbHkoZGVzdCwgcXVhdE1hdCk7XG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtxdWF0NH0gcSBSb3RhdGlvbiBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdiBUcmFuc2xhdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24ob3V0LCBxLCB2KSB7XG4gIC8vIFF1YXRlcm5pb24gbWF0aFxuICB2YXIgeCA9IHFbMF0sXG4gICAgICB5ID0gcVsxXSxcbiAgICAgIHogPSBxWzJdLFxuICAgICAgdyA9IHFbM107XG4gIHZhciB4MiA9IHggKyB4O1xuICB2YXIgeTIgPSB5ICsgeTtcbiAgdmFyIHoyID0geiArIHo7XG4gIHZhciB4eCA9IHggKiB4MjtcbiAgdmFyIHh5ID0geCAqIHkyO1xuICB2YXIgeHogPSB4ICogejI7XG4gIHZhciB5eSA9IHkgKiB5MjtcbiAgdmFyIHl6ID0geSAqIHoyO1xuICB2YXIgenogPSB6ICogejI7XG4gIHZhciB3eCA9IHcgKiB4MjtcbiAgdmFyIHd5ID0gdyAqIHkyO1xuICB2YXIgd3ogPSB3ICogejI7XG4gIG91dFswXSA9IDEgLSAoeXkgKyB6eik7XG4gIG91dFsxXSA9IHh5ICsgd3o7XG4gIG91dFsyXSA9IHh6IC0gd3k7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IHh5IC0gd3o7XG4gIG91dFs1XSA9IDEgLSAoeHggKyB6eik7XG4gIG91dFs2XSA9IHl6ICsgd3g7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IHh6ICsgd3k7XG4gIG91dFs5XSA9IHl6IC0gd3g7XG4gIG91dFsxMF0gPSAxIC0gKHh4ICsgeXkpO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IHZbMF07XG4gIG91dFsxM10gPSB2WzFdO1xuICBvdXRbMTRdID0gdlsyXTtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbWF0NCBmcm9tIGEgZHVhbCBxdWF0LlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IE1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seVF1YXQyfSBhIER1YWwgUXVhdGVybmlvblxuICogQHJldHVybnMge21hdDR9IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVF1YXQyKG91dCwgYSkge1xuICB2YXIgdHJhbnNsYXRpb24gPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcbiAgdmFyIGJ4ID0gLWFbMF0sXG4gICAgICBieSA9IC1hWzFdLFxuICAgICAgYnogPSAtYVsyXSxcbiAgICAgIGJ3ID0gYVszXSxcbiAgICAgIGF4ID0gYVs0XSxcbiAgICAgIGF5ID0gYVs1XSxcbiAgICAgIGF6ID0gYVs2XSxcbiAgICAgIGF3ID0gYVs3XTtcbiAgdmFyIG1hZ25pdHVkZSA9IGJ4ICogYnggKyBieSAqIGJ5ICsgYnogKiBieiArIGJ3ICogYnc7IC8vT25seSBzY2FsZSBpZiBpdCBtYWtlcyBzZW5zZVxuXG4gIGlmIChtYWduaXR1ZGUgPiAwKSB7XG4gICAgdHJhbnNsYXRpb25bMF0gPSAoYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieSkgKiAyIC8gbWFnbml0dWRlO1xuICAgIHRyYW5zbGF0aW9uWzFdID0gKGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnopICogMiAvIG1hZ25pdHVkZTtcbiAgICB0cmFuc2xhdGlvblsyXSA9IChheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4KSAqIDIgLyBtYWduaXR1ZGU7XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNsYXRpb25bMF0gPSAoYXggKiBidyArIGF3ICogYnggKyBheSAqIGJ6IC0gYXogKiBieSkgKiAyO1xuICAgIHRyYW5zbGF0aW9uWzFdID0gKGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYnopICogMjtcbiAgICB0cmFuc2xhdGlvblsyXSA9IChheiAqIGJ3ICsgYXcgKiBieiArIGF4ICogYnkgLSBheSAqIGJ4KSAqIDI7XG4gIH1cblxuICBmcm9tUm90YXRpb25UcmFuc2xhdGlvbihvdXQsIGEsIHRyYW5zbGF0aW9uKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgdHJhbnNsYXRpb24gdmVjdG9yIGNvbXBvbmVudCBvZiBhIHRyYW5zZm9ybWF0aW9uXG4gKiAgbWF0cml4LiBJZiBhIG1hdHJpeCBpcyBidWlsdCB3aXRoIGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uLFxuICogIHRoZSByZXR1cm5lZCB2ZWN0b3Igd2lsbCBiZSB0aGUgc2FtZSBhcyB0aGUgdHJhbnNsYXRpb24gdmVjdG9yXG4gKiAgb3JpZ2luYWxseSBzdXBwbGllZC5cbiAqIEBwYXJhbSAge3ZlYzN9IG91dCBWZWN0b3IgdG8gcmVjZWl2ZSB0cmFuc2xhdGlvbiBjb21wb25lbnRcbiAqIEBwYXJhbSAge1JlYWRvbmx5TWF0NH0gbWF0IE1hdHJpeCB0byBiZSBkZWNvbXBvc2VkIChpbnB1dClcbiAqIEByZXR1cm4ge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2xhdGlvbihvdXQsIG1hdCkge1xuICBvdXRbMF0gPSBtYXRbMTJdO1xuICBvdXRbMV0gPSBtYXRbMTNdO1xuICBvdXRbMl0gPSBtYXRbMTRdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzY2FsaW5nIGZhY3RvciBjb21wb25lbnQgb2YgYSB0cmFuc2Zvcm1hdGlvblxuICogIG1hdHJpeC4gSWYgYSBtYXRyaXggaXMgYnVpbHQgd2l0aCBmcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlXG4gKiAgd2l0aCBhIG5vcm1hbGl6ZWQgUXVhdGVybmlvbiBwYXJhbXRlciwgdGhlIHJldHVybmVkIHZlY3RvciB3aWxsIGJlXG4gKiAgdGhlIHNhbWUgYXMgdGhlIHNjYWxpbmcgdmVjdG9yXG4gKiAgb3JpZ2luYWxseSBzdXBwbGllZC5cbiAqIEBwYXJhbSAge3ZlYzN9IG91dCBWZWN0b3IgdG8gcmVjZWl2ZSBzY2FsaW5nIGZhY3RvciBjb21wb25lbnRcbiAqIEBwYXJhbSAge1JlYWRvbmx5TWF0NH0gbWF0IE1hdHJpeCB0byBiZSBkZWNvbXBvc2VkIChpbnB1dClcbiAqIEByZXR1cm4ge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY2FsaW5nKG91dCwgbWF0KSB7XG4gIHZhciBtMTEgPSBtYXRbMF07XG4gIHZhciBtMTIgPSBtYXRbMV07XG4gIHZhciBtMTMgPSBtYXRbMl07XG4gIHZhciBtMjEgPSBtYXRbNF07XG4gIHZhciBtMjIgPSBtYXRbNV07XG4gIHZhciBtMjMgPSBtYXRbNl07XG4gIHZhciBtMzEgPSBtYXRbOF07XG4gIHZhciBtMzIgPSBtYXRbOV07XG4gIHZhciBtMzMgPSBtYXRbMTBdO1xuICBvdXRbMF0gPSBNYXRoLmh5cG90KG0xMSwgbTEyLCBtMTMpO1xuICBvdXRbMV0gPSBNYXRoLmh5cG90KG0yMSwgbTIyLCBtMjMpO1xuICBvdXRbMl0gPSBNYXRoLmh5cG90KG0zMSwgbTMyLCBtMzMpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgcXVhdGVybmlvbiByZXByZXNlbnRpbmcgdGhlIHJvdGF0aW9uYWwgY29tcG9uZW50XG4gKiAgb2YgYSB0cmFuc2Zvcm1hdGlvbiBtYXRyaXguIElmIGEgbWF0cml4IGlzIGJ1aWx0IHdpdGhcbiAqICBmcm9tUm90YXRpb25UcmFuc2xhdGlvbiwgdGhlIHJldHVybmVkIHF1YXRlcm5pb24gd2lsbCBiZSB0aGVcbiAqICBzYW1lIGFzIHRoZSBxdWF0ZXJuaW9uIG9yaWdpbmFsbHkgc3VwcGxpZWQuXG4gKiBAcGFyYW0ge3F1YXR9IG91dCBRdWF0ZXJuaW9uIHRvIHJlY2VpdmUgdGhlIHJvdGF0aW9uIGNvbXBvbmVudFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IG1hdCBNYXRyaXggdG8gYmUgZGVjb21wb3NlZCAoaW5wdXQpXG4gKiBAcmV0dXJuIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Um90YXRpb24ob3V0LCBtYXQpIHtcbiAgdmFyIHNjYWxpbmcgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcbiAgZ2V0U2NhbGluZyhzY2FsaW5nLCBtYXQpO1xuICB2YXIgaXMxID0gMSAvIHNjYWxpbmdbMF07XG4gIHZhciBpczIgPSAxIC8gc2NhbGluZ1sxXTtcbiAgdmFyIGlzMyA9IDEgLyBzY2FsaW5nWzJdO1xuICB2YXIgc20xMSA9IG1hdFswXSAqIGlzMTtcbiAgdmFyIHNtMTIgPSBtYXRbMV0gKiBpczI7XG4gIHZhciBzbTEzID0gbWF0WzJdICogaXMzO1xuICB2YXIgc20yMSA9IG1hdFs0XSAqIGlzMTtcbiAgdmFyIHNtMjIgPSBtYXRbNV0gKiBpczI7XG4gIHZhciBzbTIzID0gbWF0WzZdICogaXMzO1xuICB2YXIgc20zMSA9IG1hdFs4XSAqIGlzMTtcbiAgdmFyIHNtMzIgPSBtYXRbOV0gKiBpczI7XG4gIHZhciBzbTMzID0gbWF0WzEwXSAqIGlzMztcbiAgdmFyIHRyYWNlID0gc20xMSArIHNtMjIgKyBzbTMzO1xuICB2YXIgUyA9IDA7XG5cbiAgaWYgKHRyYWNlID4gMCkge1xuICAgIFMgPSBNYXRoLnNxcnQodHJhY2UgKyAxLjApICogMjtcbiAgICBvdXRbM10gPSAwLjI1ICogUztcbiAgICBvdXRbMF0gPSAoc20yMyAtIHNtMzIpIC8gUztcbiAgICBvdXRbMV0gPSAoc20zMSAtIHNtMTMpIC8gUztcbiAgICBvdXRbMl0gPSAoc20xMiAtIHNtMjEpIC8gUztcbiAgfSBlbHNlIGlmIChzbTExID4gc20yMiAmJiBzbTExID4gc20zMykge1xuICAgIFMgPSBNYXRoLnNxcnQoMS4wICsgc20xMSAtIHNtMjIgLSBzbTMzKSAqIDI7XG4gICAgb3V0WzNdID0gKHNtMjMgLSBzbTMyKSAvIFM7XG4gICAgb3V0WzBdID0gMC4yNSAqIFM7XG4gICAgb3V0WzFdID0gKHNtMTIgKyBzbTIxKSAvIFM7XG4gICAgb3V0WzJdID0gKHNtMzEgKyBzbTEzKSAvIFM7XG4gIH0gZWxzZSBpZiAoc20yMiA+IHNtMzMpIHtcbiAgICBTID0gTWF0aC5zcXJ0KDEuMCArIHNtMjIgLSBzbTExIC0gc20zMykgKiAyO1xuICAgIG91dFszXSA9IChzbTMxIC0gc20xMykgLyBTO1xuICAgIG91dFswXSA9IChzbTEyICsgc20yMSkgLyBTO1xuICAgIG91dFsxXSA9IDAuMjUgKiBTO1xuICAgIG91dFsyXSA9IChzbTIzICsgc20zMikgLyBTO1xuICB9IGVsc2Uge1xuICAgIFMgPSBNYXRoLnNxcnQoMS4wICsgc20zMyAtIHNtMTEgLSBzbTIyKSAqIDI7XG4gICAgb3V0WzNdID0gKHNtMTIgLSBzbTIxKSAvIFM7XG4gICAgb3V0WzBdID0gKHNtMzEgKyBzbTEzKSAvIFM7XG4gICAgb3V0WzFdID0gKHNtMjMgKyBzbTMyKSAvIFM7XG4gICAgb3V0WzJdID0gMC4yNSAqIFM7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbWF0cml4IGZyb20gYSBxdWF0ZXJuaW9uIHJvdGF0aW9uLCB2ZWN0b3IgdHJhbnNsYXRpb24gYW5kIHZlY3RvciBzY2FsZVxuICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIChidXQgbXVjaCBmYXN0ZXIgdGhhbik6XG4gKlxuICogICAgIG1hdDQuaWRlbnRpdHkoZGVzdCk7XG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgdmVjKTtcbiAqICAgICBsZXQgcXVhdE1hdCA9IG1hdDQuY3JlYXRlKCk7XG4gKiAgICAgcXVhdDQudG9NYXQ0KHF1YXQsIHF1YXRNYXQpO1xuICogICAgIG1hdDQubXVsdGlwbHkoZGVzdCwgcXVhdE1hdCk7XG4gKiAgICAgbWF0NC5zY2FsZShkZXN0LCBzY2FsZSlcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge3F1YXQ0fSBxIFJvdGF0aW9uIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB2IFRyYW5zbGF0aW9uIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHMgU2NhbGluZyB2ZWN0b3JcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZShvdXQsIHEsIHYsIHMpIHtcbiAgLy8gUXVhdGVybmlvbiBtYXRoXG4gIHZhciB4ID0gcVswXSxcbiAgICAgIHkgPSBxWzFdLFxuICAgICAgeiA9IHFbMl0sXG4gICAgICB3ID0gcVszXTtcbiAgdmFyIHgyID0geCArIHg7XG4gIHZhciB5MiA9IHkgKyB5O1xuICB2YXIgejIgPSB6ICsgejtcbiAgdmFyIHh4ID0geCAqIHgyO1xuICB2YXIgeHkgPSB4ICogeTI7XG4gIHZhciB4eiA9IHggKiB6MjtcbiAgdmFyIHl5ID0geSAqIHkyO1xuICB2YXIgeXogPSB5ICogejI7XG4gIHZhciB6eiA9IHogKiB6MjtcbiAgdmFyIHd4ID0gdyAqIHgyO1xuICB2YXIgd3kgPSB3ICogeTI7XG4gIHZhciB3eiA9IHcgKiB6MjtcbiAgdmFyIHN4ID0gc1swXTtcbiAgdmFyIHN5ID0gc1sxXTtcbiAgdmFyIHN6ID0gc1syXTtcbiAgb3V0WzBdID0gKDEgLSAoeXkgKyB6eikpICogc3g7XG4gIG91dFsxXSA9ICh4eSArIHd6KSAqIHN4O1xuICBvdXRbMl0gPSAoeHogLSB3eSkgKiBzeDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gKHh5IC0gd3opICogc3k7XG4gIG91dFs1XSA9ICgxIC0gKHh4ICsgenopKSAqIHN5O1xuICBvdXRbNl0gPSAoeXogKyB3eCkgKiBzeTtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gKHh6ICsgd3kpICogc3o7XG4gIG91dFs5XSA9ICh5eiAtIHd4KSAqIHN6O1xuICBvdXRbMTBdID0gKDEgLSAoeHggKyB5eSkpICogc3o7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gdlswXTtcbiAgb3V0WzEzXSA9IHZbMV07XG4gIG91dFsxNF0gPSB2WzJdO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG1hdHJpeCBmcm9tIGEgcXVhdGVybmlvbiByb3RhdGlvbiwgdmVjdG9yIHRyYW5zbGF0aW9uIGFuZCB2ZWN0b3Igc2NhbGUsIHJvdGF0aW5nIGFuZCBzY2FsaW5nIGFyb3VuZCB0aGUgZ2l2ZW4gb3JpZ2luXG4gKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gKGJ1dCBtdWNoIGZhc3RlciB0aGFuKTpcbiAqXG4gKiAgICAgbWF0NC5pZGVudGl0eShkZXN0KTtcbiAqICAgICBtYXQ0LnRyYW5zbGF0ZShkZXN0LCB2ZWMpO1xuICogICAgIG1hdDQudHJhbnNsYXRlKGRlc3QsIG9yaWdpbik7XG4gKiAgICAgbGV0IHF1YXRNYXQgPSBtYXQ0LmNyZWF0ZSgpO1xuICogICAgIHF1YXQ0LnRvTWF0NChxdWF0LCBxdWF0TWF0KTtcbiAqICAgICBtYXQ0Lm11bHRpcGx5KGRlc3QsIHF1YXRNYXQpO1xuICogICAgIG1hdDQuc2NhbGUoZGVzdCwgc2NhbGUpXG4gKiAgICAgbWF0NC50cmFuc2xhdGUoZGVzdCwgbmVnYXRpdmVPcmlnaW4pO1xuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7cXVhdDR9IHEgUm90YXRpb24gcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHYgVHJhbnNsYXRpb24gdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gcyBTY2FsaW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IG8gVGhlIG9yaWdpbiB2ZWN0b3IgYXJvdW5kIHdoaWNoIHRvIHNjYWxlIGFuZCByb3RhdGVcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZU9yaWdpbihvdXQsIHEsIHYsIHMsIG8pIHtcbiAgLy8gUXVhdGVybmlvbiBtYXRoXG4gIHZhciB4ID0gcVswXSxcbiAgICAgIHkgPSBxWzFdLFxuICAgICAgeiA9IHFbMl0sXG4gICAgICB3ID0gcVszXTtcbiAgdmFyIHgyID0geCArIHg7XG4gIHZhciB5MiA9IHkgKyB5O1xuICB2YXIgejIgPSB6ICsgejtcbiAgdmFyIHh4ID0geCAqIHgyO1xuICB2YXIgeHkgPSB4ICogeTI7XG4gIHZhciB4eiA9IHggKiB6MjtcbiAgdmFyIHl5ID0geSAqIHkyO1xuICB2YXIgeXogPSB5ICogejI7XG4gIHZhciB6eiA9IHogKiB6MjtcbiAgdmFyIHd4ID0gdyAqIHgyO1xuICB2YXIgd3kgPSB3ICogeTI7XG4gIHZhciB3eiA9IHcgKiB6MjtcbiAgdmFyIHN4ID0gc1swXTtcbiAgdmFyIHN5ID0gc1sxXTtcbiAgdmFyIHN6ID0gc1syXTtcbiAgdmFyIG94ID0gb1swXTtcbiAgdmFyIG95ID0gb1sxXTtcbiAgdmFyIG96ID0gb1syXTtcbiAgdmFyIG91dDAgPSAoMSAtICh5eSArIHp6KSkgKiBzeDtcbiAgdmFyIG91dDEgPSAoeHkgKyB3eikgKiBzeDtcbiAgdmFyIG91dDIgPSAoeHogLSB3eSkgKiBzeDtcbiAgdmFyIG91dDQgPSAoeHkgLSB3eikgKiBzeTtcbiAgdmFyIG91dDUgPSAoMSAtICh4eCArIHp6KSkgKiBzeTtcbiAgdmFyIG91dDYgPSAoeXogKyB3eCkgKiBzeTtcbiAgdmFyIG91dDggPSAoeHogKyB3eSkgKiBzejtcbiAgdmFyIG91dDkgPSAoeXogLSB3eCkgKiBzejtcbiAgdmFyIG91dDEwID0gKDEgLSAoeHggKyB5eSkpICogc3o7XG4gIG91dFswXSA9IG91dDA7XG4gIG91dFsxXSA9IG91dDE7XG4gIG91dFsyXSA9IG91dDI7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IG91dDQ7XG4gIG91dFs1XSA9IG91dDU7XG4gIG91dFs2XSA9IG91dDY7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IG91dDg7XG4gIG91dFs5XSA9IG91dDk7XG4gIG91dFsxMF0gPSBvdXQxMDtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSB2WzBdICsgb3ggLSAob3V0MCAqIG94ICsgb3V0NCAqIG95ICsgb3V0OCAqIG96KTtcbiAgb3V0WzEzXSA9IHZbMV0gKyBveSAtIChvdXQxICogb3ggKyBvdXQ1ICogb3kgKyBvdXQ5ICogb3opO1xuICBvdXRbMTRdID0gdlsyXSArIG96IC0gKG91dDIgKiBveCArIG91dDYgKiBveSArIG91dDEwICogb3opO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyBhIDR4NCBtYXRyaXggZnJvbSB0aGUgZ2l2ZW4gcXVhdGVybmlvblxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBxIFF1YXRlcm5pb24gdG8gY3JlYXRlIG1hdHJpeCBmcm9tXG4gKlxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tUXVhdChvdXQsIHEpIHtcbiAgdmFyIHggPSBxWzBdLFxuICAgICAgeSA9IHFbMV0sXG4gICAgICB6ID0gcVsyXSxcbiAgICAgIHcgPSBxWzNdO1xuICB2YXIgeDIgPSB4ICsgeDtcbiAgdmFyIHkyID0geSArIHk7XG4gIHZhciB6MiA9IHogKyB6O1xuICB2YXIgeHggPSB4ICogeDI7XG4gIHZhciB5eCA9IHkgKiB4MjtcbiAgdmFyIHl5ID0geSAqIHkyO1xuICB2YXIgenggPSB6ICogeDI7XG4gIHZhciB6eSA9IHogKiB5MjtcbiAgdmFyIHp6ID0geiAqIHoyO1xuICB2YXIgd3ggPSB3ICogeDI7XG4gIHZhciB3eSA9IHcgKiB5MjtcbiAgdmFyIHd6ID0gdyAqIHoyO1xuICBvdXRbMF0gPSAxIC0geXkgLSB6ejtcbiAgb3V0WzFdID0geXggKyB3ejtcbiAgb3V0WzJdID0genggLSB3eTtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0geXggLSB3ejtcbiAgb3V0WzVdID0gMSAtIHh4IC0geno7XG4gIG91dFs2XSA9IHp5ICsgd3g7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IHp4ICsgd3k7XG4gIG91dFs5XSA9IHp5IC0gd3g7XG4gIG91dFsxMF0gPSAxIC0geHggLSB5eTtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE0XSA9IDA7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBmcnVzdHVtIG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBib3VuZHNcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXG4gKiBAcGFyYW0ge051bWJlcn0gbGVmdCBMZWZ0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge051bWJlcn0gcmlnaHQgUmlnaHQgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7TnVtYmVyfSBib3R0b20gQm90dG9tIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge051bWJlcn0gdG9wIFRvcCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtOdW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtOdW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJ1c3R1bShvdXQsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgbmVhciwgZmFyKSB7XG4gIHZhciBybCA9IDEgLyAocmlnaHQgLSBsZWZ0KTtcbiAgdmFyIHRiID0gMSAvICh0b3AgLSBib3R0b20pO1xuICB2YXIgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICBvdXRbMF0gPSBuZWFyICogMiAqIHJsO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSBuZWFyICogMiAqIHRiO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAocmlnaHQgKyBsZWZ0KSAqIHJsO1xuICBvdXRbOV0gPSAodG9wICsgYm90dG9tKSAqIHRiO1xuICBvdXRbMTBdID0gKGZhciArIG5lYXIpICogbmY7XG4gIG91dFsxMV0gPSAtMTtcbiAgb3V0WzEyXSA9IDA7XG4gIG91dFsxM10gPSAwO1xuICBvdXRbMTRdID0gZmFyICogbmVhciAqIDIgKiBuZjtcbiAgb3V0WzE1XSA9IDA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIHBlcnNwZWN0aXZlIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGJvdW5kcy5cbiAqIFRoZSBuZWFyL2ZhciBjbGlwIHBsYW5lcyBjb3JyZXNwb25kIHRvIGEgbm9ybWFsaXplZCBkZXZpY2UgY29vcmRpbmF0ZSBaIHJhbmdlIG9mIFstMSwgMV0sXG4gKiB3aGljaCBtYXRjaGVzIFdlYkdML09wZW5HTCdzIGNsaXAgdm9sdW1lLlxuICogUGFzc2luZyBudWxsL3VuZGVmaW5lZC9ubyB2YWx1ZSBmb3IgZmFyIHdpbGwgZ2VuZXJhdGUgaW5maW5pdGUgcHJvamVjdGlvbiBtYXRyaXguXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtudW1iZXJ9IGZvdnkgVmVydGljYWwgZmllbGQgb2YgdmlldyBpbiByYWRpYW5zXG4gKiBAcGFyYW0ge251bWJlcn0gYXNwZWN0IEFzcGVjdCByYXRpby4gdHlwaWNhbGx5IHZpZXdwb3J0IHdpZHRoL2hlaWdodFxuICogQHBhcmFtIHtudW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW0sIGNhbiBiZSBudWxsIG9yIEluZmluaXR5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHBlcnNwZWN0aXZlTk8ob3V0LCBmb3Z5LCBhc3BlY3QsIG5lYXIsIGZhcikge1xuICB2YXIgZiA9IDEuMCAvIE1hdGgudGFuKGZvdnkgLyAyKSxcbiAgICAgIG5mO1xuICBvdXRbMF0gPSBmIC8gYXNwZWN0O1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSBmO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTFdID0gLTE7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE1XSA9IDA7XG5cbiAgaWYgKGZhciAhPSBudWxsICYmIGZhciAhPT0gSW5maW5pdHkpIHtcbiAgICBuZiA9IDEgLyAobmVhciAtIGZhcik7XG4gICAgb3V0WzEwXSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICAgIG91dFsxNF0gPSAyICogZmFyICogbmVhciAqIG5mO1xuICB9IGVsc2Uge1xuICAgIG91dFsxMF0gPSAtMTtcbiAgICBvdXRbMTRdID0gLTIgKiBuZWFyO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQ0LnBlcnNwZWN0aXZlTk99XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHBlcnNwZWN0aXZlID0gcGVyc3BlY3RpdmVOTztcbi8qKlxuICogR2VuZXJhdGVzIGEgcGVyc3BlY3RpdmUgcHJvamVjdGlvbiBtYXRyaXggc3VpdGFibGUgZm9yIFdlYkdQVSB3aXRoIHRoZSBnaXZlbiBib3VuZHMuXG4gKiBUaGUgbmVhci9mYXIgY2xpcCBwbGFuZXMgY29ycmVzcG9uZCB0byBhIG5vcm1hbGl6ZWQgZGV2aWNlIGNvb3JkaW5hdGUgWiByYW5nZSBvZiBbMCwgMV0sXG4gKiB3aGljaCBtYXRjaGVzIFdlYkdQVS9WdWxrYW4vRGlyZWN0WC9NZXRhbCdzIGNsaXAgdm9sdW1lLlxuICogUGFzc2luZyBudWxsL3VuZGVmaW5lZC9ubyB2YWx1ZSBmb3IgZmFyIHdpbGwgZ2VuZXJhdGUgaW5maW5pdGUgcHJvamVjdGlvbiBtYXRyaXguXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtudW1iZXJ9IGZvdnkgVmVydGljYWwgZmllbGQgb2YgdmlldyBpbiByYWRpYW5zXG4gKiBAcGFyYW0ge251bWJlcn0gYXNwZWN0IEFzcGVjdCByYXRpby4gdHlwaWNhbGx5IHZpZXdwb3J0IHdpZHRoL2hlaWdodFxuICogQHBhcmFtIHtudW1iZXJ9IG5lYXIgTmVhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IGZhciBGYXIgYm91bmQgb2YgdGhlIGZydXN0dW0sIGNhbiBiZSBudWxsIG9yIEluZmluaXR5XG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHBlcnNwZWN0aXZlWk8ob3V0LCBmb3Z5LCBhc3BlY3QsIG5lYXIsIGZhcikge1xuICB2YXIgZiA9IDEuMCAvIE1hdGgudGFuKGZvdnkgLyAyKSxcbiAgICAgIG5mO1xuICBvdXRbMF0gPSBmIC8gYXNwZWN0O1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSBmO1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTFdID0gLTE7XG4gIG91dFsxMl0gPSAwO1xuICBvdXRbMTNdID0gMDtcbiAgb3V0WzE1XSA9IDA7XG5cbiAgaWYgKGZhciAhPSBudWxsICYmIGZhciAhPT0gSW5maW5pdHkpIHtcbiAgICBuZiA9IDEgLyAobmVhciAtIGZhcik7XG4gICAgb3V0WzEwXSA9IGZhciAqIG5mO1xuICAgIG91dFsxNF0gPSBmYXIgKiBuZWFyICogbmY7XG4gIH0gZWxzZSB7XG4gICAgb3V0WzEwXSA9IC0xO1xuICAgIG91dFsxNF0gPSAtbmVhcjtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIHBlcnNwZWN0aXZlIHByb2plY3Rpb24gbWF0cml4IHdpdGggdGhlIGdpdmVuIGZpZWxkIG9mIHZpZXcuXG4gKiBUaGlzIGlzIHByaW1hcmlseSB1c2VmdWwgZm9yIGdlbmVyYXRpbmcgcHJvamVjdGlvbiBtYXRyaWNlcyB0byBiZSB1c2VkXG4gKiB3aXRoIHRoZSBzdGlsbCBleHBlcmllbWVudGFsIFdlYlZSIEFQSS5cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXG4gKiBAcGFyYW0ge09iamVjdH0gZm92IE9iamVjdCBjb250YWluaW5nIHRoZSBmb2xsb3dpbmcgdmFsdWVzOiB1cERlZ3JlZXMsIGRvd25EZWdyZWVzLCBsZWZ0RGVncmVlcywgcmlnaHREZWdyZWVzXG4gKiBAcGFyYW0ge251bWJlcn0gbmVhciBOZWFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwZXJzcGVjdGl2ZUZyb21GaWVsZE9mVmlldyhvdXQsIGZvdiwgbmVhciwgZmFyKSB7XG4gIHZhciB1cFRhbiA9IE1hdGgudGFuKGZvdi51cERlZ3JlZXMgKiBNYXRoLlBJIC8gMTgwLjApO1xuICB2YXIgZG93blRhbiA9IE1hdGgudGFuKGZvdi5kb3duRGVncmVlcyAqIE1hdGguUEkgLyAxODAuMCk7XG4gIHZhciBsZWZ0VGFuID0gTWF0aC50YW4oZm92LmxlZnREZWdyZWVzICogTWF0aC5QSSAvIDE4MC4wKTtcbiAgdmFyIHJpZ2h0VGFuID0gTWF0aC50YW4oZm92LnJpZ2h0RGVncmVlcyAqIE1hdGguUEkgLyAxODAuMCk7XG4gIHZhciB4U2NhbGUgPSAyLjAgLyAobGVmdFRhbiArIHJpZ2h0VGFuKTtcbiAgdmFyIHlTY2FsZSA9IDIuMCAvICh1cFRhbiArIGRvd25UYW4pO1xuICBvdXRbMF0gPSB4U2NhbGU7XG4gIG91dFsxXSA9IDAuMDtcbiAgb3V0WzJdID0gMC4wO1xuICBvdXRbM10gPSAwLjA7XG4gIG91dFs0XSA9IDAuMDtcbiAgb3V0WzVdID0geVNjYWxlO1xuICBvdXRbNl0gPSAwLjA7XG4gIG91dFs3XSA9IDAuMDtcbiAgb3V0WzhdID0gLSgobGVmdFRhbiAtIHJpZ2h0VGFuKSAqIHhTY2FsZSAqIDAuNSk7XG4gIG91dFs5XSA9ICh1cFRhbiAtIGRvd25UYW4pICogeVNjYWxlICogMC41O1xuICBvdXRbMTBdID0gZmFyIC8gKG5lYXIgLSBmYXIpO1xuICBvdXRbMTFdID0gLTEuMDtcbiAgb3V0WzEyXSA9IDAuMDtcbiAgb3V0WzEzXSA9IDAuMDtcbiAgb3V0WzE0XSA9IGZhciAqIG5lYXIgLyAobmVhciAtIGZhcik7XG4gIG91dFsxNV0gPSAwLjA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIG9ydGhvZ29uYWwgcHJvamVjdGlvbiBtYXRyaXggd2l0aCB0aGUgZ2l2ZW4gYm91bmRzLlxuICogVGhlIG5lYXIvZmFyIGNsaXAgcGxhbmVzIGNvcnJlc3BvbmQgdG8gYSBub3JtYWxpemVkIGRldmljZSBjb29yZGluYXRlIFogcmFuZ2Ugb2YgWy0xLCAxXSxcbiAqIHdoaWNoIG1hdGNoZXMgV2ViR0wvT3BlbkdMJ3MgY2xpcCB2b2x1bWUuXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtudW1iZXJ9IGxlZnQgTGVmdCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IHJpZ2h0IFJpZ2h0IGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gYm90dG9tIEJvdHRvbSBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IHRvcCBUb3AgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBuZWFyIE5lYXIgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBmYXIgRmFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG9ydGhvTk8ob3V0LCBsZWZ0LCByaWdodCwgYm90dG9tLCB0b3AsIG5lYXIsIGZhcikge1xuICB2YXIgbHIgPSAxIC8gKGxlZnQgLSByaWdodCk7XG4gIHZhciBidCA9IDEgLyAoYm90dG9tIC0gdG9wKTtcbiAgdmFyIG5mID0gMSAvIChuZWFyIC0gZmFyKTtcbiAgb3V0WzBdID0gLTIgKiBscjtcbiAgb3V0WzFdID0gMDtcbiAgb3V0WzJdID0gMDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0gMDtcbiAgb3V0WzVdID0gLTIgKiBidDtcbiAgb3V0WzZdID0gMDtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0gMDtcbiAgb3V0WzldID0gMDtcbiAgb3V0WzEwXSA9IDIgKiBuZjtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAobGVmdCArIHJpZ2h0KSAqIGxyO1xuICBvdXRbMTNdID0gKHRvcCArIGJvdHRvbSkgKiBidDtcbiAgb3V0WzE0XSA9IChmYXIgKyBuZWFyKSAqIG5mO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBtYXQ0Lm9ydGhvTk99XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG9ydGhvID0gb3J0aG9OTztcbi8qKlxuICogR2VuZXJhdGVzIGEgb3J0aG9nb25hbCBwcm9qZWN0aW9uIG1hdHJpeCB3aXRoIHRoZSBnaXZlbiBib3VuZHMuXG4gKiBUaGUgbmVhci9mYXIgY2xpcCBwbGFuZXMgY29ycmVzcG9uZCB0byBhIG5vcm1hbGl6ZWQgZGV2aWNlIGNvb3JkaW5hdGUgWiByYW5nZSBvZiBbMCwgMV0sXG4gKiB3aGljaCBtYXRjaGVzIFdlYkdQVS9WdWxrYW4vRGlyZWN0WC9NZXRhbCdzIGNsaXAgdm9sdW1lLlxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IG1hdDQgZnJ1c3R1bSBtYXRyaXggd2lsbCBiZSB3cml0dGVuIGludG9cbiAqIEBwYXJhbSB7bnVtYmVyfSBsZWZ0IExlZnQgYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSByaWdodCBSaWdodCBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHBhcmFtIHtudW1iZXJ9IGJvdHRvbSBCb3R0b20gYm91bmQgb2YgdGhlIGZydXN0dW1cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b3AgVG9wIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gbmVhciBOZWFyIGJvdW5kIG9mIHRoZSBmcnVzdHVtXG4gKiBAcGFyYW0ge251bWJlcn0gZmFyIEZhciBib3VuZCBvZiB0aGUgZnJ1c3R1bVxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvcnRob1pPKG91dCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgdG9wLCBuZWFyLCBmYXIpIHtcbiAgdmFyIGxyID0gMSAvIChsZWZ0IC0gcmlnaHQpO1xuICB2YXIgYnQgPSAxIC8gKGJvdHRvbSAtIHRvcCk7XG4gIHZhciBuZiA9IDEgLyAobmVhciAtIGZhcik7XG4gIG91dFswXSA9IC0yICogbHI7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IDA7XG4gIG91dFs1XSA9IC0yICogYnQ7XG4gIG91dFs2XSA9IDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IDA7XG4gIG91dFs5XSA9IDA7XG4gIG91dFsxMF0gPSBuZjtcbiAgb3V0WzExXSA9IDA7XG4gIG91dFsxMl0gPSAobGVmdCArIHJpZ2h0KSAqIGxyO1xuICBvdXRbMTNdID0gKHRvcCArIGJvdHRvbSkgKiBidDtcbiAgb3V0WzE0XSA9IG5lYXIgKiBuZjtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIGxvb2stYXQgbWF0cml4IHdpdGggdGhlIGdpdmVuIGV5ZSBwb3NpdGlvbiwgZm9jYWwgcG9pbnQsIGFuZCB1cCBheGlzLlxuICogSWYgeW91IHdhbnQgYSBtYXRyaXggdGhhdCBhY3R1YWxseSBtYWtlcyBhbiBvYmplY3QgbG9vayBhdCBhbm90aGVyIG9iamVjdCwgeW91IHNob3VsZCB1c2UgdGFyZ2V0VG8gaW5zdGVhZC5cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCBtYXQ0IGZydXN0dW0gbWF0cml4IHdpbGwgYmUgd3JpdHRlbiBpbnRvXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gZXllIFBvc2l0aW9uIG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBjZW50ZXIgUG9pbnQgdGhlIHZpZXdlciBpcyBsb29raW5nIGF0XG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdXAgdmVjMyBwb2ludGluZyB1cFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsb29rQXQob3V0LCBleWUsIGNlbnRlciwgdXApIHtcbiAgdmFyIHgwLCB4MSwgeDIsIHkwLCB5MSwgeTIsIHowLCB6MSwgejIsIGxlbjtcbiAgdmFyIGV5ZXggPSBleWVbMF07XG4gIHZhciBleWV5ID0gZXllWzFdO1xuICB2YXIgZXlleiA9IGV5ZVsyXTtcbiAgdmFyIHVweCA9IHVwWzBdO1xuICB2YXIgdXB5ID0gdXBbMV07XG4gIHZhciB1cHogPSB1cFsyXTtcbiAgdmFyIGNlbnRlcnggPSBjZW50ZXJbMF07XG4gIHZhciBjZW50ZXJ5ID0gY2VudGVyWzFdO1xuICB2YXIgY2VudGVyeiA9IGNlbnRlclsyXTtcblxuICBpZiAoTWF0aC5hYnMoZXlleCAtIGNlbnRlcngpIDwgZ2xNYXRyaXguRVBTSUxPTiAmJiBNYXRoLmFicyhleWV5IC0gY2VudGVyeSkgPCBnbE1hdHJpeC5FUFNJTE9OICYmIE1hdGguYWJzKGV5ZXogLSBjZW50ZXJ6KSA8IGdsTWF0cml4LkVQU0lMT04pIHtcbiAgICByZXR1cm4gaWRlbnRpdHkob3V0KTtcbiAgfVxuXG4gIHowID0gZXlleCAtIGNlbnRlcng7XG4gIHoxID0gZXlleSAtIGNlbnRlcnk7XG4gIHoyID0gZXlleiAtIGNlbnRlcno7XG4gIGxlbiA9IDEgLyBNYXRoLmh5cG90KHowLCB6MSwgejIpO1xuICB6MCAqPSBsZW47XG4gIHoxICo9IGxlbjtcbiAgejIgKj0gbGVuO1xuICB4MCA9IHVweSAqIHoyIC0gdXB6ICogejE7XG4gIHgxID0gdXB6ICogejAgLSB1cHggKiB6MjtcbiAgeDIgPSB1cHggKiB6MSAtIHVweSAqIHowO1xuICBsZW4gPSBNYXRoLmh5cG90KHgwLCB4MSwgeDIpO1xuXG4gIGlmICghbGVuKSB7XG4gICAgeDAgPSAwO1xuICAgIHgxID0gMDtcbiAgICB4MiA9IDA7XG4gIH0gZWxzZSB7XG4gICAgbGVuID0gMSAvIGxlbjtcbiAgICB4MCAqPSBsZW47XG4gICAgeDEgKj0gbGVuO1xuICAgIHgyICo9IGxlbjtcbiAgfVxuXG4gIHkwID0gejEgKiB4MiAtIHoyICogeDE7XG4gIHkxID0gejIgKiB4MCAtIHowICogeDI7XG4gIHkyID0gejAgKiB4MSAtIHoxICogeDA7XG4gIGxlbiA9IE1hdGguaHlwb3QoeTAsIHkxLCB5Mik7XG5cbiAgaWYgKCFsZW4pIHtcbiAgICB5MCA9IDA7XG4gICAgeTEgPSAwO1xuICAgIHkyID0gMDtcbiAgfSBlbHNlIHtcbiAgICBsZW4gPSAxIC8gbGVuO1xuICAgIHkwICo9IGxlbjtcbiAgICB5MSAqPSBsZW47XG4gICAgeTIgKj0gbGVuO1xuICB9XG5cbiAgb3V0WzBdID0geDA7XG4gIG91dFsxXSA9IHkwO1xuICBvdXRbMl0gPSB6MDtcbiAgb3V0WzNdID0gMDtcbiAgb3V0WzRdID0geDE7XG4gIG91dFs1XSA9IHkxO1xuICBvdXRbNl0gPSB6MTtcbiAgb3V0WzddID0gMDtcbiAgb3V0WzhdID0geDI7XG4gIG91dFs5XSA9IHkyO1xuICBvdXRbMTBdID0gejI7XG4gIG91dFsxMV0gPSAwO1xuICBvdXRbMTJdID0gLSh4MCAqIGV5ZXggKyB4MSAqIGV5ZXkgKyB4MiAqIGV5ZXopO1xuICBvdXRbMTNdID0gLSh5MCAqIGV5ZXggKyB5MSAqIGV5ZXkgKyB5MiAqIGV5ZXopO1xuICBvdXRbMTRdID0gLSh6MCAqIGV5ZXggKyB6MSAqIGV5ZXkgKyB6MiAqIGV5ZXopO1xuICBvdXRbMTVdID0gMTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgbWF0cml4IHRoYXQgbWFrZXMgc29tZXRoaW5nIGxvb2sgYXQgc29tZXRoaW5nIGVsc2UuXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgbWF0NCBmcnVzdHVtIG1hdHJpeCB3aWxsIGJlIHdyaXR0ZW4gaW50b1xuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGV5ZSBQb3NpdGlvbiBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gY2VudGVyIFBvaW50IHRoZSB2aWV3ZXIgaXMgbG9va2luZyBhdFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IHVwIHZlYzMgcG9pbnRpbmcgdXBcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdGFyZ2V0VG8ob3V0LCBleWUsIHRhcmdldCwgdXApIHtcbiAgdmFyIGV5ZXggPSBleWVbMF0sXG4gICAgICBleWV5ID0gZXllWzFdLFxuICAgICAgZXlleiA9IGV5ZVsyXSxcbiAgICAgIHVweCA9IHVwWzBdLFxuICAgICAgdXB5ID0gdXBbMV0sXG4gICAgICB1cHogPSB1cFsyXTtcbiAgdmFyIHowID0gZXlleCAtIHRhcmdldFswXSxcbiAgICAgIHoxID0gZXlleSAtIHRhcmdldFsxXSxcbiAgICAgIHoyID0gZXlleiAtIHRhcmdldFsyXTtcbiAgdmFyIGxlbiA9IHowICogejAgKyB6MSAqIHoxICsgejIgKiB6MjtcblxuICBpZiAobGVuID4gMCkge1xuICAgIGxlbiA9IDEgLyBNYXRoLnNxcnQobGVuKTtcbiAgICB6MCAqPSBsZW47XG4gICAgejEgKj0gbGVuO1xuICAgIHoyICo9IGxlbjtcbiAgfVxuXG4gIHZhciB4MCA9IHVweSAqIHoyIC0gdXB6ICogejEsXG4gICAgICB4MSA9IHVweiAqIHowIC0gdXB4ICogejIsXG4gICAgICB4MiA9IHVweCAqIHoxIC0gdXB5ICogejA7XG4gIGxlbiA9IHgwICogeDAgKyB4MSAqIHgxICsgeDIgKiB4MjtcblxuICBpZiAobGVuID4gMCkge1xuICAgIGxlbiA9IDEgLyBNYXRoLnNxcnQobGVuKTtcbiAgICB4MCAqPSBsZW47XG4gICAgeDEgKj0gbGVuO1xuICAgIHgyICo9IGxlbjtcbiAgfVxuXG4gIG91dFswXSA9IHgwO1xuICBvdXRbMV0gPSB4MTtcbiAgb3V0WzJdID0geDI7XG4gIG91dFszXSA9IDA7XG4gIG91dFs0XSA9IHoxICogeDIgLSB6MiAqIHgxO1xuICBvdXRbNV0gPSB6MiAqIHgwIC0gejAgKiB4MjtcbiAgb3V0WzZdID0gejAgKiB4MSAtIHoxICogeDA7XG4gIG91dFs3XSA9IDA7XG4gIG91dFs4XSA9IHowO1xuICBvdXRbOV0gPSB6MTtcbiAgb3V0WzEwXSA9IHoyO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IGV5ZXg7XG4gIG91dFsxM10gPSBleWV5O1xuICBvdXRbMTRdID0gZXllejtcbiAgb3V0WzE1XSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBtYXQ0XG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgbWF0cml4IHRvIHJlcHJlc2VudCBhcyBhIHN0cmluZ1xuICogQHJldHVybnMge1N0cmluZ30gc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtYXRyaXhcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyKGEpIHtcbiAgcmV0dXJuIFwibWF0NChcIiArIGFbMF0gKyBcIiwgXCIgKyBhWzFdICsgXCIsIFwiICsgYVsyXSArIFwiLCBcIiArIGFbM10gKyBcIiwgXCIgKyBhWzRdICsgXCIsIFwiICsgYVs1XSArIFwiLCBcIiArIGFbNl0gKyBcIiwgXCIgKyBhWzddICsgXCIsIFwiICsgYVs4XSArIFwiLCBcIiArIGFbOV0gKyBcIiwgXCIgKyBhWzEwXSArIFwiLCBcIiArIGFbMTFdICsgXCIsIFwiICsgYVsxMl0gKyBcIiwgXCIgKyBhWzEzXSArIFwiLCBcIiArIGFbMTRdICsgXCIsIFwiICsgYVsxNV0gKyBcIilcIjtcbn1cbi8qKlxuICogUmV0dXJucyBGcm9iZW5pdXMgbm9ybSBvZiBhIG1hdDRcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgbWF0cml4IHRvIGNhbGN1bGF0ZSBGcm9iZW5pdXMgbm9ybSBvZlxuICogQHJldHVybnMge051bWJlcn0gRnJvYmVuaXVzIG5vcm1cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvYihhKSB7XG4gIHJldHVybiBNYXRoLmh5cG90KGFbMF0sIGFbMV0sIGFbMl0sIGFbM10sIGFbNF0sIGFbNV0sIGFbNl0sIGFbN10sIGFbOF0sIGFbOV0sIGFbMTBdLCBhWzExXSwgYVsxMl0sIGFbMTNdLCBhWzE0XSwgYVsxNV0pO1xufVxuLyoqXG4gKiBBZGRzIHR3byBtYXQ0J3NcbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIG1hdHJpeFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge21hdDR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl07XG4gIG91dFszXSA9IGFbM10gKyBiWzNdO1xuICBvdXRbNF0gPSBhWzRdICsgYls0XTtcbiAgb3V0WzVdID0gYVs1XSArIGJbNV07XG4gIG91dFs2XSA9IGFbNl0gKyBiWzZdO1xuICBvdXRbN10gPSBhWzddICsgYls3XTtcbiAgb3V0WzhdID0gYVs4XSArIGJbOF07XG4gIG91dFs5XSA9IGFbOV0gKyBiWzldO1xuICBvdXRbMTBdID0gYVsxMF0gKyBiWzEwXTtcbiAgb3V0WzExXSA9IGFbMTFdICsgYlsxMV07XG4gIG91dFsxMl0gPSBhWzEyXSArIGJbMTJdO1xuICBvdXRbMTNdID0gYVsxM10gKyBiWzEzXTtcbiAgb3V0WzE0XSA9IGFbMTRdICsgYlsxNF07XG4gIG91dFsxNV0gPSBhWzE1XSArIGJbMTVdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTdWJ0cmFjdHMgbWF0cml4IGIgZnJvbSBtYXRyaXggYVxuICpcbiAqIEBwYXJhbSB7bWF0NH0gb3V0IHRoZSByZWNlaXZpbmcgbWF0cml4XG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7bWF0NH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLSBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC0gYlszXTtcbiAgb3V0WzRdID0gYVs0XSAtIGJbNF07XG4gIG91dFs1XSA9IGFbNV0gLSBiWzVdO1xuICBvdXRbNl0gPSBhWzZdIC0gYls2XTtcbiAgb3V0WzddID0gYVs3XSAtIGJbN107XG4gIG91dFs4XSA9IGFbOF0gLSBiWzhdO1xuICBvdXRbOV0gPSBhWzldIC0gYls5XTtcbiAgb3V0WzEwXSA9IGFbMTBdIC0gYlsxMF07XG4gIG91dFsxMV0gPSBhWzExXSAtIGJbMTFdO1xuICBvdXRbMTJdID0gYVsxMl0gLSBiWzEyXTtcbiAgb3V0WzEzXSA9IGFbMTNdIC0gYlsxM107XG4gIG91dFsxNF0gPSBhWzE0XSAtIGJbMTRdO1xuICBvdXRbMTVdID0gYVsxNV0gLSBiWzE1XTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTXVsdGlwbHkgZWFjaCBlbGVtZW50IG9mIHRoZSBtYXRyaXggYnkgYSBzY2FsYXIuXG4gKlxuICogQHBhcmFtIHttYXQ0fSBvdXQgdGhlIHJlY2VpdmluZyBtYXRyaXhcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBhIHRoZSBtYXRyaXggdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgbWF0cml4J3MgZWxlbWVudHMgYnlcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXIob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiO1xuICBvdXRbMV0gPSBhWzFdICogYjtcbiAgb3V0WzJdID0gYVsyXSAqIGI7XG4gIG91dFszXSA9IGFbM10gKiBiO1xuICBvdXRbNF0gPSBhWzRdICogYjtcbiAgb3V0WzVdID0gYVs1XSAqIGI7XG4gIG91dFs2XSA9IGFbNl0gKiBiO1xuICBvdXRbN10gPSBhWzddICogYjtcbiAgb3V0WzhdID0gYVs4XSAqIGI7XG4gIG91dFs5XSA9IGFbOV0gKiBiO1xuICBvdXRbMTBdID0gYVsxMF0gKiBiO1xuICBvdXRbMTFdID0gYVsxMV0gKiBiO1xuICBvdXRbMTJdID0gYVsxMl0gKiBiO1xuICBvdXRbMTNdID0gYVsxM10gKiBiO1xuICBvdXRbMTRdID0gYVsxNF0gKiBiO1xuICBvdXRbMTVdID0gYVsxNV0gKiBiO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBBZGRzIHR3byBtYXQ0J3MgYWZ0ZXIgbXVsdGlwbHlpbmcgZWFjaCBlbGVtZW50IG9mIHRoZSBzZWNvbmQgb3BlcmFuZCBieSBhIHNjYWxhciB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge21hdDR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYidzIGVsZW1lbnRzIGJ5IGJlZm9yZSBhZGRpbmdcbiAqIEByZXR1cm5zIHttYXQ0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlTY2FsYXJBbmRBZGQob3V0LCBhLCBiLCBzY2FsZSkge1xuICBvdXRbMF0gPSBhWzBdICsgYlswXSAqIHNjYWxlO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXSAqIHNjYWxlO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXSAqIHNjYWxlO1xuICBvdXRbM10gPSBhWzNdICsgYlszXSAqIHNjYWxlO1xuICBvdXRbNF0gPSBhWzRdICsgYls0XSAqIHNjYWxlO1xuICBvdXRbNV0gPSBhWzVdICsgYls1XSAqIHNjYWxlO1xuICBvdXRbNl0gPSBhWzZdICsgYls2XSAqIHNjYWxlO1xuICBvdXRbN10gPSBhWzddICsgYls3XSAqIHNjYWxlO1xuICBvdXRbOF0gPSBhWzhdICsgYls4XSAqIHNjYWxlO1xuICBvdXRbOV0gPSBhWzldICsgYls5XSAqIHNjYWxlO1xuICBvdXRbMTBdID0gYVsxMF0gKyBiWzEwXSAqIHNjYWxlO1xuICBvdXRbMTFdID0gYVsxMV0gKyBiWzExXSAqIHNjYWxlO1xuICBvdXRbMTJdID0gYVsxMl0gKyBiWzEyXSAqIHNjYWxlO1xuICBvdXRbMTNdID0gYVsxM10gKyBiWzEzXSAqIHNjYWxlO1xuICBvdXRbMTRdID0gYVsxNF0gKyBiWzE0XSAqIHNjYWxlO1xuICBvdXRbMTVdID0gYVsxNV0gKyBiWzE1XSAqIHNjYWxlO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBtYXRyaWNlcyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgVGhlIGZpcnN0IG1hdHJpeC5cbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIFRoZSBzZWNvbmQgbWF0cml4LlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdICYmIGFbNF0gPT09IGJbNF0gJiYgYVs1XSA9PT0gYls1XSAmJiBhWzZdID09PSBiWzZdICYmIGFbN10gPT09IGJbN10gJiYgYVs4XSA9PT0gYls4XSAmJiBhWzldID09PSBiWzldICYmIGFbMTBdID09PSBiWzEwXSAmJiBhWzExXSA9PT0gYlsxMV0gJiYgYVsxMl0gPT09IGJbMTJdICYmIGFbMTNdID09PSBiWzEzXSAmJiBhWzE0XSA9PT0gYlsxNF0gJiYgYVsxNV0gPT09IGJbMTVdO1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBtYXRyaWNlcyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seU1hdDR9IGEgVGhlIGZpcnN0IG1hdHJpeC5cbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBiIFRoZSBzZWNvbmQgbWF0cml4LlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIG1hdHJpY2VzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHMoYSwgYikge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdO1xuICB2YXIgYTQgPSBhWzRdLFxuICAgICAgYTUgPSBhWzVdLFxuICAgICAgYTYgPSBhWzZdLFxuICAgICAgYTcgPSBhWzddO1xuICB2YXIgYTggPSBhWzhdLFxuICAgICAgYTkgPSBhWzldLFxuICAgICAgYTEwID0gYVsxMF0sXG4gICAgICBhMTEgPSBhWzExXTtcbiAgdmFyIGExMiA9IGFbMTJdLFxuICAgICAgYTEzID0gYVsxM10sXG4gICAgICBhMTQgPSBhWzE0XSxcbiAgICAgIGExNSA9IGFbMTVdO1xuICB2YXIgYjAgPSBiWzBdLFxuICAgICAgYjEgPSBiWzFdLFxuICAgICAgYjIgPSBiWzJdLFxuICAgICAgYjMgPSBiWzNdO1xuICB2YXIgYjQgPSBiWzRdLFxuICAgICAgYjUgPSBiWzVdLFxuICAgICAgYjYgPSBiWzZdLFxuICAgICAgYjcgPSBiWzddO1xuICB2YXIgYjggPSBiWzhdLFxuICAgICAgYjkgPSBiWzldLFxuICAgICAgYjEwID0gYlsxMF0sXG4gICAgICBiMTEgPSBiWzExXTtcbiAgdmFyIGIxMiA9IGJbMTJdLFxuICAgICAgYjEzID0gYlsxM10sXG4gICAgICBiMTQgPSBiWzE0XSxcbiAgICAgIGIxNSA9IGJbMTVdO1xuICByZXR1cm4gTWF0aC5hYnMoYTAgLSBiMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTApLCBNYXRoLmFicyhiMCkpICYmIE1hdGguYWJzKGExIC0gYjEpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExKSwgTWF0aC5hYnMoYjEpKSAmJiBNYXRoLmFicyhhMiAtIGIyKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMiksIE1hdGguYWJzKGIyKSkgJiYgTWF0aC5hYnMoYTMgLSBiMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTMpLCBNYXRoLmFicyhiMykpICYmIE1hdGguYWJzKGE0IC0gYjQpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE0KSwgTWF0aC5hYnMoYjQpKSAmJiBNYXRoLmFicyhhNSAtIGI1KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhNSksIE1hdGguYWJzKGI1KSkgJiYgTWF0aC5hYnMoYTYgLSBiNikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTYpLCBNYXRoLmFicyhiNikpICYmIE1hdGguYWJzKGE3IC0gYjcpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGE3KSwgTWF0aC5hYnMoYjcpKSAmJiBNYXRoLmFicyhhOCAtIGI4KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhOCksIE1hdGguYWJzKGI4KSkgJiYgTWF0aC5hYnMoYTkgLSBiOSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTkpLCBNYXRoLmFicyhiOSkpICYmIE1hdGguYWJzKGExMCAtIGIxMCkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEwKSwgTWF0aC5hYnMoYjEwKSkgJiYgTWF0aC5hYnMoYTExIC0gYjExKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMTEpLCBNYXRoLmFicyhiMTEpKSAmJiBNYXRoLmFicyhhMTIgLSBiMTIpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExMiksIE1hdGguYWJzKGIxMikpICYmIE1hdGguYWJzKGExMyAtIGIxMykgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEzKSwgTWF0aC5hYnMoYjEzKSkgJiYgTWF0aC5hYnMoYTE0IC0gYjE0KSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMTQpLCBNYXRoLmFicyhiMTQpKSAmJiBNYXRoLmFicyhhMTUgLSBiMTUpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGExNSksIE1hdGguYWJzKGIxNSkpO1xufVxuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDQubXVsdGlwbHl9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG11bCA9IG11bHRpcGx5O1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIG1hdDQuc3VidHJhY3R9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHN1YiA9IHN1YnRyYWN0OyIsImltcG9ydCAqIGFzIGdsTWF0cml4IGZyb20gXCIuL2NvbW1vbi5qc1wiO1xuLyoqXG4gKiA0IERpbWVuc2lvbmFsIFZlY3RvclxuICogQG1vZHVsZSB2ZWM0XG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWM0XG4gKlxuICogQHJldHVybnMge3ZlYzR9IGEgbmV3IDREIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg0KTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgICBvdXRbM10gPSAwO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWM0IGluaXRpYWxpemVkIHdpdGggdmFsdWVzIGZyb20gYW4gZXhpc3RpbmcgdmVjdG9yXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIGNsb25lXG4gKiBAcmV0dXJucyB7dmVjNH0gYSBuZXcgNEQgdmVjdG9yXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb25lKGEpIHtcbiAgdmFyIG91dCA9IG5ldyBnbE1hdHJpeC5BUlJBWV9UWVBFKDQpO1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHZlYzQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcgVyBjb21wb25lbnRcbiAqIEByZXR1cm5zIHt2ZWM0fSBhIG5ldyA0RCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVZhbHVlcyh4LCB5LCB6LCB3KSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg0KTtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgb3V0WzJdID0gejtcbiAgb3V0WzNdID0gdztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIHZlYzQgdG8gYW5vdGhlclxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgc291cmNlIHZlY3RvclxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0IHRvIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcgVyBjb21wb25lbnRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0KG91dCwgeCwgeSwgeiwgdykge1xuICBvdXRbMF0gPSB4O1xuICBvdXRbMV0gPSB5O1xuICBvdXRbMl0gPSB6O1xuICBvdXRbM10gPSB3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBBZGRzIHR3byB2ZWM0J3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl07XG4gIG91dFszXSA9IGFbM10gKyBiWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTdWJ0cmFjdHMgdmVjdG9yIGIgZnJvbSB2ZWN0b3IgYVxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdIC0gYlswXTtcbiAgb3V0WzFdID0gYVsxXSAtIGJbMV07XG4gIG91dFsyXSA9IGFbMl0gLSBiWzJdO1xuICBvdXRbM10gPSBhWzNdIC0gYlszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTXVsdGlwbGllcyB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICogYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAqIGJbMl07XG4gIG91dFszXSA9IGFbM10gKiBiWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBEaXZpZGVzIHR3byB2ZWM0J3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkaXZpZGUob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gLyBiWzBdO1xuICBvdXRbMV0gPSBhWzFdIC8gYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAvIGJbMl07XG4gIG91dFszXSA9IGFbM10gLyBiWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBNYXRoLmNlaWwgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBjZWlsXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNlaWwob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGguY2VpbChhWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5jZWlsKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLmNlaWwoYVsyXSk7XG4gIG91dFszXSA9IE1hdGguY2VpbChhWzNdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTWF0aC5mbG9vciB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzRcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIGZsb29yXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZsb29yKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLmZsb29yKGFbMF0pO1xuICBvdXRbMV0gPSBNYXRoLmZsb29yKGFbMV0pO1xuICBvdXRbMl0gPSBNYXRoLmZsb29yKGFbMl0pO1xuICBvdXRbM10gPSBNYXRoLmZsb29yKGFbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtaW5pbXVtIG9mIHR3byB2ZWM0J3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtaW4ob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IE1hdGgubWluKGFbMF0sIGJbMF0pO1xuICBvdXRbMV0gPSBNYXRoLm1pbihhWzFdLCBiWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5taW4oYVsyXSwgYlsyXSk7XG4gIG91dFszXSA9IE1hdGgubWluKGFbM10sIGJbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIG9mIHR3byB2ZWM0J3NcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtYXgob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IE1hdGgubWF4KGFbMF0sIGJbMF0pO1xuICBvdXRbMV0gPSBNYXRoLm1heChhWzFdLCBiWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5tYXgoYVsyXSwgYlsyXSk7XG4gIG91dFszXSA9IE1hdGgubWF4KGFbM10sIGJbM10pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBNYXRoLnJvdW5kIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gcm91bmRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm91bmQob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGgucm91bmQoYVswXSk7XG4gIG91dFsxXSA9IE1hdGgucm91bmQoYVsxXSk7XG4gIG91dFsyXSA9IE1hdGgucm91bmQoYVsyXSk7XG4gIG91dFszXSA9IE1hdGgucm91bmQoYVszXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNjYWxlcyBhIHZlYzQgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgdmVjdG9yIGJ5XG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYjtcbiAgb3V0WzFdID0gYVsxXSAqIGI7XG4gIG91dFsyXSA9IGFbMl0gKiBiO1xuICBvdXRbM10gPSBhWzNdICogYjtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQWRkcyB0d28gdmVjNCdzIGFmdGVyIHNjYWxpbmcgdGhlIHNlY29uZCBvcGVyYW5kIGJ5IGEgc2NhbGFyIHZhbHVlXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSBzY2FsZSB0aGUgYW1vdW50IHRvIHNjYWxlIGIgYnkgYmVmb3JlIGFkZGluZ1xuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZUFuZEFkZChvdXQsIGEsIGIsIHNjYWxlKSB7XG4gIG91dFswXSA9IGFbMF0gKyBiWzBdICogc2NhbGU7XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdICogc2NhbGU7XG4gIG91dFsyXSA9IGFbMl0gKyBiWzJdICogc2NhbGU7XG4gIG91dFszXSA9IGFbM10gKyBiWzNdICogc2NhbGU7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWM0J3NcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2UoYSwgYikge1xuICB2YXIgeCA9IGJbMF0gLSBhWzBdO1xuICB2YXIgeSA9IGJbMV0gLSBhWzFdO1xuICB2YXIgeiA9IGJbMl0gLSBhWzJdO1xuICB2YXIgdyA9IGJbM10gLSBhWzNdO1xuICByZXR1cm4gTWF0aC5oeXBvdCh4LCB5LCB6LCB3KTtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc3F1YXJlZCBldWNsaWRpYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gc3F1YXJlZCBkaXN0YW5jZSBiZXR3ZWVuIGEgYW5kIGJcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlKGEsIGIpIHtcbiAgdmFyIHggPSBiWzBdIC0gYVswXTtcbiAgdmFyIHkgPSBiWzFdIC0gYVsxXTtcbiAgdmFyIHogPSBiWzJdIC0gYVsyXTtcbiAgdmFyIHcgPSBiWzNdIC0gYVszXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogeiArIHcgKiB3O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsZW5ndGggb2YgYSB2ZWM0XG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdmVjdG9yIHRvIGNhbGN1bGF0ZSBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGxlbmd0aCBvZiBhXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxlbmd0aChhKSB7XG4gIHZhciB4ID0gYVswXTtcbiAgdmFyIHkgPSBhWzFdO1xuICB2YXIgeiA9IGFbMl07XG4gIHZhciB3ID0gYVszXTtcbiAgcmV0dXJuIE1hdGguaHlwb3QoeCwgeSwgeiwgdyk7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgbGVuZ3RoIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgbGVuZ3RoIG9mIGFcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZExlbmd0aChhKSB7XG4gIHZhciB4ID0gYVswXTtcbiAgdmFyIHkgPSBhWzFdO1xuICB2YXIgeiA9IGFbMl07XG4gIHZhciB3ID0gYVszXTtcbiAgcmV0dXJuIHggKiB4ICsgeSAqIHkgKyB6ICogeiArIHcgKiB3O1xufVxuLyoqXG4gKiBOZWdhdGVzIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gbmVnYXRlXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5lZ2F0ZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gLWFbMF07XG4gIG91dFsxXSA9IC1hWzFdO1xuICBvdXRbMl0gPSAtYVsyXTtcbiAgb3V0WzNdID0gLWFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWM0XG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byBpbnZlcnRcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJzZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gMS4wIC8gYVswXTtcbiAgb3V0WzFdID0gMS4wIC8gYVsxXTtcbiAgb3V0WzJdID0gMS4wIC8gYVsyXTtcbiAgb3V0WzNdID0gMS4wIC8gYVszXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTm9ybWFsaXplIGEgdmVjNFxuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSB2ZWN0b3IgdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZShvdXQsIGEpIHtcbiAgdmFyIHggPSBhWzBdO1xuICB2YXIgeSA9IGFbMV07XG4gIHZhciB6ID0gYVsyXTtcbiAgdmFyIHcgPSBhWzNdO1xuICB2YXIgbGVuID0geCAqIHggKyB5ICogeSArIHogKiB6ICsgdyAqIHc7XG5cbiAgaWYgKGxlbiA+IDApIHtcbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gIH1cblxuICBvdXRbMF0gPSB4ICogbGVuO1xuICBvdXRbMV0gPSB5ICogbGVuO1xuICBvdXRbMl0gPSB6ICogbGVuO1xuICBvdXRbM10gPSB3ICogbGVuO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gZG90IHByb2R1Y3Qgb2YgYSBhbmQgYlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkb3QoYSwgYikge1xuICByZXR1cm4gYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXSArIGFbMl0gKiBiWzJdICsgYVszXSAqIGJbM107XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGNyb3NzLXByb2R1Y3Qgb2YgdGhyZWUgdmVjdG9ycyBpbiBhIDQtZGltZW5zaW9uYWwgc3BhY2VcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gcmVzdWx0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gVSB0aGUgZmlyc3QgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gViB0aGUgc2Vjb25kIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IFcgdGhlIHRoaXJkIHZlY3RvclxuICogQHJldHVybnMge3ZlYzR9IHJlc3VsdFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcm9zcyhvdXQsIHUsIHYsIHcpIHtcbiAgdmFyIEEgPSB2WzBdICogd1sxXSAtIHZbMV0gKiB3WzBdLFxuICAgICAgQiA9IHZbMF0gKiB3WzJdIC0gdlsyXSAqIHdbMF0sXG4gICAgICBDID0gdlswXSAqIHdbM10gLSB2WzNdICogd1swXSxcbiAgICAgIEQgPSB2WzFdICogd1syXSAtIHZbMl0gKiB3WzFdLFxuICAgICAgRSA9IHZbMV0gKiB3WzNdIC0gdlszXSAqIHdbMV0sXG4gICAgICBGID0gdlsyXSAqIHdbM10gLSB2WzNdICogd1syXTtcbiAgdmFyIEcgPSB1WzBdO1xuICB2YXIgSCA9IHVbMV07XG4gIHZhciBJID0gdVsyXTtcbiAgdmFyIEogPSB1WzNdO1xuICBvdXRbMF0gPSBIICogRiAtIEkgKiBFICsgSiAqIEQ7XG4gIG91dFsxXSA9IC0oRyAqIEYpICsgSSAqIEMgLSBKICogQjtcbiAgb3V0WzJdID0gRyAqIEUgLSBIICogQyArIEogKiBBO1xuICBvdXRbM10gPSAtKEcgKiBEKSArIEggKiBCIC0gSSAqIEE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gdmVjNCdzXG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHt2ZWM0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGVycChvdXQsIGEsIGIsIHQpIHtcbiAgdmFyIGF4ID0gYVswXTtcbiAgdmFyIGF5ID0gYVsxXTtcbiAgdmFyIGF6ID0gYVsyXTtcbiAgdmFyIGF3ID0gYVszXTtcbiAgb3V0WzBdID0gYXggKyB0ICogKGJbMF0gLSBheCk7XG4gIG91dFsxXSA9IGF5ICsgdCAqIChiWzFdIC0gYXkpO1xuICBvdXRbMl0gPSBheiArIHQgKiAoYlsyXSAtIGF6KTtcbiAgb3V0WzNdID0gYXcgKyB0ICogKGJbM10gLSBhdyk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSB2ZWN0b3Igd2l0aCB0aGUgZ2l2ZW4gc2NhbGVcbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtOdW1iZXJ9IFtzY2FsZV0gTGVuZ3RoIG9mIHRoZSByZXN1bHRpbmcgdmVjdG9yLiBJZiBvbW1pdHRlZCwgYSB1bml0IHZlY3RvciB3aWxsIGJlIHJldHVybmVkXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbShvdXQsIHNjYWxlKSB7XG4gIHNjYWxlID0gc2NhbGUgfHwgMS4wOyAvLyBNYXJzYWdsaWEsIEdlb3JnZS4gQ2hvb3NpbmcgYSBQb2ludCBmcm9tIHRoZSBTdXJmYWNlIG9mIGFcbiAgLy8gU3BoZXJlLiBBbm4uIE1hdGguIFN0YXRpc3QuIDQzICgxOTcyKSwgbm8uIDIsIDY0NS0tNjQ2LlxuICAvLyBodHRwOi8vcHJvamVjdGV1Y2xpZC5vcmcvZXVjbGlkLmFvbXMvMTE3NzY5MjY0NDtcblxuICB2YXIgdjEsIHYyLCB2MywgdjQ7XG4gIHZhciBzMSwgczI7XG5cbiAgZG8ge1xuICAgIHYxID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyIC0gMTtcbiAgICB2MiA9IGdsTWF0cml4LlJBTkRPTSgpICogMiAtIDE7XG4gICAgczEgPSB2MSAqIHYxICsgdjIgKiB2MjtcbiAgfSB3aGlsZSAoczEgPj0gMSk7XG5cbiAgZG8ge1xuICAgIHYzID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyIC0gMTtcbiAgICB2NCA9IGdsTWF0cml4LlJBTkRPTSgpICogMiAtIDE7XG4gICAgczIgPSB2MyAqIHYzICsgdjQgKiB2NDtcbiAgfSB3aGlsZSAoczIgPj0gMSk7XG5cbiAgdmFyIGQgPSBNYXRoLnNxcnQoKDEgLSBzMSkgLyBzMik7XG4gIG91dFswXSA9IHNjYWxlICogdjE7XG4gIG91dFsxXSA9IHNjYWxlICogdjI7XG4gIG91dFsyXSA9IHNjYWxlICogdjMgKiBkO1xuICBvdXRbM10gPSBzY2FsZSAqIHY0ICogZDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjNCB3aXRoIGEgbWF0NC5cbiAqXG4gKiBAcGFyYW0ge3ZlYzR9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGEgdGhlIHZlY3RvciB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7UmVhZG9ubHlNYXQ0fSBtIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1NYXQ0KG91dCwgYSwgbSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdLFxuICAgICAgdyA9IGFbM107XG4gIG91dFswXSA9IG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzhdICogeiArIG1bMTJdICogdztcbiAgb3V0WzFdID0gbVsxXSAqIHggKyBtWzVdICogeSArIG1bOV0gKiB6ICsgbVsxM10gKiB3O1xuICBvdXRbMl0gPSBtWzJdICogeCArIG1bNl0gKiB5ICsgbVsxMF0gKiB6ICsgbVsxNF0gKiB3O1xuICBvdXRbM10gPSBtWzNdICogeCArIG1bN10gKiB5ICsgbVsxMV0gKiB6ICsgbVsxNV0gKiB3O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWM0IHdpdGggYSBxdWF0XG4gKlxuICogQHBhcmFtIHt2ZWM0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gcSBxdWF0ZXJuaW9uIHRvIHRyYW5zZm9ybSB3aXRoXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVF1YXQob3V0LCBhLCBxKSB7XG4gIHZhciB4ID0gYVswXSxcbiAgICAgIHkgPSBhWzFdLFxuICAgICAgeiA9IGFbMl07XG4gIHZhciBxeCA9IHFbMF0sXG4gICAgICBxeSA9IHFbMV0sXG4gICAgICBxeiA9IHFbMl0sXG4gICAgICBxdyA9IHFbM107IC8vIGNhbGN1bGF0ZSBxdWF0ICogdmVjXG5cbiAgdmFyIGl4ID0gcXcgKiB4ICsgcXkgKiB6IC0gcXogKiB5O1xuICB2YXIgaXkgPSBxdyAqIHkgKyBxeiAqIHggLSBxeCAqIHo7XG4gIHZhciBpeiA9IHF3ICogeiArIHF4ICogeSAtIHF5ICogeDtcbiAgdmFyIGl3ID0gLXF4ICogeCAtIHF5ICogeSAtIHF6ICogejsgLy8gY2FsY3VsYXRlIHJlc3VsdCAqIGludmVyc2UgcXVhdFxuXG4gIG91dFswXSA9IGl4ICogcXcgKyBpdyAqIC1xeCArIGl5ICogLXF6IC0gaXogKiAtcXk7XG4gIG91dFsxXSA9IGl5ICogcXcgKyBpdyAqIC1xeSArIGl6ICogLXF4IC0gaXggKiAtcXo7XG4gIG91dFsyXSA9IGl6ICogcXcgKyBpdyAqIC1xeiArIGl4ICogLXF5IC0gaXkgKiAtcXg7XG4gIG91dFszXSA9IGFbM107XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzQgdG8gemVyb1xuICpcbiAqIEBwYXJhbSB7dmVjNH0gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7dmVjNH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHplcm8ob3V0KSB7XG4gIG91dFswXSA9IDAuMDtcbiAgb3V0WzFdID0gMC4wO1xuICBvdXRbMl0gPSAwLjA7XG4gIG91dFszXSA9IDAuMDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIHZlY3RvciB0byByZXByZXNlbnQgYXMgYSBzdHJpbmdcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cihhKSB7XG4gIHJldHVybiBcInZlYzQoXCIgKyBhWzBdICsgXCIsIFwiICsgYVsxXSArIFwiLCBcIiArIGFbMl0gKyBcIiwgXCIgKyBhWzNdICsgXCIpXCI7XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHZlY3RvcnMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWM0fSBhIFRoZSBmaXJzdCB2ZWN0b3IuXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYiBUaGUgc2Vjb25kIHZlY3Rvci5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXSAmJiBhWzNdID09PSBiWzNdO1xufVxuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB2ZWN0b3JzIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSBlbGVtZW50cyBpbiB0aGUgc2FtZSBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjNH0gYSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtSZWFkb25seVZlYzR9IGIgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxzKGEsIGIpIHtcbiAgdmFyIGEwID0gYVswXSxcbiAgICAgIGExID0gYVsxXSxcbiAgICAgIGEyID0gYVsyXSxcbiAgICAgIGEzID0gYVszXTtcbiAgdmFyIGIwID0gYlswXSxcbiAgICAgIGIxID0gYlsxXSxcbiAgICAgIGIyID0gYlsyXSxcbiAgICAgIGIzID0gYlszXTtcbiAgcmV0dXJuIE1hdGguYWJzKGEwIC0gYjApIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEwKSwgTWF0aC5hYnMoYjApKSAmJiBNYXRoLmFicyhhMSAtIGIxKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMSksIE1hdGguYWJzKGIxKSkgJiYgTWF0aC5hYnMoYTIgLSBiMikgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTIpLCBNYXRoLmFicyhiMikpICYmIE1hdGguYWJzKGEzIC0gYjMpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEzKSwgTWF0aC5hYnMoYjMpKTtcbn1cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzdWIgPSBzdWJ0cmFjdDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0Lm11bHRpcGx5fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBtdWwgPSBtdWx0aXBseTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LmRpdmlkZX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgZGl2ID0gZGl2aWRlO1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQuZGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRpc3QgPSBkaXN0YW5jZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0LnNxdWFyZWREaXN0YW5jZX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3FyRGlzdCA9IHNxdWFyZWREaXN0YW5jZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWM0Lmxlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbGVuID0gbGVuZ3RoO1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzQuc3F1YXJlZExlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3FyTGVuID0gc3F1YXJlZExlbmd0aDtcbi8qKlxuICogUGVyZm9ybSBzb21lIG9wZXJhdGlvbiBvdmVyIGFuIGFycmF5IG9mIHZlYzRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGFycmF5IG9mIHZlY3RvcnMgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0ge051bWJlcn0gc3RyaWRlIE51bWJlciBvZiBlbGVtZW50cyBiZXR3ZWVuIHRoZSBzdGFydCBvZiBlYWNoIHZlYzQuIElmIDAgYXNzdW1lcyB0aWdodGx5IHBhY2tlZFxuICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gc2tpcCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBhcnJheVxuICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50IE51bWJlciBvZiB2ZWM0cyB0byBpdGVyYXRlIG92ZXIuIElmIDAgaXRlcmF0ZXMgb3ZlciBlbnRpcmUgYXJyYXlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggdmVjdG9yIGluIHRoZSBhcnJheVxuICogQHBhcmFtIHtPYmplY3R9IFthcmddIGFkZGl0aW9uYWwgYXJndW1lbnQgdG8gcGFzcyB0byBmblxuICogQHJldHVybnMge0FycmF5fSBhXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB2ZWMgPSBjcmVhdGUoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhLCBzdHJpZGUsIG9mZnNldCwgY291bnQsIGZuLCBhcmcpIHtcbiAgICB2YXIgaSwgbDtcblxuICAgIGlmICghc3RyaWRlKSB7XG4gICAgICBzdHJpZGUgPSA0O1xuICAgIH1cblxuICAgIGlmICghb2Zmc2V0KSB7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgIH1cblxuICAgIGlmIChjb3VudCkge1xuICAgICAgbCA9IE1hdGgubWluKGNvdW50ICogc3RyaWRlICsgb2Zmc2V0LCBhLmxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGwgPSBhLmxlbmd0aDtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBsOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmVjWzBdID0gYVtpXTtcbiAgICAgIHZlY1sxXSA9IGFbaSArIDFdO1xuICAgICAgdmVjWzJdID0gYVtpICsgMl07XG4gICAgICB2ZWNbM10gPSBhW2kgKyAzXTtcbiAgICAgIGZuKHZlYywgdmVjLCBhcmcpO1xuICAgICAgYVtpXSA9IHZlY1swXTtcbiAgICAgIGFbaSArIDFdID0gdmVjWzFdO1xuICAgICAgYVtpICsgMl0gPSB2ZWNbMl07XG4gICAgICBhW2kgKyAzXSA9IHZlY1szXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYTtcbiAgfTtcbn0oKTsiLCJpbXBvcnQgKiBhcyBnbE1hdHJpeCBmcm9tIFwiLi9jb21tb24uanNcIjtcbmltcG9ydCAqIGFzIG1hdDMgZnJvbSBcIi4vbWF0My5qc1wiO1xuaW1wb3J0ICogYXMgdmVjMyBmcm9tIFwiLi92ZWMzLmpzXCI7XG5pbXBvcnQgKiBhcyB2ZWM0IGZyb20gXCIuL3ZlYzQuanNcIjtcbi8qKlxuICogUXVhdGVybmlvblxuICogQG1vZHVsZSBxdWF0XG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGlkZW50aXR5IHF1YXRcbiAqXG4gKiBAcmV0dXJucyB7cXVhdH0gYSBuZXcgcXVhdGVybmlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSg0KTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgfVxuXG4gIG91dFszXSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldCBhIHF1YXQgdG8gdGhlIGlkZW50aXR5IHF1YXRlcm5pb25cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHkob3V0KSB7XG4gIG91dFswXSA9IDA7XG4gIG91dFsxXSA9IDA7XG4gIG91dFsyXSA9IDA7XG4gIG91dFszXSA9IDE7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNldHMgYSBxdWF0IGZyb20gdGhlIGdpdmVuIGFuZ2xlIGFuZCByb3RhdGlvbiBheGlzLFxuICogdGhlbiByZXR1cm5zIGl0LlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGF4aXMgdGhlIGF4aXMgYXJvdW5kIHdoaWNoIHRvIHJvdGF0ZVxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCB0aGUgYW5nbGUgaW4gcmFkaWFuc1xuICogQHJldHVybnMge3F1YXR9IG91dFxuICoqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0QXhpc0FuZ2xlKG91dCwgYXhpcywgcmFkKSB7XG4gIHJhZCA9IHJhZCAqIDAuNTtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQpO1xuICBvdXRbMF0gPSBzICogYXhpc1swXTtcbiAgb3V0WzFdID0gcyAqIGF4aXNbMV07XG4gIG91dFsyXSA9IHMgKiBheGlzWzJdO1xuICBvdXRbM10gPSBNYXRoLmNvcyhyYWQpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBHZXRzIHRoZSByb3RhdGlvbiBheGlzIGFuZCBhbmdsZSBmb3IgYSBnaXZlblxuICogIHF1YXRlcm5pb24uIElmIGEgcXVhdGVybmlvbiBpcyBjcmVhdGVkIHdpdGhcbiAqICBzZXRBeGlzQW5nbGUsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSBzYW1lXG4gKiAgdmFsdWVzIGFzIHByb3ZpZGllZCBpbiB0aGUgb3JpZ2luYWwgcGFyYW1ldGVyIGxpc3RcbiAqICBPUiBmdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB2YWx1ZXMuXG4gKiBFeGFtcGxlOiBUaGUgcXVhdGVybmlvbiBmb3JtZWQgYnkgYXhpcyBbMCwgMCwgMV0gYW5kXG4gKiAgYW5nbGUgLTkwIGlzIHRoZSBzYW1lIGFzIHRoZSBxdWF0ZXJuaW9uIGZvcm1lZCBieVxuICogIFswLCAwLCAxXSBhbmQgMjcwLiBUaGlzIG1ldGhvZCBmYXZvcnMgdGhlIGxhdHRlci5cbiAqIEBwYXJhbSAge3ZlYzN9IG91dF9heGlzICBWZWN0b3IgcmVjZWl2aW5nIHRoZSBheGlzIG9mIHJvdGF0aW9uXG4gKiBAcGFyYW0gIHtSZWFkb25seVF1YXR9IHEgICAgIFF1YXRlcm5pb24gdG8gYmUgZGVjb21wb3NlZFxuICogQHJldHVybiB7TnVtYmVyfSAgICAgQW5nbGUsIGluIHJhZGlhbnMsIG9mIHRoZSByb3RhdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBeGlzQW5nbGUob3V0X2F4aXMsIHEpIHtcbiAgdmFyIHJhZCA9IE1hdGguYWNvcyhxWzNdKSAqIDIuMDtcbiAgdmFyIHMgPSBNYXRoLnNpbihyYWQgLyAyLjApO1xuXG4gIGlmIChzID4gZ2xNYXRyaXguRVBTSUxPTikge1xuICAgIG91dF9heGlzWzBdID0gcVswXSAvIHM7XG4gICAgb3V0X2F4aXNbMV0gPSBxWzFdIC8gcztcbiAgICBvdXRfYXhpc1syXSA9IHFbMl0gLyBzO1xuICB9IGVsc2Uge1xuICAgIC8vIElmIHMgaXMgemVybywgcmV0dXJuIGFueSBheGlzIChubyByb3RhdGlvbiAtIGF4aXMgZG9lcyBub3QgbWF0dGVyKVxuICAgIG91dF9heGlzWzBdID0gMTtcbiAgICBvdXRfYXhpc1sxXSA9IDA7XG4gICAgb3V0X2F4aXNbMl0gPSAwO1xuICB9XG5cbiAgcmV0dXJuIHJhZDtcbn1cbi8qKlxuICogR2V0cyB0aGUgYW5ndWxhciBkaXN0YW5jZSBiZXR3ZWVuIHR3byB1bml0IHF1YXRlcm5pb25zXG4gKlxuICogQHBhcmFtICB7UmVhZG9ubHlRdWF0fSBhICAgICBPcmlnaW4gdW5pdCBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0gIHtSZWFkb25seVF1YXR9IGIgICAgIERlc3RpbmF0aW9uIHVuaXQgcXVhdGVybmlvblxuICogQHJldHVybiB7TnVtYmVyfSAgICAgQW5nbGUsIGluIHJhZGlhbnMsIGJldHdlZW4gdGhlIHR3byBxdWF0ZXJuaW9uc1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBbmdsZShhLCBiKSB7XG4gIHZhciBkb3Rwcm9kdWN0ID0gZG90KGEsIGIpO1xuICByZXR1cm4gTWF0aC5hY29zKDIgKiBkb3Rwcm9kdWN0ICogZG90cHJvZHVjdCAtIDEpO1xufVxuLyoqXG4gKiBNdWx0aXBsaWVzIHR3byBxdWF0J3NcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl0sXG4gICAgICBhdyA9IGFbM107XG4gIHZhciBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICBieiA9IGJbMl0sXG4gICAgICBidyA9IGJbM107XG4gIG91dFswXSA9IGF4ICogYncgKyBhdyAqIGJ4ICsgYXkgKiBieiAtIGF6ICogYnk7XG4gIG91dFsxXSA9IGF5ICogYncgKyBhdyAqIGJ5ICsgYXogKiBieCAtIGF4ICogYno7XG4gIG91dFsyXSA9IGF6ICogYncgKyBhdyAqIGJ6ICsgYXggKiBieSAtIGF5ICogYng7XG4gIG91dFszXSA9IGF3ICogYncgLSBheCAqIGJ4IC0gYXkgKiBieSAtIGF6ICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZXMgYSBxdWF0ZXJuaW9uIGJ5IHRoZSBnaXZlbiBhbmdsZSBhYm91dCB0aGUgWCBheGlzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgcXVhdCByZWNlaXZpbmcgb3BlcmF0aW9uIHJlc3VsdFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byByb3RhdGVcbiAqIEBwYXJhbSB7bnVtYmVyfSByYWQgYW5nbGUgKGluIHJhZGlhbnMpIHRvIHJvdGF0ZVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVYKG91dCwgYSwgcmFkKSB7XG4gIHJhZCAqPSAwLjU7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl0sXG4gICAgICBhdyA9IGFbM107XG4gIHZhciBieCA9IE1hdGguc2luKHJhZCksXG4gICAgICBidyA9IE1hdGguY29zKHJhZCk7XG4gIG91dFswXSA9IGF4ICogYncgKyBhdyAqIGJ4O1xuICBvdXRbMV0gPSBheSAqIGJ3ICsgYXogKiBieDtcbiAgb3V0WzJdID0gYXogKiBidyAtIGF5ICogYng7XG4gIG91dFszXSA9IGF3ICogYncgLSBheCAqIGJ4O1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGVzIGEgcXVhdGVybmlvbiBieSB0aGUgZ2l2ZW4gYW5nbGUgYWJvdXQgdGhlIFkgYXhpc1xuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHF1YXQgcmVjZWl2aW5nIG9wZXJhdGlvbiByZXN1bHRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkIGFuZ2xlIChpbiByYWRpYW5zKSB0byByb3RhdGVcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWShvdXQsIGEsIHJhZCkge1xuICByYWQgKj0gMC41O1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdLFxuICAgICAgYXcgPSBhWzNdO1xuICB2YXIgYnkgPSBNYXRoLnNpbihyYWQpLFxuICAgICAgYncgPSBNYXRoLmNvcyhyYWQpO1xuICBvdXRbMF0gPSBheCAqIGJ3IC0gYXogKiBieTtcbiAgb3V0WzFdID0gYXkgKiBidyArIGF3ICogYnk7XG4gIG91dFsyXSA9IGF6ICogYncgKyBheCAqIGJ5O1xuICBvdXRbM10gPSBhdyAqIGJ3IC0gYXkgKiBieTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlcyBhIHF1YXRlcm5pb24gYnkgdGhlIGdpdmVuIGFuZ2xlIGFib3V0IHRoZSBaIGF4aXNcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCBxdWF0IHJlY2VpdmluZyBvcGVyYXRpb24gcmVzdWx0XG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IHJhZCBhbmdsZSAoaW4gcmFkaWFucykgdG8gcm90YXRlXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVoob3V0LCBhLCByYWQpIHtcbiAgcmFkICo9IDAuNTtcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgdmFyIGJ6ID0gTWF0aC5zaW4ocmFkKSxcbiAgICAgIGJ3ID0gTWF0aC5jb3MocmFkKTtcbiAgb3V0WzBdID0gYXggKiBidyArIGF5ICogYno7XG4gIG91dFsxXSA9IGF5ICogYncgLSBheCAqIGJ6O1xuICBvdXRbMl0gPSBheiAqIGJ3ICsgYXcgKiBiejtcbiAgb3V0WzNdID0gYXcgKiBidyAtIGF6ICogYno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIFcgY29tcG9uZW50IG9mIGEgcXVhdCBmcm9tIHRoZSBYLCBZLCBhbmQgWiBjb21wb25lbnRzLlxuICogQXNzdW1lcyB0aGF0IHF1YXRlcm5pb24gaXMgMSB1bml0IGluIGxlbmd0aC5cbiAqIEFueSBleGlzdGluZyBXIGNvbXBvbmVudCB3aWxsIGJlIGlnbm9yZWQuXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBXIGNvbXBvbmVudCBvZlxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVXKG91dCwgYSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdO1xuICBvdXRbMF0gPSB4O1xuICBvdXRbMV0gPSB5O1xuICBvdXRbMl0gPSB6O1xuICBvdXRbM10gPSBNYXRoLnNxcnQoTWF0aC5hYnMoMS4wIC0geCAqIHggLSB5ICogeSAtIHogKiB6KSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgZXhwb25lbnRpYWwgb2YgYSB1bml0IHF1YXRlcm5pb24uXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSB0aGUgZXhwb25lbnRpYWwgb2ZcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhwKG91dCwgYSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdLFxuICAgICAgdyA9IGFbM107XG4gIHZhciByID0gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkgKyB6ICogeik7XG4gIHZhciBldCA9IE1hdGguZXhwKHcpO1xuICB2YXIgcyA9IHIgPiAwID8gZXQgKiBNYXRoLnNpbihyKSAvIHIgOiAwO1xuICBvdXRbMF0gPSB4ICogcztcbiAgb3V0WzFdID0geSAqIHM7XG4gIG91dFsyXSA9IHogKiBzO1xuICBvdXRbM10gPSBldCAqIE1hdGguY29zKHIpO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIGEgdW5pdCBxdWF0ZXJuaW9uLlxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdCB0byBjYWxjdWxhdGUgdGhlIGV4cG9uZW50aWFsIG9mXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxuKG91dCwgYSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdLFxuICAgICAgdyA9IGFbM107XG4gIHZhciByID0gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkgKyB6ICogeik7XG4gIHZhciB0ID0gciA+IDAgPyBNYXRoLmF0YW4yKHIsIHcpIC8gciA6IDA7XG4gIG91dFswXSA9IHggKiB0O1xuICBvdXRbMV0gPSB5ICogdDtcbiAgb3V0WzJdID0geiAqIHQ7XG4gIG91dFszXSA9IDAuNSAqIE1hdGgubG9nKHggKiB4ICsgeSAqIHkgKyB6ICogeiArIHcgKiB3KTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBzY2FsYXIgcG93ZXIgb2YgYSB1bml0IHF1YXRlcm5pb24uXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSB0aGUgZXhwb25lbnRpYWwgb2ZcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgcXVhdGVybmlvbiBieVxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBwb3cob3V0LCBhLCBiKSB7XG4gIGxuKG91dCwgYSk7XG4gIHNjYWxlKG91dCwgb3V0LCBiKTtcbiAgZXhwKG91dCwgb3V0KTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUGVyZm9ybXMgYSBzcGhlcmljYWwgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gcXVhdFxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzbGVycChvdXQsIGEsIGIsIHQpIHtcbiAgLy8gYmVuY2htYXJrczpcbiAgLy8gICAgaHR0cDovL2pzcGVyZi5jb20vcXVhdGVybmlvbi1zbGVycC1pbXBsZW1lbnRhdGlvbnNcbiAgdmFyIGF4ID0gYVswXSxcbiAgICAgIGF5ID0gYVsxXSxcbiAgICAgIGF6ID0gYVsyXSxcbiAgICAgIGF3ID0gYVszXTtcbiAgdmFyIGJ4ID0gYlswXSxcbiAgICAgIGJ5ID0gYlsxXSxcbiAgICAgIGJ6ID0gYlsyXSxcbiAgICAgIGJ3ID0gYlszXTtcbiAgdmFyIG9tZWdhLCBjb3NvbSwgc2lub20sIHNjYWxlMCwgc2NhbGUxOyAvLyBjYWxjIGNvc2luZVxuXG4gIGNvc29tID0gYXggKiBieCArIGF5ICogYnkgKyBheiAqIGJ6ICsgYXcgKiBidzsgLy8gYWRqdXN0IHNpZ25zIChpZiBuZWNlc3NhcnkpXG5cbiAgaWYgKGNvc29tIDwgMC4wKSB7XG4gICAgY29zb20gPSAtY29zb207XG4gICAgYnggPSAtYng7XG4gICAgYnkgPSAtYnk7XG4gICAgYnogPSAtYno7XG4gICAgYncgPSAtYnc7XG4gIH0gLy8gY2FsY3VsYXRlIGNvZWZmaWNpZW50c1xuXG5cbiAgaWYgKDEuMCAtIGNvc29tID4gZ2xNYXRyaXguRVBTSUxPTikge1xuICAgIC8vIHN0YW5kYXJkIGNhc2UgKHNsZXJwKVxuICAgIG9tZWdhID0gTWF0aC5hY29zKGNvc29tKTtcbiAgICBzaW5vbSA9IE1hdGguc2luKG9tZWdhKTtcbiAgICBzY2FsZTAgPSBNYXRoLnNpbigoMS4wIC0gdCkgKiBvbWVnYSkgLyBzaW5vbTtcbiAgICBzY2FsZTEgPSBNYXRoLnNpbih0ICogb21lZ2EpIC8gc2lub207XG4gIH0gZWxzZSB7XG4gICAgLy8gXCJmcm9tXCIgYW5kIFwidG9cIiBxdWF0ZXJuaW9ucyBhcmUgdmVyeSBjbG9zZVxuICAgIC8vICAuLi4gc28gd2UgY2FuIGRvIGEgbGluZWFyIGludGVycG9sYXRpb25cbiAgICBzY2FsZTAgPSAxLjAgLSB0O1xuICAgIHNjYWxlMSA9IHQ7XG4gIH0gLy8gY2FsY3VsYXRlIGZpbmFsIHZhbHVlc1xuXG5cbiAgb3V0WzBdID0gc2NhbGUwICogYXggKyBzY2FsZTEgKiBieDtcbiAgb3V0WzFdID0gc2NhbGUwICogYXkgKyBzY2FsZTEgKiBieTtcbiAgb3V0WzJdID0gc2NhbGUwICogYXogKyBzY2FsZTEgKiBiejtcbiAgb3V0WzNdID0gc2NhbGUwICogYXcgKyBzY2FsZTEgKiBidztcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHVuaXQgcXVhdGVybmlvblxuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb20ob3V0KSB7XG4gIC8vIEltcGxlbWVudGF0aW9uIG9mIGh0dHA6Ly9wbGFubmluZy5jcy51aXVjLmVkdS9ub2RlMTk4Lmh0bWxcbiAgLy8gVE9ETzogQ2FsbGluZyByYW5kb20gMyB0aW1lcyBpcyBwcm9iYWJseSBub3QgdGhlIGZhc3Rlc3Qgc29sdXRpb25cbiAgdmFyIHUxID0gZ2xNYXRyaXguUkFORE9NKCk7XG4gIHZhciB1MiA9IGdsTWF0cml4LlJBTkRPTSgpO1xuICB2YXIgdTMgPSBnbE1hdHJpeC5SQU5ET00oKTtcbiAgdmFyIHNxcnQxTWludXNVMSA9IE1hdGguc3FydCgxIC0gdTEpO1xuICB2YXIgc3FydFUxID0gTWF0aC5zcXJ0KHUxKTtcbiAgb3V0WzBdID0gc3FydDFNaW51c1UxICogTWF0aC5zaW4oMi4wICogTWF0aC5QSSAqIHUyKTtcbiAgb3V0WzFdID0gc3FydDFNaW51c1UxICogTWF0aC5jb3MoMi4wICogTWF0aC5QSSAqIHUyKTtcbiAgb3V0WzJdID0gc3FydFUxICogTWF0aC5zaW4oMi4wICogTWF0aC5QSSAqIHUzKTtcbiAgb3V0WzNdID0gc3FydFUxICogTWF0aC5jb3MoMi4wICogTWF0aC5QSSAqIHUzKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgaW52ZXJzZSBvZiBhIHF1YXRcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXQgdG8gY2FsY3VsYXRlIGludmVyc2Ugb2ZcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW52ZXJ0KG91dCwgYSkge1xuICB2YXIgYTAgPSBhWzBdLFxuICAgICAgYTEgPSBhWzFdLFxuICAgICAgYTIgPSBhWzJdLFxuICAgICAgYTMgPSBhWzNdO1xuICB2YXIgZG90ID0gYTAgKiBhMCArIGExICogYTEgKyBhMiAqIGEyICsgYTMgKiBhMztcbiAgdmFyIGludkRvdCA9IGRvdCA/IDEuMCAvIGRvdCA6IDA7IC8vIFRPRE86IFdvdWxkIGJlIGZhc3RlciB0byByZXR1cm4gWzAsMCwwLDBdIGltbWVkaWF0ZWx5IGlmIGRvdCA9PSAwXG5cbiAgb3V0WzBdID0gLWEwICogaW52RG90O1xuICBvdXRbMV0gPSAtYTEgKiBpbnZEb3Q7XG4gIG91dFsyXSA9IC1hMiAqIGludkRvdDtcbiAgb3V0WzNdID0gYTMgKiBpbnZEb3Q7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGNvbmp1Z2F0ZSBvZiBhIHF1YXRcbiAqIElmIHRoZSBxdWF0ZXJuaW9uIGlzIG5vcm1hbGl6ZWQsIHRoaXMgZnVuY3Rpb24gaXMgZmFzdGVyIHRoYW4gcXVhdC5pbnZlcnNlIGFuZCBwcm9kdWNlcyB0aGUgc2FtZSByZXN1bHQuXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSBxdWF0IHRvIGNhbGN1bGF0ZSBjb25qdWdhdGUgb2ZcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29uanVnYXRlKG91dCwgYSkge1xuICBvdXRbMF0gPSAtYVswXTtcbiAgb3V0WzFdID0gLWFbMV07XG4gIG91dFsyXSA9IC1hWzJdO1xuICBvdXRbM10gPSBhWzNdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgcXVhdGVybmlvbiBmcm9tIHRoZSBnaXZlbiAzeDMgcm90YXRpb24gbWF0cml4LlxuICpcbiAqIE5PVEU6IFRoZSByZXN1bHRhbnQgcXVhdGVybmlvbiBpcyBub3Qgbm9ybWFsaXplZCwgc28geW91IHNob3VsZCBiZSBzdXJlXG4gKiB0byByZW5vcm1hbGl6ZSB0aGUgcXVhdGVybmlvbiB5b3Vyc2VsZiB3aGVyZSBuZWNlc3NhcnkuXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gbSByb3RhdGlvbiBtYXRyaXhcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tTWF0MyhvdXQsIG0pIHtcbiAgLy8gQWxnb3JpdGhtIGluIEtlbiBTaG9lbWFrZSdzIGFydGljbGUgaW4gMTk4NyBTSUdHUkFQSCBjb3Vyc2Ugbm90ZXNcbiAgLy8gYXJ0aWNsZSBcIlF1YXRlcm5pb24gQ2FsY3VsdXMgYW5kIEZhc3QgQW5pbWF0aW9uXCIuXG4gIHZhciBmVHJhY2UgPSBtWzBdICsgbVs0XSArIG1bOF07XG4gIHZhciBmUm9vdDtcblxuICBpZiAoZlRyYWNlID4gMC4wKSB7XG4gICAgLy8gfHd8ID4gMS8yLCBtYXkgYXMgd2VsbCBjaG9vc2UgdyA+IDEvMlxuICAgIGZSb290ID0gTWF0aC5zcXJ0KGZUcmFjZSArIDEuMCk7IC8vIDJ3XG5cbiAgICBvdXRbM10gPSAwLjUgKiBmUm9vdDtcbiAgICBmUm9vdCA9IDAuNSAvIGZSb290OyAvLyAxLyg0dylcblxuICAgIG91dFswXSA9IChtWzVdIC0gbVs3XSkgKiBmUm9vdDtcbiAgICBvdXRbMV0gPSAobVs2XSAtIG1bMl0pICogZlJvb3Q7XG4gICAgb3V0WzJdID0gKG1bMV0gLSBtWzNdKSAqIGZSb290O1xuICB9IGVsc2Uge1xuICAgIC8vIHx3fCA8PSAxLzJcbiAgICB2YXIgaSA9IDA7XG4gICAgaWYgKG1bNF0gPiBtWzBdKSBpID0gMTtcbiAgICBpZiAobVs4XSA+IG1baSAqIDMgKyBpXSkgaSA9IDI7XG4gICAgdmFyIGogPSAoaSArIDEpICUgMztcbiAgICB2YXIgayA9IChpICsgMikgJSAzO1xuICAgIGZSb290ID0gTWF0aC5zcXJ0KG1baSAqIDMgKyBpXSAtIG1baiAqIDMgKyBqXSAtIG1bayAqIDMgKyBrXSArIDEuMCk7XG4gICAgb3V0W2ldID0gMC41ICogZlJvb3Q7XG4gICAgZlJvb3QgPSAwLjUgLyBmUm9vdDtcbiAgICBvdXRbM10gPSAobVtqICogMyArIGtdIC0gbVtrICogMyArIGpdKSAqIGZSb290O1xuICAgIG91dFtqXSA9IChtW2ogKiAzICsgaV0gKyBtW2kgKiAzICsgal0pICogZlJvb3Q7XG4gICAgb3V0W2tdID0gKG1bayAqIDMgKyBpXSArIG1baSAqIDMgKyBrXSkgKiBmUm9vdDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBxdWF0ZXJuaW9uIGZyb20gdGhlIGdpdmVuIGV1bGVyIGFuZ2xlIHgsIHksIHouXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge3h9IEFuZ2xlIHRvIHJvdGF0ZSBhcm91bmQgWCBheGlzIGluIGRlZ3JlZXMuXG4gKiBAcGFyYW0ge3l9IEFuZ2xlIHRvIHJvdGF0ZSBhcm91bmQgWSBheGlzIGluIGRlZ3JlZXMuXG4gKiBAcGFyYW0ge3p9IEFuZ2xlIHRvIHJvdGF0ZSBhcm91bmQgWiBheGlzIGluIGRlZ3JlZXMuXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUV1bGVyKG91dCwgeCwgeSwgeikge1xuICB2YXIgaGFsZlRvUmFkID0gMC41ICogTWF0aC5QSSAvIDE4MC4wO1xuICB4ICo9IGhhbGZUb1JhZDtcbiAgeSAqPSBoYWxmVG9SYWQ7XG4gIHogKj0gaGFsZlRvUmFkO1xuICB2YXIgc3ggPSBNYXRoLnNpbih4KTtcbiAgdmFyIGN4ID0gTWF0aC5jb3MoeCk7XG4gIHZhciBzeSA9IE1hdGguc2luKHkpO1xuICB2YXIgY3kgPSBNYXRoLmNvcyh5KTtcbiAgdmFyIHN6ID0gTWF0aC5zaW4oeik7XG4gIHZhciBjeiA9IE1hdGguY29zKHopO1xuICBvdXRbMF0gPSBzeCAqIGN5ICogY3ogLSBjeCAqIHN5ICogc3o7XG4gIG91dFsxXSA9IGN4ICogc3kgKiBjeiArIHN4ICogY3kgKiBzejtcbiAgb3V0WzJdID0gY3ggKiBjeSAqIHN6IC0gc3ggKiBzeSAqIGN6O1xuICBvdXRbM10gPSBjeCAqIGN5ICogY3ogKyBzeCAqIHN5ICogc3o7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBxdWF0ZW5pb25cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJxdWF0KFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIsIFwiICsgYVszXSArIFwiKVwiO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHF1YXQgaW5pdGlhbGl6ZWQgd2l0aCB2YWx1ZXMgZnJvbSBhbiBleGlzdGluZyBxdWF0ZXJuaW9uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgcXVhdGVybmlvbiB0byBjbG9uZVxuICogQHJldHVybnMge3F1YXR9IGEgbmV3IHF1YXRlcm5pb25cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgY2xvbmUgPSB2ZWM0LmNsb25lO1xuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHF1YXQgaW5pdGlhbGl6ZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHcgVyBjb21wb25lbnRcbiAqIEByZXR1cm5zIHtxdWF0fSBhIG5ldyBxdWF0ZXJuaW9uXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGZyb21WYWx1ZXMgPSB2ZWM0LmZyb21WYWx1ZXM7XG4vKipcbiAqIENvcHkgdGhlIHZhbHVlcyBmcm9tIG9uZSBxdWF0IHRvIGFub3RoZXJcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBzb3VyY2UgcXVhdGVybmlvblxuICogQHJldHVybnMge3F1YXR9IG91dFxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBjb3B5ID0gdmVjNC5jb3B5O1xuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSBxdWF0IHRvIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB3IFcgY29tcG9uZW50XG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNldCA9IHZlYzQuc2V0O1xuLyoqXG4gKiBBZGRzIHR3byBxdWF0J3NcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgYWRkID0gdmVjNC5hZGQ7XG4vKipcbiAqIEFsaWFzIGZvciB7QGxpbmsgcXVhdC5tdWx0aXBseX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbXVsID0gbXVsdGlwbHk7XG4vKipcbiAqIFNjYWxlcyBhIHF1YXQgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgdmVjdG9yIGJ5XG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNjYWxlID0gdmVjNC5zY2FsZTtcbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZG90IHByb2R1Y3Qgb2YgdHdvIHF1YXQnc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRvdCBwcm9kdWN0IG9mIGEgYW5kIGJcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgZG90ID0gdmVjNC5kb3Q7XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gcXVhdCdzXG4gKlxuICogQHBhcmFtIHtxdWF0fSBvdXQgdGhlIHJlY2VpdmluZyBxdWF0ZXJuaW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcGFyYW0ge051bWJlcn0gdCBpbnRlcnBvbGF0aW9uIGFtb3VudCwgaW4gdGhlIHJhbmdlIFswLTFdLCBiZXR3ZWVuIHRoZSB0d28gaW5wdXRzXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGxlcnAgPSB2ZWM0LmxlcnA7XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiBhIHF1YXRcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIGxlbmd0aCBvZlxuICogQHJldHVybnMge051bWJlcn0gbGVuZ3RoIG9mIGFcbiAqL1xuXG5leHBvcnQgdmFyIGxlbmd0aCA9IHZlYzQubGVuZ3RoO1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHF1YXQubGVuZ3RofVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBsZW4gPSBsZW5ndGg7XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNxdWFyZWQgbGVuZ3RoIG9mIGEgcXVhdFxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHZlY3RvciB0byBjYWxjdWxhdGUgc3F1YXJlZCBsZW5ndGggb2ZcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IHNxdWFyZWQgbGVuZ3RoIG9mIGFcbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3F1YXJlZExlbmd0aCA9IHZlYzQuc3F1YXJlZExlbmd0aDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayBxdWF0LnNxdWFyZWRMZW5ndGh9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIHNxckxlbiA9IHNxdWFyZWRMZW5ndGg7XG4vKipcbiAqIE5vcm1hbGl6ZSBhIHF1YXRcbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIHF1YXRlcm5pb24gdG8gbm9ybWFsaXplXG4gKiBAcmV0dXJucyB7cXVhdH0gb3V0XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIG5vcm1hbGl6ZSA9IHZlYzQubm9ybWFsaXplO1xuLyoqXG4gKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBxdWF0ZXJuaW9ucyBoYXZlIGV4YWN0bHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24gKHdoZW4gY29tcGFyZWQgd2l0aCA9PT0pXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgVGhlIGZpcnN0IHF1YXRlcm5pb24uXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiBUaGUgc2Vjb25kIHF1YXRlcm5pb24uXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmVjdG9ycyBhcmUgZXF1YWwsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuXG5leHBvcnQgdmFyIGV4YWN0RXF1YWxzID0gdmVjNC5leGFjdEVxdWFscztcbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgcXVhdGVybmlvbnMgaGF2ZSBhcHByb3hpbWF0ZWx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBhIFRoZSBmaXJzdCB2ZWN0b3IuXG4gKiBAcGFyYW0ge1JlYWRvbmx5UXVhdH0gYiBUaGUgc2Vjb25kIHZlY3Rvci5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCB2YXIgZXF1YWxzID0gdmVjNC5lcXVhbHM7XG4vKipcbiAqIFNldHMgYSBxdWF0ZXJuaW9uIHRvIHJlcHJlc2VudCB0aGUgc2hvcnRlc3Qgcm90YXRpb24gZnJvbSBvbmVcbiAqIHZlY3RvciB0byBhbm90aGVyLlxuICpcbiAqIEJvdGggdmVjdG9ycyBhcmUgYXNzdW1lZCB0byBiZSB1bml0IGxlbmd0aC5cbiAqXG4gKiBAcGFyYW0ge3F1YXR9IG91dCB0aGUgcmVjZWl2aW5nIHF1YXRlcm5pb24uXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgaW5pdGlhbCB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBkZXN0aW5hdGlvbiB2ZWN0b3JcbiAqIEByZXR1cm5zIHtxdWF0fSBvdXRcbiAqL1xuXG5leHBvcnQgdmFyIHJvdGF0aW9uVG8gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0bXB2ZWMzID0gdmVjMy5jcmVhdGUoKTtcbiAgdmFyIHhVbml0VmVjMyA9IHZlYzMuZnJvbVZhbHVlcygxLCAwLCAwKTtcbiAgdmFyIHlVbml0VmVjMyA9IHZlYzMuZnJvbVZhbHVlcygwLCAxLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvdXQsIGEsIGIpIHtcbiAgICB2YXIgZG90ID0gdmVjMy5kb3QoYSwgYik7XG5cbiAgICBpZiAoZG90IDwgLTAuOTk5OTk5KSB7XG4gICAgICB2ZWMzLmNyb3NzKHRtcHZlYzMsIHhVbml0VmVjMywgYSk7XG4gICAgICBpZiAodmVjMy5sZW4odG1wdmVjMykgPCAwLjAwMDAwMSkgdmVjMy5jcm9zcyh0bXB2ZWMzLCB5VW5pdFZlYzMsIGEpO1xuICAgICAgdmVjMy5ub3JtYWxpemUodG1wdmVjMywgdG1wdmVjMyk7XG4gICAgICBzZXRBeGlzQW5nbGUob3V0LCB0bXB2ZWMzLCBNYXRoLlBJKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfSBlbHNlIGlmIChkb3QgPiAwLjk5OTk5OSkge1xuICAgICAgb3V0WzBdID0gMDtcbiAgICAgIG91dFsxXSA9IDA7XG4gICAgICBvdXRbMl0gPSAwO1xuICAgICAgb3V0WzNdID0gMTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZlYzMuY3Jvc3ModG1wdmVjMywgYSwgYik7XG4gICAgICBvdXRbMF0gPSB0bXB2ZWMzWzBdO1xuICAgICAgb3V0WzFdID0gdG1wdmVjM1sxXTtcbiAgICAgIG91dFsyXSA9IHRtcHZlYzNbMl07XG4gICAgICBvdXRbM10gPSAxICsgZG90O1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZShvdXQsIG91dCk7XG4gICAgfVxuICB9O1xufSgpO1xuLyoqXG4gKiBQZXJmb3JtcyBhIHNwaGVyaWNhbCBsaW5lYXIgaW50ZXJwb2xhdGlvbiB3aXRoIHR3byBjb250cm9sIHBvaW50c1xuICpcbiAqIEBwYXJhbSB7cXVhdH0gb3V0IHRoZSByZWNlaXZpbmcgcXVhdGVybmlvblxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IGMgdGhlIHRoaXJkIG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlRdWF0fSBkIHRoZSBmb3VydGggb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCB2YXIgc3FsZXJwID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdGVtcDEgPSBjcmVhdGUoKTtcbiAgdmFyIHRlbXAyID0gY3JlYXRlKCk7XG4gIHJldHVybiBmdW5jdGlvbiAob3V0LCBhLCBiLCBjLCBkLCB0KSB7XG4gICAgc2xlcnAodGVtcDEsIGEsIGQsIHQpO1xuICAgIHNsZXJwKHRlbXAyLCBiLCBjLCB0KTtcbiAgICBzbGVycChvdXQsIHRlbXAxLCB0ZW1wMiwgMiAqIHQgKiAoMSAtIHQpKTtcbiAgICByZXR1cm4gb3V0O1xuICB9O1xufSgpO1xuLyoqXG4gKiBTZXRzIHRoZSBzcGVjaWZpZWQgcXVhdGVybmlvbiB3aXRoIHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlblxuICogYXhlcy4gRWFjaCBheGlzIGlzIGEgdmVjMyBhbmQgaXMgZXhwZWN0ZWQgdG8gYmUgdW5pdCBsZW5ndGggYW5kXG4gKiBwZXJwZW5kaWN1bGFyIHRvIGFsbCBvdGhlciBzcGVjaWZpZWQgYXhlcy5cbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gdmlldyAgdGhlIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIHZpZXdpbmcgZGlyZWN0aW9uXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gcmlnaHQgdGhlIHZlY3RvciByZXByZXNlbnRpbmcgdGhlIGxvY2FsIFwicmlnaHRcIiBkaXJlY3Rpb25cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSB1cCAgICB0aGUgdmVjdG9yIHJlcHJlc2VudGluZyB0aGUgbG9jYWwgXCJ1cFwiIGRpcmVjdGlvblxuICogQHJldHVybnMge3F1YXR9IG91dFxuICovXG5cbmV4cG9ydCB2YXIgc2V0QXhlcyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG1hdHIgPSBtYXQzLmNyZWF0ZSgpO1xuICByZXR1cm4gZnVuY3Rpb24gKG91dCwgdmlldywgcmlnaHQsIHVwKSB7XG4gICAgbWF0clswXSA9IHJpZ2h0WzBdO1xuICAgIG1hdHJbM10gPSByaWdodFsxXTtcbiAgICBtYXRyWzZdID0gcmlnaHRbMl07XG4gICAgbWF0clsxXSA9IHVwWzBdO1xuICAgIG1hdHJbNF0gPSB1cFsxXTtcbiAgICBtYXRyWzddID0gdXBbMl07XG4gICAgbWF0clsyXSA9IC12aWV3WzBdO1xuICAgIG1hdHJbNV0gPSAtdmlld1sxXTtcbiAgICBtYXRyWzhdID0gLXZpZXdbMl07XG4gICAgcmV0dXJuIG5vcm1hbGl6ZShvdXQsIGZyb21NYXQzKG91dCwgbWF0cikpO1xuICB9O1xufSgpOyIsImltcG9ydCAqIGFzIGdsTWF0cml4IGZyb20gXCIuL2NvbW1vbi5qc1wiO1xuaW1wb3J0ICogYXMgbWF0MiBmcm9tIFwiLi9tYXQyLmpzXCI7XG5pbXBvcnQgKiBhcyBtYXQyZCBmcm9tIFwiLi9tYXQyZC5qc1wiO1xuaW1wb3J0ICogYXMgbWF0MyBmcm9tIFwiLi9tYXQzLmpzXCI7XG5pbXBvcnQgKiBhcyBtYXQ0IGZyb20gXCIuL21hdDQuanNcIjtcbmltcG9ydCAqIGFzIHF1YXQgZnJvbSBcIi4vcXVhdC5qc1wiO1xuaW1wb3J0ICogYXMgcXVhdDIgZnJvbSBcIi4vcXVhdDIuanNcIjtcbmltcG9ydCAqIGFzIHZlYzIgZnJvbSBcIi4vdmVjMi5qc1wiO1xuaW1wb3J0ICogYXMgdmVjMyBmcm9tIFwiLi92ZWMzLmpzXCI7XG5pbXBvcnQgKiBhcyB2ZWM0IGZyb20gXCIuL3ZlYzQuanNcIjtcbmV4cG9ydCB7IGdsTWF0cml4LCBtYXQyLCBtYXQyZCwgbWF0MywgbWF0NCwgcXVhdCwgcXVhdDIsIHZlYzIsIHZlYzMsIHZlYzQgfTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AST_TOKEN_TYPES", function() { return AST_TOKEN_TYPES; });\n/* unused harmony export AST_NODE_TYPES */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "STORAGE_CLASS", function() { return STORAGE_CLASS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Target", function() { return Target; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefineValuePlaceholder", function() { return DefineValuePlaceholder; });\n/* harmony import */ var reflect_metadata__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(239);\n/* harmony import */ var reflect_metadata__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(reflect_metadata__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _ComponentManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25);\n/* harmony import */ var _components_framegraph_System__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(135);\n/* harmony import */ var _components_geometry_GeometryComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(137);\n/* harmony import */ var _components_geometry_System__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(122);\n/* harmony import */ var _components_material_MaterialComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(123);\n/* harmony import */ var _components_material_System__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(124);\n/* harmony import */ var _components_mesh_CullableComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(125);\n/* harmony import */ var _components_mesh_MeshComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(126);\n/* harmony import */ var _components_mesh_System__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(127);\n/* harmony import */ var _components_renderer_passes_PixelPickingPass__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(70);\n/* harmony import */ var _components_renderer_System__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(129);\n/* harmony import */ var _components_scenegraph_HierarchyComponent__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(130);\n/* harmony import */ var _components_scenegraph_System__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(131);\n/* harmony import */ var _components_scenegraph_TransformComponent__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(132);\n/* harmony import */ var _Entity__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(121);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "createEntity", function() { return _Entity__WEBPACK_IMPORTED_MODULE_15__["b"]; });\n\n/* harmony import */ var _identifier__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(13);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IDENTIFIER", function() { return _identifier__WEBPACK_IMPORTED_MODULE_16__["a"]; });\n\n/* harmony import */ var _inversify_config__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(92);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "createWorldContainer", function() { return _inversify_config__WEBPACK_IMPORTED_MODULE_17__["a"]; });\n\n/* harmony import */ var _utils_aabb__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(248);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "generateAABBFromVertices", function() { return _utils_aabb__WEBPACK_IMPORTED_MODULE_18__["a"]; });\n\n/* harmony import */ var _utils_isSafari__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(249);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isSafari", function() { return _utils_isSafari__WEBPACK_IMPORTED_MODULE_19__["a"]; });\n\n/* harmony import */ var _services__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(278);\n/* harmony import */ var _shape__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(279);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AABB", function() { return _shape__WEBPACK_IMPORTED_MODULE_21__["a"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return _shape__WEBPACK_IMPORTED_MODULE_21__["b"]; });\n\n/* harmony import */ var _components_renderer__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(117);\n/* harmony reexport (checked) */ if(__webpack_require__.o(_components_renderer__WEBPACK_IMPORTED_MODULE_22__, "gl")) __webpack_require__.d(__webpack_exports__, "gl", function() { return _components_renderer__WEBPACK_IMPORTED_MODULE_22__["gl"]; });\n\n/* harmony import */ var _components_material_interface__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(261);\n/* harmony import */ var _components_material_interface__WEBPACK_IMPORTED_MODULE_23___default = /*#__PURE__*/__webpack_require__.n(_components_material_interface__WEBPACK_IMPORTED_MODULE_23__);\n/* harmony reexport (checked) */ if(__webpack_require__.o(_components_material_interface__WEBPACK_IMPORTED_MODULE_23__, "gl")) __webpack_require__.d(__webpack_exports__, "gl", function() { return _components_material_interface__WEBPACK_IMPORTED_MODULE_23__["gl"]; });\n\n/* harmony import */ var _components_mesh_interface__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(262);\n/* harmony import */ var _components_mesh_interface__WEBPACK_IMPORTED_MODULE_24___default = /*#__PURE__*/__webpack_require__.n(_components_mesh_interface__WEBPACK_IMPORTED_MODULE_24__);\n/* harmony reexport (checked) */ if(__webpack_require__.o(_components_mesh_interface__WEBPACK_IMPORTED_MODULE_24__, "gl")) __webpack_require__.d(__webpack_exports__, "gl", function() { return _components_mesh_interface__WEBPACK_IMPORTED_MODULE_24__["gl"]; });\n\n/* harmony reexport (checked) */ if(__webpack_require__.o(_components_renderer__WEBPACK_IMPORTED_MODULE_22__, "gl")) __webpack_require__.d(__webpack_exports__, "gl", function() { return _components_renderer__WEBPACK_IMPORTED_MODULE_22__["gl"]; });\n\n// tslint:disable-next-line:no-reference\n/// \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * inspired by Entitas\' Systems\n * @see https://github.com/sschmid/Entitas-CSharp/wiki/Systems\n */\n\nvar AST_TOKEN_TYPES;\n\n(function (AST_TOKEN_TYPES) {\n AST_TOKEN_TYPES["Void"] = "Void";\n AST_TOKEN_TYPES["Boolean"] = "Boolean";\n AST_TOKEN_TYPES["Float"] = "Float";\n AST_TOKEN_TYPES["Uint32"] = "Uint32";\n AST_TOKEN_TYPES["Int32"] = "Int32";\n AST_TOKEN_TYPES["Vector"] = "Vector";\n AST_TOKEN_TYPES["Vector2Float"] = "vec2";\n AST_TOKEN_TYPES["Vector3Float"] = "vec3";\n AST_TOKEN_TYPES["Vector4Float"] = "vec4";\n AST_TOKEN_TYPES["Vector2Boolean"] = "vec2";\n AST_TOKEN_TYPES["Vector3Boolean"] = "vec3";\n AST_TOKEN_TYPES["Vector4Boolean"] = "vec4";\n AST_TOKEN_TYPES["Vector2Uint"] = "vec2";\n AST_TOKEN_TYPES["Vector3Uint"] = "vec3";\n AST_TOKEN_TYPES["Vector4Uint"] = "vec4";\n AST_TOKEN_TYPES["Vector2Int"] = "vec2";\n AST_TOKEN_TYPES["Vector3Int"] = "vec3";\n AST_TOKEN_TYPES["Vector4Int"] = "vec4";\n AST_TOKEN_TYPES["Matrix"] = "Matrix";\n AST_TOKEN_TYPES["Matrix3x3Float"] = "mat3x3";\n AST_TOKEN_TYPES["Matrix4x4Float"] = "mat4x4";\n AST_TOKEN_TYPES["Struct"] = "Struct";\n AST_TOKEN_TYPES["FloatArray"] = "Float[]";\n AST_TOKEN_TYPES["Vector4FloatArray"] = "vec4[]";\n})(AST_TOKEN_TYPES || (AST_TOKEN_TYPES = {}));\n\nvar AST_NODE_TYPES;\n\n(function (AST_NODE_TYPES) {\n AST_NODE_TYPES["Program"] = "Program";\n AST_NODE_TYPES["Identifier"] = "Identifier";\n AST_NODE_TYPES["VariableDeclaration"] = "VariableDeclaration";\n AST_NODE_TYPES["BlockStatement"] = "BlockStatement";\n AST_NODE_TYPES["ReturnStatement"] = "ReturnStatement";\n AST_NODE_TYPES["FunctionDeclaration"] = "FunctionDeclaration";\n AST_NODE_TYPES["VariableDeclarator"] = "VariableDeclarator";\n AST_NODE_TYPES["AssignmentExpression"] = "AssignmentExpression";\n AST_NODE_TYPES["LogicalExpression"] = "LogicalExpression";\n AST_NODE_TYPES["BinaryExpression"] = "BinaryExpression";\n AST_NODE_TYPES["ArrayExpression"] = "ArrayExpression";\n AST_NODE_TYPES["UnaryExpression"] = "UnaryExpression";\n AST_NODE_TYPES["UpdateExpression"] = "UpdateExpression";\n AST_NODE_TYPES["FunctionExpression"] = "FunctionExpression";\n AST_NODE_TYPES["MemberExpression"] = "MemberExpression";\n AST_NODE_TYPES["ConditionalExpression"] = "ConditionalExpression";\n AST_NODE_TYPES["ExpressionStatement"] = "ExpressionStatement";\n AST_NODE_TYPES["CallExpression"] = "CallExpression";\n AST_NODE_TYPES["NumThreadStatement"] = "NumThreadStatement";\n AST_NODE_TYPES["StorageStatement"] = "StorageStatement";\n AST_NODE_TYPES["DoWhileStatement"] = "DoWhileStatement";\n AST_NODE_TYPES["WhileStatement"] = "WhileStatement";\n AST_NODE_TYPES["ForStatement"] = "ForStatement";\n AST_NODE_TYPES["BreakStatement"] = "BreakStatement";\n AST_NODE_TYPES["ContinueStatement"] = "ContinueStatement";\n AST_NODE_TYPES["IfStatement"] = "IfStatement";\n AST_NODE_TYPES["ImportedFunctionStatement"] = "ImportedFunctionStatement";\n})(AST_NODE_TYPES || (AST_NODE_TYPES = {}));\n\nvar STORAGE_CLASS;\n\n(function (STORAGE_CLASS) {\n STORAGE_CLASS["Input"] = "Input";\n STORAGE_CLASS["Output"] = "Output";\n STORAGE_CLASS["Uniform"] = "Uniform";\n STORAGE_CLASS["Workgroup"] = "Workgroup";\n STORAGE_CLASS["UniformConstant"] = "UniformConstant";\n STORAGE_CLASS["Image"] = "Image";\n STORAGE_CLASS["StorageBuffer"] = "StorageBuffer";\n STORAGE_CLASS["Private"] = "Private";\n STORAGE_CLASS["Function"] = "Function";\n})(STORAGE_CLASS || (STORAGE_CLASS = {}));\n\n/**\n * 根据目标平台生成 Shader 代码\n * * WebGL GLSL 1.0\n * * WebGPU Chrome/Edge GLSL 4.5 & WGSL @see https://gpuweb.github.io/gpuweb/wgsl.html\n * * Safari WHLSL (maybe deprecated)\n */\nvar Target;\n\n(function (Target) {\n Target["GLSL100"] = "GLSL100";\n Target["GLSL450"] = "GLSL450";\n Target["WGSL"] = "WGSL";\n})(Target || (Target = {}));\n\nvar DefineValuePlaceholder = \'__DefineValuePlaceholder__\';\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy13ZWJncHUtY29yZS9lcy9pbmRleC5qcz8xYTNkIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUMwQjtBQUN1QztBQUNDO0FBQ1U7QUFDZDtBQUNjO0FBQ2Q7QUFDVTtBQUNSO0FBQ1Y7QUFDMkI7QUFDbkI7QUFDa0I7QUFDZDtBQUNjO0FBQ3hDO0FBQ0U7QUFDd0Q7QUFDMUM7QUFDWjtBQUM1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsMENBQTBDOztBQUUzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsd0NBQXdDOztBQUV6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsc0NBQXNDOztBQUV2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsd0JBQXdCOztBQUV6QjtBQUNtQztBQUNSO0FBQ0g7QUFDYztBQUNVO0FBQ0o7QUFDTjtBQUVpUTtBQUN2UyIsImZpbGUiOiIzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXJlZmVyZW5jZVxuLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uLy4uLy4uL25vZGVfbW9kdWxlcy9Ad2ViZ3B1L3R5cGVzL2Rpc3QvaW5kZXguZC50c1wiIC8+XG5pbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBDb21wb25lbnRNYW5hZ2VyIH0gZnJvbSAnLi9Db21wb25lbnRNYW5hZ2VyJztcbmltcG9ydCB7IEZyYW1lR3JhcGhTeXN0ZW0gfSBmcm9tICcuL2NvbXBvbmVudHMvZnJhbWVncmFwaC9TeXN0ZW0nO1xuaW1wb3J0IHsgR2VvbWV0cnlDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvZ2VvbWV0cnkvR2VvbWV0cnlDb21wb25lbnQnO1xuaW1wb3J0IHsgR2VvbWV0cnlTeXN0ZW0gfSBmcm9tICcuL2NvbXBvbmVudHMvZ2VvbWV0cnkvU3lzdGVtJztcbmltcG9ydCB7IE1hdGVyaWFsQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL21hdGVyaWFsL01hdGVyaWFsQ29tcG9uZW50JztcbmltcG9ydCB7IE1hdGVyaWFsU3lzdGVtIH0gZnJvbSAnLi9jb21wb25lbnRzL21hdGVyaWFsL1N5c3RlbSc7XG5pbXBvcnQgeyBDdWxsYWJsZUNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9tZXNoL0N1bGxhYmxlQ29tcG9uZW50JztcbmltcG9ydCB7IE1lc2hDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvbWVzaC9NZXNoQ29tcG9uZW50JztcbmltcG9ydCB7IE1lc2hTeXN0ZW0gfSBmcm9tICcuL2NvbXBvbmVudHMvbWVzaC9TeXN0ZW0nO1xuaW1wb3J0IHsgUGl4ZWxQaWNraW5nUGFzcyB9IGZyb20gJy4vY29tcG9uZW50cy9yZW5kZXJlci9wYXNzZXMvUGl4ZWxQaWNraW5nUGFzcyc7XG5pbXBvcnQgeyBSZW5kZXJlclN5c3RlbSB9IGZyb20gJy4vY29tcG9uZW50cy9yZW5kZXJlci9TeXN0ZW0nO1xuaW1wb3J0IHsgSGllcmFyY2h5Q29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL3NjZW5lZ3JhcGgvSGllcmFyY2h5Q29tcG9uZW50JztcbmltcG9ydCB7IFNjZW5lR3JhcGhTeXN0ZW0gfSBmcm9tICcuL2NvbXBvbmVudHMvc2NlbmVncmFwaC9TeXN0ZW0nO1xuaW1wb3J0IHsgVHJhbnNmb3JtQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL3NjZW5lZ3JhcGgvVHJhbnNmb3JtQ29tcG9uZW50JztcbmltcG9ydCB7IGNyZWF0ZUVudGl0eSB9IGZyb20gJy4vRW50aXR5JztcbmltcG9ydCB7IElERU5USUZJRVIgfSBmcm9tICcuL2lkZW50aWZpZXInO1xuaW1wb3J0IHsgY29udGFpbmVyLCBjcmVhdGVXb3JsZENvbnRhaW5lciwgbGF6eUluamVjdCwgbGF6eU11bHRpSW5qZWN0IH0gZnJvbSAnLi9pbnZlcnNpZnkuY29uZmlnJztcbmltcG9ydCB7IGdlbmVyYXRlQUFCQkZyb21WZXJ0aWNlcyB9IGZyb20gJy4vdXRpbHMvYWFiYic7XG5pbXBvcnQgeyBpc1NhZmFyaSB9IGZyb20gJy4vdXRpbHMvaXNTYWZhcmknO1xuLyoqXG4gKiBpbnNwaXJlZCBieSBFbnRpdGFzJyBTeXN0ZW1zXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9zc2NobWlkL0VudGl0YXMtQ1NoYXJwL3dpa2kvU3lzdGVtc1xuICovXG5cbnZhciBBU1RfVE9LRU5fVFlQRVM7XG5cbihmdW5jdGlvbiAoQVNUX1RPS0VOX1RZUEVTKSB7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZvaWRcIl0gPSBcIlZvaWRcIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiQm9vbGVhblwiXSA9IFwiQm9vbGVhblwiO1xuICBBU1RfVE9LRU5fVFlQRVNbXCJGbG9hdFwiXSA9IFwiRmxvYXRcIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiVWludDMyXCJdID0gXCJVaW50MzJcIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiSW50MzJcIl0gPSBcIkludDMyXCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvclwiXSA9IFwiVmVjdG9yXCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjJGbG9hdFwiXSA9IFwidmVjMjxmMzI+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjNGbG9hdFwiXSA9IFwidmVjMzxmMzI+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjRGbG9hdFwiXSA9IFwidmVjNDxmMzI+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjJCb29sZWFuXCJdID0gXCJ2ZWMyPGJvb2w+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjNCb29sZWFuXCJdID0gXCJ2ZWMzPGJvb2w+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjRCb29sZWFuXCJdID0gXCJ2ZWM0PGJvb2w+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjJVaW50XCJdID0gXCJ2ZWMyPHUzMj5cIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiVmVjdG9yM1VpbnRcIl0gPSBcInZlYzM8dTMyPlwiO1xuICBBU1RfVE9LRU5fVFlQRVNbXCJWZWN0b3I0VWludFwiXSA9IFwidmVjNDx1MzI+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIlZlY3RvcjJJbnRcIl0gPSBcInZlYzI8aTMyPlwiO1xuICBBU1RfVE9LRU5fVFlQRVNbXCJWZWN0b3IzSW50XCJdID0gXCJ2ZWMzPGkzMj5cIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiVmVjdG9yNEludFwiXSA9IFwidmVjNDxpMzI+XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIk1hdHJpeFwiXSA9IFwiTWF0cml4XCI7XG4gIEFTVF9UT0tFTl9UWVBFU1tcIk1hdHJpeDN4M0Zsb2F0XCJdID0gXCJtYXQzeDM8ZjMyPlwiO1xuICBBU1RfVE9LRU5fVFlQRVNbXCJNYXRyaXg0eDRGbG9hdFwiXSA9IFwibWF0NHg0PGkzMj5cIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiU3RydWN0XCJdID0gXCJTdHJ1Y3RcIjtcbiAgQVNUX1RPS0VOX1RZUEVTW1wiRmxvYXRBcnJheVwiXSA9IFwiRmxvYXRbXVwiO1xuICBBU1RfVE9LRU5fVFlQRVNbXCJWZWN0b3I0RmxvYXRBcnJheVwiXSA9IFwidmVjNDxmMzI+W11cIjtcbn0pKEFTVF9UT0tFTl9UWVBFUyB8fCAoQVNUX1RPS0VOX1RZUEVTID0ge30pKTtcblxudmFyIEFTVF9OT0RFX1RZUEVTO1xuXG4oZnVuY3Rpb24gKEFTVF9OT0RFX1RZUEVTKSB7XG4gIEFTVF9OT0RFX1RZUEVTW1wiUHJvZ3JhbVwiXSA9IFwiUHJvZ3JhbVwiO1xuICBBU1RfTk9ERV9UWVBFU1tcIklkZW50aWZpZXJcIl0gPSBcIklkZW50aWZpZXJcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJWYXJpYWJsZURlY2xhcmF0aW9uXCJdID0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCI7XG4gIEFTVF9OT0RFX1RZUEVTW1wiQmxvY2tTdGF0ZW1lbnRcIl0gPSBcIkJsb2NrU3RhdGVtZW50XCI7XG4gIEFTVF9OT0RFX1RZUEVTW1wiUmV0dXJuU3RhdGVtZW50XCJdID0gXCJSZXR1cm5TdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCJdID0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCI7XG4gIEFTVF9OT0RFX1RZUEVTW1wiVmFyaWFibGVEZWNsYXJhdG9yXCJdID0gXCJWYXJpYWJsZURlY2xhcmF0b3JcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJBc3NpZ25tZW50RXhwcmVzc2lvblwiXSA9IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIjtcbiAgQVNUX05PREVfVFlQRVNbXCJMb2dpY2FsRXhwcmVzc2lvblwiXSA9IFwiTG9naWNhbEV4cHJlc3Npb25cIjtcbiAgQVNUX05PREVfVFlQRVNbXCJCaW5hcnlFeHByZXNzaW9uXCJdID0gXCJCaW5hcnlFeHByZXNzaW9uXCI7XG4gIEFTVF9OT0RFX1RZUEVTW1wiQXJyYXlFeHByZXNzaW9uXCJdID0gXCJBcnJheUV4cHJlc3Npb25cIjtcbiAgQVNUX05PREVfVFlQRVNbXCJVbmFyeUV4cHJlc3Npb25cIl0gPSBcIlVuYXJ5RXhwcmVzc2lvblwiO1xuICBBU1RfTk9ERV9UWVBFU1tcIlVwZGF0ZUV4cHJlc3Npb25cIl0gPSBcIlVwZGF0ZUV4cHJlc3Npb25cIjtcbiAgQVNUX05PREVfVFlQRVNbXCJGdW5jdGlvbkV4cHJlc3Npb25cIl0gPSBcIkZ1bmN0aW9uRXhwcmVzc2lvblwiO1xuICBBU1RfTk9ERV9UWVBFU1tcIk1lbWJlckV4cHJlc3Npb25cIl0gPSBcIk1lbWJlckV4cHJlc3Npb25cIjtcbiAgQVNUX05PREVfVFlQRVNbXCJDb25kaXRpb25hbEV4cHJlc3Npb25cIl0gPSBcIkNvbmRpdGlvbmFsRXhwcmVzc2lvblwiO1xuICBBU1RfTk9ERV9UWVBFU1tcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIl0gPSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJDYWxsRXhwcmVzc2lvblwiXSA9IFwiQ2FsbEV4cHJlc3Npb25cIjtcbiAgQVNUX05PREVfVFlQRVNbXCJOdW1UaHJlYWRTdGF0ZW1lbnRcIl0gPSBcIk51bVRocmVhZFN0YXRlbWVudFwiO1xuICBBU1RfTk9ERV9UWVBFU1tcIlN0b3JhZ2VTdGF0ZW1lbnRcIl0gPSBcIlN0b3JhZ2VTdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJEb1doaWxlU3RhdGVtZW50XCJdID0gXCJEb1doaWxlU3RhdGVtZW50XCI7XG4gIEFTVF9OT0RFX1RZUEVTW1wiV2hpbGVTdGF0ZW1lbnRcIl0gPSBcIldoaWxlU3RhdGVtZW50XCI7XG4gIEFTVF9OT0RFX1RZUEVTW1wiRm9yU3RhdGVtZW50XCJdID0gXCJGb3JTdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJCcmVha1N0YXRlbWVudFwiXSA9IFwiQnJlYWtTdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJDb250aW51ZVN0YXRlbWVudFwiXSA9IFwiQ29udGludWVTdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJJZlN0YXRlbWVudFwiXSA9IFwiSWZTdGF0ZW1lbnRcIjtcbiAgQVNUX05PREVfVFlQRVNbXCJJbXBvcnRlZEZ1bmN0aW9uU3RhdGVtZW50XCJdID0gXCJJbXBvcnRlZEZ1bmN0aW9uU3RhdGVtZW50XCI7XG59KShBU1RfTk9ERV9UWVBFUyB8fCAoQVNUX05PREVfVFlQRVMgPSB7fSkpO1xuXG52YXIgU1RPUkFHRV9DTEFTUztcblxuKGZ1bmN0aW9uIChTVE9SQUdFX0NMQVNTKSB7XG4gIFNUT1JBR0VfQ0xBU1NbXCJJbnB1dFwiXSA9IFwiSW5wdXRcIjtcbiAgU1RPUkFHRV9DTEFTU1tcIk91dHB1dFwiXSA9IFwiT3V0cHV0XCI7XG4gIFNUT1JBR0VfQ0xBU1NbXCJVbmlmb3JtXCJdID0gXCJVbmlmb3JtXCI7XG4gIFNUT1JBR0VfQ0xBU1NbXCJXb3JrZ3JvdXBcIl0gPSBcIldvcmtncm91cFwiO1xuICBTVE9SQUdFX0NMQVNTW1wiVW5pZm9ybUNvbnN0YW50XCJdID0gXCJVbmlmb3JtQ29uc3RhbnRcIjtcbiAgU1RPUkFHRV9DTEFTU1tcIkltYWdlXCJdID0gXCJJbWFnZVwiO1xuICBTVE9SQUdFX0NMQVNTW1wiU3RvcmFnZUJ1ZmZlclwiXSA9IFwiU3RvcmFnZUJ1ZmZlclwiO1xuICBTVE9SQUdFX0NMQVNTW1wiUHJpdmF0ZVwiXSA9IFwiUHJpdmF0ZVwiO1xuICBTVE9SQUdFX0NMQVNTW1wiRnVuY3Rpb25cIl0gPSBcIkZ1bmN0aW9uXCI7XG59KShTVE9SQUdFX0NMQVNTIHx8IChTVE9SQUdFX0NMQVNTID0ge30pKTtcblxuLyoqXG4gKiDmoLnmja7nm67moIflubPlj7DnlJ/miJAgU2hhZGVyIOS7o+eggVxuICogKiBXZWJHTCBHTFNMIDEuMFxuICogKiBXZWJHUFUgQ2hyb21lL0VkZ2UgR0xTTCA0LjUgJiBXR1NMIEBzZWUgaHR0cHM6Ly9ncHV3ZWIuZ2l0aHViLmlvL2dwdXdlYi93Z3NsLmh0bWxcbiAqICogU2FmYXJpIFdITFNMIChtYXliZSBkZXByZWNhdGVkKVxuICovXG52YXIgVGFyZ2V0O1xuXG4oZnVuY3Rpb24gKFRhcmdldCkge1xuICBUYXJnZXRbXCJHTFNMMTAwXCJdID0gXCJHTFNMMTAwXCI7XG4gIFRhcmdldFtcIkdMU0w0NTBcIl0gPSBcIkdMU0w0NTBcIjtcbiAgVGFyZ2V0W1wiV0dTTFwiXSA9IFwiV0dTTFwiO1xufSkoVGFyZ2V0IHx8IChUYXJnZXQgPSB7fSkpO1xuXG52YXIgRGVmaW5lVmFsdWVQbGFjZWhvbGRlciA9ICdfX0RlZmluZVZhbHVlUGxhY2Vob2xkZXJfXyc7XG5leHBvcnQgKiBmcm9tICcuL0NvbXBvbmVudE1hbmFnZXInO1xuZXhwb3J0ICogZnJvbSAnLi9zZXJ2aWNlcyc7XG5leHBvcnQgKiBmcm9tICcuL3NoYXBlJztcbmV4cG9ydCAqIGZyb20gJy4vY29tcG9uZW50cy9yZW5kZXJlcic7XG5leHBvcnQgKiBmcm9tICcuL2NvbXBvbmVudHMvbWF0ZXJpYWwvaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vY29tcG9uZW50cy9tZXNoL2ludGVyZmFjZSc7XG5leHBvcnQgKiBmcm9tICcuL2NvbXBvbmVudHMvcmVuZGVyZXInO1xuZXhwb3J0IHsgY29udGFpbmVyLCBjcmVhdGVXb3JsZENvbnRhaW5lciwgbGF6eUluamVjdCwgbGF6eU11bHRpSW5qZWN0LCBjcmVhdGVFbnRpdHksIENvbXBvbmVudCwgQ29tcG9uZW50TWFuYWdlciwgSURFTlRJRklFUiwgRnJhbWVHcmFwaFN5c3RlbSwgR2VvbWV0cnlTeXN0ZW0sIFJlbmRlcmVyU3lzdGVtIC8vIEludGVyYWN0aW9uU3lzdGVtLFxuLCBNYXRlcmlhbFN5c3RlbSwgTWVzaFN5c3RlbSwgU2NlbmVHcmFwaFN5c3RlbSwgQ3VsbGFibGVDb21wb25lbnQsIE1lc2hDb21wb25lbnQsIFRyYW5zZm9ybUNvbXBvbmVudCwgTWF0ZXJpYWxDb21wb25lbnQsIEdlb21ldHJ5Q29tcG9uZW50LCBIaWVyYXJjaHlDb21wb25lbnQsIGlzU2FmYXJpLCBnZW5lcmF0ZUFBQkJGcm9tVmVydGljZXMsIFBpeGVsUGlja2luZ1Bhc3MsIEFTVF9UT0tFTl9UWVBFUywgQVNUX05PREVfVFlQRVMsIFNUT1JBR0VfQ0xBU1MsIFRhcmdldCwgRGVmaW5lVmFsdWVQbGFjZWhvbGRlciB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3\n')},function(module,exports){eval('function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9kZWZpbmVQcm9wZXJ0eS5qcz85NTIzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiI0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5IGluIG9iaikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBvYmo7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2RlZmluZVByb3BlcnR5O1xubW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHMsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4\n')},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nexports.multiBindToService = exports.getServiceIdentifierAsString = exports.typeConstraint = exports.namedConstraint = exports.taggedConstraint = exports.traverseAncerstors = exports.decorate = exports.id = exports.MetadataReader = exports.postConstruct = exports.targetName = exports.multiInject = exports.unmanaged = exports.optional = exports.LazyServiceIdentifer = exports.inject = exports.named = exports.tagged = exports.injectable = exports.ContainerModule = exports.AsyncContainerModule = exports.TargetTypeEnum = exports.BindingTypeEnum = exports.BindingScopeEnum = exports.Container = exports.METADATA_KEY = void 0;\nvar keys = __webpack_require__(32);\nexports.METADATA_KEY = keys;\nvar container_1 = __webpack_require__(502);\nObject.defineProperty(exports, "Container", { enumerable: true, get: function () { return container_1.Container; } });\nvar literal_types_1 = __webpack_require__(56);\nObject.defineProperty(exports, "BindingScopeEnum", { enumerable: true, get: function () { return literal_types_1.BindingScopeEnum; } });\nObject.defineProperty(exports, "BindingTypeEnum", { enumerable: true, get: function () { return literal_types_1.BindingTypeEnum; } });\nObject.defineProperty(exports, "TargetTypeEnum", { enumerable: true, get: function () { return literal_types_1.TargetTypeEnum; } });\nvar container_module_1 = __webpack_require__(518);\nObject.defineProperty(exports, "AsyncContainerModule", { enumerable: true, get: function () { return container_module_1.AsyncContainerModule; } });\nObject.defineProperty(exports, "ContainerModule", { enumerable: true, get: function () { return container_module_1.ContainerModule; } });\nvar injectable_1 = __webpack_require__(519);\nObject.defineProperty(exports, "injectable", { enumerable: true, get: function () { return injectable_1.injectable; } });\nvar tagged_1 = __webpack_require__(520);\nObject.defineProperty(exports, "tagged", { enumerable: true, get: function () { return tagged_1.tagged; } });\nvar named_1 = __webpack_require__(521);\nObject.defineProperty(exports, "named", { enumerable: true, get: function () { return named_1.named; } });\nvar inject_1 = __webpack_require__(244);\nObject.defineProperty(exports, "inject", { enumerable: true, get: function () { return inject_1.inject; } });\nObject.defineProperty(exports, "LazyServiceIdentifer", { enumerable: true, get: function () { return inject_1.LazyServiceIdentifer; } });\nvar optional_1 = __webpack_require__(522);\nObject.defineProperty(exports, "optional", { enumerable: true, get: function () { return optional_1.optional; } });\nvar unmanaged_1 = __webpack_require__(523);\nObject.defineProperty(exports, "unmanaged", { enumerable: true, get: function () { return unmanaged_1.unmanaged; } });\nvar multi_inject_1 = __webpack_require__(524);\nObject.defineProperty(exports, "multiInject", { enumerable: true, get: function () { return multi_inject_1.multiInject; } });\nvar target_name_1 = __webpack_require__(525);\nObject.defineProperty(exports, "targetName", { enumerable: true, get: function () { return target_name_1.targetName; } });\nvar post_construct_1 = __webpack_require__(526);\nObject.defineProperty(exports, "postConstruct", { enumerable: true, get: function () { return post_construct_1.postConstruct; } });\nvar metadata_reader_1 = __webpack_require__(242);\nObject.defineProperty(exports, "MetadataReader", { enumerable: true, get: function () { return metadata_reader_1.MetadataReader; } });\nvar id_1 = __webpack_require__(68);\nObject.defineProperty(exports, "id", { enumerable: true, get: function () { return id_1.id; } });\nvar decorator_utils_1 = __webpack_require__(60);\nObject.defineProperty(exports, "decorate", { enumerable: true, get: function () { return decorator_utils_1.decorate; } });\nvar constraint_helpers_1 = __webpack_require__(247);\nObject.defineProperty(exports, "traverseAncerstors", { enumerable: true, get: function () { return constraint_helpers_1.traverseAncerstors; } });\nObject.defineProperty(exports, "taggedConstraint", { enumerable: true, get: function () { return constraint_helpers_1.taggedConstraint; } });\nObject.defineProperty(exports, "namedConstraint", { enumerable: true, get: function () { return constraint_helpers_1.namedConstraint; } });\nObject.defineProperty(exports, "typeConstraint", { enumerable: true, get: function () { return constraint_helpers_1.typeConstraint; } });\nvar serialization_1 = __webpack_require__(91);\nObject.defineProperty(exports, "getServiceIdentifierAsString", { enumerable: true, get: function () { return serialization_1.getServiceIdentifierAsString; } });\nvar binding_utils_1 = __webpack_require__(527);\nObject.defineProperty(exports, "multiBindToService", { enumerable: true, get: function () { return binding_utils_1.multiBindToService; } });\n//# sourceMappingURL=inversify.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9pbnZlcnNpZnkuanM/ZTFjNiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBYTtBQUNiLDhDQUE4QyxjQUFjO0FBQzVEO0FBQ0EsV0FBVyxtQkFBTyxDQUFDLEVBQTJCO0FBQzlDO0FBQ0Esa0JBQWtCLG1CQUFPLENBQUMsR0FBdUI7QUFDakQsNkNBQTZDLHFDQUFxQyw4QkFBOEIsRUFBRSxFQUFFO0FBQ3BILHNCQUFzQixtQkFBTyxDQUFDLEVBQTJCO0FBQ3pELG9EQUFvRCxxQ0FBcUMseUNBQXlDLEVBQUUsRUFBRTtBQUN0SSxtREFBbUQscUNBQXFDLHdDQUF3QyxFQUFFLEVBQUU7QUFDcEksa0RBQWtELHFDQUFxQyx1Q0FBdUMsRUFBRSxFQUFFO0FBQ2xJLHlCQUF5QixtQkFBTyxDQUFDLEdBQThCO0FBQy9ELHdEQUF3RCxxQ0FBcUMsZ0RBQWdELEVBQUUsRUFBRTtBQUNqSixtREFBbUQscUNBQXFDLDJDQUEyQyxFQUFFLEVBQUU7QUFDdkksbUJBQW1CLG1CQUFPLENBQUMsR0FBeUI7QUFDcEQsOENBQThDLHFDQUFxQyxnQ0FBZ0MsRUFBRSxFQUFFO0FBQ3ZILGVBQWUsbUJBQU8sQ0FBQyxHQUFxQjtBQUM1QywwQ0FBMEMscUNBQXFDLHdCQUF3QixFQUFFLEVBQUU7QUFDM0csY0FBYyxtQkFBTyxDQUFDLEdBQW9CO0FBQzFDLHlDQUF5QyxxQ0FBcUMsc0JBQXNCLEVBQUUsRUFBRTtBQUN4RyxlQUFlLG1CQUFPLENBQUMsR0FBcUI7QUFDNUMsMENBQTBDLHFDQUFxQyx3QkFBd0IsRUFBRSxFQUFFO0FBQzNHLHdEQUF3RCxxQ0FBcUMsc0NBQXNDLEVBQUUsRUFBRTtBQUN2SSxpQkFBaUIsbUJBQU8sQ0FBQyxHQUF1QjtBQUNoRCw0Q0FBNEMscUNBQXFDLDRCQUE0QixFQUFFLEVBQUU7QUFDakgsa0JBQWtCLG1CQUFPLENBQUMsR0FBd0I7QUFDbEQsNkNBQTZDLHFDQUFxQyw4QkFBOEIsRUFBRSxFQUFFO0FBQ3BILHFCQUFxQixtQkFBTyxDQUFDLEdBQTJCO0FBQ3hELCtDQUErQyxxQ0FBcUMsbUNBQW1DLEVBQUUsRUFBRTtBQUMzSCxvQkFBb0IsbUJBQU8sQ0FBQyxHQUEwQjtBQUN0RCw4Q0FBOEMscUNBQXFDLGlDQUFpQyxFQUFFLEVBQUU7QUFDeEgsdUJBQXVCLG1CQUFPLENBQUMsR0FBNkI7QUFDNUQsaURBQWlELHFDQUFxQyx1Q0FBdUMsRUFBRSxFQUFFO0FBQ2pJLHdCQUF3QixtQkFBTyxDQUFDLEdBQTRCO0FBQzVELGtEQUFrRCxxQ0FBcUMseUNBQXlDLEVBQUUsRUFBRTtBQUNwSSxXQUFXLG1CQUFPLENBQUMsRUFBWTtBQUMvQixzQ0FBc0MscUNBQXFDLGdCQUFnQixFQUFFLEVBQUU7QUFDL0Ysd0JBQXdCLG1CQUFPLENBQUMsRUFBOEI7QUFDOUQsNENBQTRDLHFDQUFxQyxtQ0FBbUMsRUFBRSxFQUFFO0FBQ3hILDJCQUEyQixtQkFBTyxDQUFDLEdBQTZCO0FBQ2hFLHNEQUFzRCxxQ0FBcUMsZ0RBQWdELEVBQUUsRUFBRTtBQUMvSSxvREFBb0QscUNBQXFDLDhDQUE4QyxFQUFFLEVBQUU7QUFDM0ksbURBQW1ELHFDQUFxQyw2Q0FBNkMsRUFBRSxFQUFFO0FBQ3pJLGtEQUFrRCxxQ0FBcUMsNENBQTRDLEVBQUUsRUFBRTtBQUN2SSxzQkFBc0IsbUJBQU8sQ0FBQyxFQUF1QjtBQUNyRCxnRUFBZ0UscUNBQXFDLHFEQUFxRCxFQUFFLEVBQUU7QUFDOUosc0JBQXNCLG1CQUFPLENBQUMsR0FBdUI7QUFDckQsc0RBQXNELHFDQUFxQywyQ0FBMkMsRUFBRSxFQUFFO0FBQzFJIiwiZmlsZSI6IjUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMubXVsdGlCaW5kVG9TZXJ2aWNlID0gZXhwb3J0cy5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nID0gZXhwb3J0cy50eXBlQ29uc3RyYWludCA9IGV4cG9ydHMubmFtZWRDb25zdHJhaW50ID0gZXhwb3J0cy50YWdnZWRDb25zdHJhaW50ID0gZXhwb3J0cy50cmF2ZXJzZUFuY2Vyc3RvcnMgPSBleHBvcnRzLmRlY29yYXRlID0gZXhwb3J0cy5pZCA9IGV4cG9ydHMuTWV0YWRhdGFSZWFkZXIgPSBleHBvcnRzLnBvc3RDb25zdHJ1Y3QgPSBleHBvcnRzLnRhcmdldE5hbWUgPSBleHBvcnRzLm11bHRpSW5qZWN0ID0gZXhwb3J0cy51bm1hbmFnZWQgPSBleHBvcnRzLm9wdGlvbmFsID0gZXhwb3J0cy5MYXp5U2VydmljZUlkZW50aWZlciA9IGV4cG9ydHMuaW5qZWN0ID0gZXhwb3J0cy5uYW1lZCA9IGV4cG9ydHMudGFnZ2VkID0gZXhwb3J0cy5pbmplY3RhYmxlID0gZXhwb3J0cy5Db250YWluZXJNb2R1bGUgPSBleHBvcnRzLkFzeW5jQ29udGFpbmVyTW9kdWxlID0gZXhwb3J0cy5UYXJnZXRUeXBlRW51bSA9IGV4cG9ydHMuQmluZGluZ1R5cGVFbnVtID0gZXhwb3J0cy5CaW5kaW5nU2NvcGVFbnVtID0gZXhwb3J0cy5Db250YWluZXIgPSBleHBvcnRzLk1FVEFEQVRBX0tFWSA9IHZvaWQgMDtcbnZhciBrZXlzID0gcmVxdWlyZShcIi4vY29uc3RhbnRzL21ldGFkYXRhX2tleXNcIik7XG5leHBvcnRzLk1FVEFEQVRBX0tFWSA9IGtleXM7XG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXIvY29udGFpbmVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29udGFpbmVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250YWluZXJfMS5Db250YWluZXI7IH0gfSk7XG52YXIgbGl0ZXJhbF90eXBlc18xID0gcmVxdWlyZShcIi4vY29uc3RhbnRzL2xpdGVyYWxfdHlwZXNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJCaW5kaW5nU2NvcGVFbnVtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXRlcmFsX3R5cGVzXzEuQmluZGluZ1Njb3BlRW51bTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkJpbmRpbmdUeXBlRW51bVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gbGl0ZXJhbF90eXBlc18xLkJpbmRpbmdUeXBlRW51bTsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIlRhcmdldFR5cGVFbnVtXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBsaXRlcmFsX3R5cGVzXzEuVGFyZ2V0VHlwZUVudW07IH0gfSk7XG52YXIgY29udGFpbmVyX21vZHVsZV8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyL2NvbnRhaW5lcl9tb2R1bGVcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJBc3luY0NvbnRhaW5lck1vZHVsZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29udGFpbmVyX21vZHVsZV8xLkFzeW5jQ29udGFpbmVyTW9kdWxlOyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiQ29udGFpbmVyTW9kdWxlXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb250YWluZXJfbW9kdWxlXzEuQ29udGFpbmVyTW9kdWxlOyB9IH0pO1xudmFyIGluamVjdGFibGVfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vaW5qZWN0YWJsZVwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImluamVjdGFibGVcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGluamVjdGFibGVfMS5pbmplY3RhYmxlOyB9IH0pO1xudmFyIHRhZ2dlZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi90YWdnZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0YWdnZWRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRhZ2dlZF8xLnRhZ2dlZDsgfSB9KTtcbnZhciBuYW1lZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9uYW1lZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm5hbWVkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBuYW1lZF8xLm5hbWVkOyB9IH0pO1xudmFyIGluamVjdF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9pbmplY3RcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJpbmplY3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGluamVjdF8xLmluamVjdDsgfSB9KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIkxhenlTZXJ2aWNlSWRlbnRpZmVyXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpbmplY3RfMS5MYXp5U2VydmljZUlkZW50aWZlcjsgfSB9KTtcbnZhciBvcHRpb25hbF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9vcHRpb25hbFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIm9wdGlvbmFsXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRpb25hbF8xLm9wdGlvbmFsOyB9IH0pO1xudmFyIHVubWFuYWdlZF8xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi91bm1hbmFnZWRcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ1bm1hbmFnZWRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHVubWFuYWdlZF8xLnVubWFuYWdlZDsgfSB9KTtcbnZhciBtdWx0aV9pbmplY3RfMSA9IHJlcXVpcmUoXCIuL2Fubm90YXRpb24vbXVsdGlfaW5qZWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibXVsdGlJbmplY3RcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG11bHRpX2luamVjdF8xLm11bHRpSW5qZWN0OyB9IH0pO1xudmFyIHRhcmdldF9uYW1lXzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL3RhcmdldF9uYW1lXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidGFyZ2V0TmFtZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGFyZ2V0X25hbWVfMS50YXJnZXROYW1lOyB9IH0pO1xudmFyIHBvc3RfY29uc3RydWN0XzEgPSByZXF1aXJlKFwiLi9hbm5vdGF0aW9uL3Bvc3RfY29uc3RydWN0XCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwicG9zdENvbnN0cnVjdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcG9zdF9jb25zdHJ1Y3RfMS5wb3N0Q29uc3RydWN0OyB9IH0pO1xudmFyIG1ldGFkYXRhX3JlYWRlcl8xID0gcmVxdWlyZShcIi4vcGxhbm5pbmcvbWV0YWRhdGFfcmVhZGVyXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTWV0YWRhdGFSZWFkZXJcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG1ldGFkYXRhX3JlYWRlcl8xLk1ldGFkYXRhUmVhZGVyOyB9IH0pO1xudmFyIGlkXzEgPSByZXF1aXJlKFwiLi91dGlscy9pZFwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImlkXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBpZF8xLmlkOyB9IH0pO1xudmFyIGRlY29yYXRvcl91dGlsc18xID0gcmVxdWlyZShcIi4vYW5ub3RhdGlvbi9kZWNvcmF0b3JfdXRpbHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJkZWNvcmF0ZVwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVjb3JhdG9yX3V0aWxzXzEuZGVjb3JhdGU7IH0gfSk7XG52YXIgY29uc3RyYWludF9oZWxwZXJzXzEgPSByZXF1aXJlKFwiLi9zeW50YXgvY29uc3RyYWludF9oZWxwZXJzXCIpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidHJhdmVyc2VBbmNlcnN0b3JzXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50cmF2ZXJzZUFuY2Vyc3RvcnM7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0YWdnZWRDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS50YWdnZWRDb25zdHJhaW50OyB9IH0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwibmFtZWRDb25zdHJhaW50XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBjb25zdHJhaW50X2hlbHBlcnNfMS5uYW1lZENvbnN0cmFpbnQ7IH0gfSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ0eXBlQ29uc3RyYWludFwiLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gY29uc3RyYWludF9oZWxwZXJzXzEudHlwZUNvbnN0cmFpbnQ7IH0gfSk7XG52YXIgc2VyaWFsaXphdGlvbl8xID0gcmVxdWlyZShcIi4vdXRpbHMvc2VyaWFsaXphdGlvblwiKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcImdldFNlcnZpY2VJZGVudGlmaWVyQXNTdHJpbmdcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlcmlhbGl6YXRpb25fMS5nZXRTZXJ2aWNlSWRlbnRpZmllckFzU3RyaW5nOyB9IH0pO1xudmFyIGJpbmRpbmdfdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3V0aWxzL2JpbmRpbmdfdXRpbHNcIik7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJtdWx0aUJpbmRUb1NlcnZpY2VcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGJpbmRpbmdfdXRpbHNfMS5tdWx0aUJpbmRUb1NlcnZpY2U7IH0gfSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnZlcnNpZnkuanMubWFwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///5\n')},function(module,exports){eval('function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\n\nmodule.exports = _classCallCheck;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVjay5qcz85NzBiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiI2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY2xhc3NDYWxsQ2hlY2s7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6\n')},function(module,exports){eval('function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nmodule.exports = _createClass;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcy5qcz81YmMzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJmaWxlIjoiNy5qcyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIHJldHVybiBDb25zdHJ1Y3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY3JlYXRlQ2xhc3M7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7\n')},function(module,exports,__webpack_require__){"use strict";eval('\n// https://github.com/gpuweb/gpuweb/blob/01b20b4ad93fabae1e8e0d7752515f69708d33e0/spec/index.bs\nObject.defineProperty(exports, "__esModule", { value: true });\n// tslint:disable:variable-name\n// String enums\nvar ExtensionName;\n(function (ExtensionName) {\n ExtensionName["TextureCompressionBC"] = "texture-compression-bc";\n})(ExtensionName = exports.ExtensionName || (exports.ExtensionName = {}));\nvar AddressMode;\n(function (AddressMode) {\n AddressMode["ClampToEdge"] = "clamp-to-edge";\n AddressMode["Repeat"] = "repeat";\n AddressMode["MirrorRepeat"] = "mirror-repeat";\n})(AddressMode = exports.AddressMode || (exports.AddressMode = {}));\nvar BindingType;\n(function (BindingType) {\n BindingType["UniformBuffer"] = "uniform-buffer";\n BindingType["StorageBuffer"] = "storage-buffer";\n BindingType["ReadonlyStorageBuffer"] = "readonly-storage-buffer";\n BindingType["Sampler"] = "sampler";\n BindingType["ComparisonSampler"] = "comparison-sampler";\n BindingType["SampledTexture"] = "sampled-texture";\n BindingType["ReadonlyStorageTexture"] = "readonly-storage-texture";\n BindingType["WriteonlyStorageTexture"] = "writeonly-storage-texture";\n})(BindingType = exports.BindingType || (exports.BindingType = {}));\nvar BlendFactor;\n(function (BlendFactor) {\n BlendFactor["Zero"] = "zero";\n BlendFactor["One"] = "one";\n BlendFactor["SrcColor"] = "src-color";\n BlendFactor["OneMinusSrcColor"] = "one-minus-src-color";\n BlendFactor["SrcAlpha"] = "src-alpha";\n BlendFactor["OneMinusSrcAlpha"] = "one-minus-src-alpha";\n BlendFactor["DstColor"] = "dst-color";\n BlendFactor["OneMinusDstColor"] = "one-minus-dst-color";\n BlendFactor["DstAlpha"] = "dst-alpha";\n BlendFactor["OneMinusDstAlpha"] = "one-minus-dst-alpha";\n BlendFactor["SrcAlphaSaturated"] = "src-alpha-saturated";\n BlendFactor["BlendColor"] = "blend-color";\n BlendFactor["OneMinusBlendColor"] = "one-minus-blend-color";\n})(BlendFactor = exports.BlendFactor || (exports.BlendFactor = {}));\nvar BlendOperation;\n(function (BlendOperation) {\n BlendOperation["Add"] = "add";\n BlendOperation["Subtract"] = "subtract";\n BlendOperation["ReverseSubtract"] = "reverse-subtract";\n BlendOperation["Min"] = "min";\n BlendOperation["Max"] = "max";\n})(BlendOperation = exports.BlendOperation || (exports.BlendOperation = {}));\nvar CompareFunction;\n(function (CompareFunction) {\n CompareFunction["Never"] = "never";\n CompareFunction["Less"] = "less";\n CompareFunction["Equal"] = "equal";\n CompareFunction["LessEqual"] = "less-equal";\n CompareFunction["Greater"] = "greater";\n CompareFunction["NotEqual"] = "not-equal";\n CompareFunction["GreaterEqual"] = "greater-equal";\n CompareFunction["Always"] = "always";\n})(CompareFunction = exports.CompareFunction || (exports.CompareFunction = {}));\nvar CullMode;\n(function (CullMode) {\n CullMode["None"] = "none";\n CullMode["Front"] = "front";\n CullMode["Back"] = "back";\n})(CullMode = exports.CullMode || (exports.CullMode = {}));\nvar FilterMode;\n(function (FilterMode) {\n FilterMode["Nearest"] = "nearest";\n FilterMode["Linear"] = "linear";\n})(FilterMode = exports.FilterMode || (exports.FilterMode = {}));\nvar FrontFace;\n(function (FrontFace) {\n FrontFace["CCW"] = "ccw";\n FrontFace["CW"] = "cw";\n})(FrontFace = exports.FrontFace || (exports.FrontFace = {}));\nvar IndexFormat;\n(function (IndexFormat) {\n IndexFormat["Uint16"] = "uint16";\n IndexFormat["Uint32"] = "uint32";\n})(IndexFormat = exports.IndexFormat || (exports.IndexFormat = {}));\nvar InputStepMode;\n(function (InputStepMode) {\n InputStepMode["Vertex"] = "vertex";\n InputStepMode["Instance"] = "instance";\n})(InputStepMode = exports.InputStepMode || (exports.InputStepMode = {}));\nvar LoadOp;\n(function (LoadOp) {\n LoadOp["Load"] = "load";\n})(LoadOp = exports.LoadOp || (exports.LoadOp = {}));\nvar PrimitiveTopology;\n(function (PrimitiveTopology) {\n PrimitiveTopology["PointList"] = "point-list";\n PrimitiveTopology["LineList"] = "line-list";\n PrimitiveTopology["LineStrip"] = "line-strip";\n PrimitiveTopology["TriangleList"] = "triangle-list";\n PrimitiveTopology["TriangleStrip"] = "triangle-strip";\n})(PrimitiveTopology = exports.PrimitiveTopology || (exports.PrimitiveTopology = {}));\nvar StencilOperation;\n(function (StencilOperation) {\n StencilOperation["Keep"] = "keep";\n StencilOperation["Zero"] = "zero";\n StencilOperation["Replace"] = "replace";\n StencilOperation["Invert"] = "invert";\n StencilOperation["IncrementClamp"] = "increment-clamp";\n StencilOperation["DecrementClamp"] = "decrement-clamp";\n StencilOperation["IncrementWrap"] = "increment-wrap";\n StencilOperation["DecrementWrap"] = "decrement-wrap";\n})(StencilOperation = exports.StencilOperation || (exports.StencilOperation = {}));\nvar StoreOp;\n(function (StoreOp) {\n StoreOp["Store"] = "store";\n StoreOp["Clear"] = "clear";\n})(StoreOp = exports.StoreOp || (exports.StoreOp = {}));\nvar TextureDimension;\n(function (TextureDimension) {\n TextureDimension["E1d"] = "1d";\n TextureDimension["E2d"] = "2d";\n TextureDimension["E3d"] = "3d";\n})(TextureDimension = exports.TextureDimension || (exports.TextureDimension = {}));\nvar TextureFormat;\n(function (TextureFormat) {\n TextureFormat["R8Unorm"] = "r8unorm";\n TextureFormat["R8Snorm"] = "r8snorm";\n TextureFormat["R8Uint"] = "r8uint";\n TextureFormat["R8Sint"] = "r8sint";\n TextureFormat["R16Uint"] = "r16uint";\n TextureFormat["R16Sint"] = "r16sint";\n TextureFormat["R16Float"] = "r16float";\n TextureFormat["RG8Unorm"] = "rg8unorm";\n TextureFormat["RG8Snorm"] = "rg8snorm";\n TextureFormat["RG8Uint"] = "rg8uint";\n TextureFormat["RG8Sint"] = "rg8sint";\n TextureFormat["R32Uint"] = "r32uint";\n TextureFormat["R32Sint"] = "r32sint";\n TextureFormat["R32Float"] = "r32float";\n TextureFormat["RG16Uint"] = "rg16uint";\n TextureFormat["RG16Sint"] = "rg16sint";\n TextureFormat["RG16Float"] = "rg16float";\n TextureFormat["RGBA8Unorm"] = "rgba8unorm";\n TextureFormat["RGBA8UnormSRGB"] = "rgba8unorm-srgb";\n TextureFormat["RGBA8Snorm"] = "rgba8snorm";\n TextureFormat["RGBA8Uint"] = "rgba8uint";\n TextureFormat["RGBA8Sint"] = "rgba8sint";\n TextureFormat["BGRA8Unorm"] = "bgra8unorm";\n TextureFormat["BGRA8UnormSRGB"] = "bgra8unorm-srgb";\n TextureFormat["RGB10A2Unorm"] = "rgb10a2unorm";\n TextureFormat["RG11B10Float"] = "rg11b10float";\n TextureFormat["RG32Uint"] = "rg32uint";\n TextureFormat["RG32Sint"] = "rg32sint";\n TextureFormat["RG32Float"] = "rg32float";\n TextureFormat["RGBA16Uint"] = "rgba16uint";\n TextureFormat["RGBA16Sint"] = "rgba16sint";\n TextureFormat["RGBA16Float"] = "rgba16float";\n TextureFormat["RGBA32Uint"] = "rgba32uint";\n TextureFormat["RGBA32Sint"] = "rgba32sint";\n TextureFormat["RGBA32Float"] = "rgba32float";\n TextureFormat["Depth32Float"] = "depth32float";\n TextureFormat["Depth24Plus"] = "depth24plus";\n TextureFormat["Depth24PlusStencil8"] = "depth24plus-stencil8";\n})(TextureFormat = exports.TextureFormat || (exports.TextureFormat = {}));\nvar TextureComponentType;\n(function (TextureComponentType) {\n TextureComponentType["Float"] = "float";\n TextureComponentType["Sint"] = "sint";\n TextureComponentType["Uint"] = "uint";\n})(TextureComponentType = exports.TextureComponentType || (exports.TextureComponentType = {}));\nvar TextureViewDimension;\n(function (TextureViewDimension) {\n TextureViewDimension["E1d"] = "1d";\n TextureViewDimension["E2d"] = "2d";\n TextureViewDimension["E2dArray"] = "2d-array";\n TextureViewDimension["Cube"] = "cube";\n TextureViewDimension["CubeArray"] = "cube-array";\n TextureViewDimension["E3d"] = "3d";\n})(TextureViewDimension = exports.TextureViewDimension || (exports.TextureViewDimension = {}));\nvar VertexFormat;\n(function (VertexFormat) {\n VertexFormat["Uchar2"] = "uchar2";\n VertexFormat["Uchar4"] = "uchar4";\n VertexFormat["Char2"] = "char2";\n VertexFormat["Char4"] = "char4";\n VertexFormat["Uchar2Norm"] = "uchar2norm";\n VertexFormat["Uchar4Norm"] = "uchar4norm";\n VertexFormat["Char2Norm"] = "char2norm";\n VertexFormat["Char4Norm"] = "char4norm";\n VertexFormat["Ushort2"] = "ushort2";\n VertexFormat["Ushort4"] = "ushort4";\n VertexFormat["Short2"] = "short2";\n VertexFormat["Short4"] = "short4";\n VertexFormat["Ushort2Norm"] = "ushort2norm";\n VertexFormat["Ushort4Norm"] = "ushort4norm";\n VertexFormat["Short2Norm"] = "short2norm";\n VertexFormat["Short4Norm"] = "short4norm";\n VertexFormat["Half2"] = "half2";\n VertexFormat["Half4"] = "half4";\n VertexFormat["Float"] = "float";\n VertexFormat["Float2"] = "float2";\n VertexFormat["Float3"] = "float3";\n VertexFormat["Float4"] = "float4";\n VertexFormat["Uint"] = "uint";\n VertexFormat["Uint2"] = "uint2";\n VertexFormat["Uint3"] = "uint3";\n VertexFormat["Uint4"] = "uint4";\n VertexFormat["Int"] = "int";\n VertexFormat["Int2"] = "int2";\n VertexFormat["Int3"] = "int3";\n VertexFormat["Int4"] = "int4";\n})(VertexFormat = exports.VertexFormat || (exports.VertexFormat = {}));\nvar TextureAspect;\n(function (TextureAspect) {\n TextureAspect["All"] = "all";\n TextureAspect["StencilOnly"] = "stencil-only";\n TextureAspect["DepthOnly"] = "depth-only";\n})(TextureAspect = exports.TextureAspect || (exports.TextureAspect = {}));\nvar CompilationMessageType;\n(function (CompilationMessageType) {\n CompilationMessageType["Error"] = "error";\n CompilationMessageType["Warning"] = "warning";\n CompilationMessageType["Info"] = "info";\n})(CompilationMessageType = exports.CompilationMessageType || (exports.CompilationMessageType = {}));\nvar QueryType;\n(function (QueryType) {\n QueryType["Occlusion"] = "occlusion";\n})(QueryType = exports.QueryType || (exports.QueryType = {}));\n// Bit fields\nvar BufferUsage;\n(function (BufferUsage) {\n BufferUsage[BufferUsage["MapRead"] = 1] = "MapRead";\n BufferUsage[BufferUsage["MapWrite"] = 2] = "MapWrite";\n BufferUsage[BufferUsage["CopySrc"] = 4] = "CopySrc";\n BufferUsage[BufferUsage["CopyDst"] = 8] = "CopyDst";\n BufferUsage[BufferUsage["Index"] = 16] = "Index";\n BufferUsage[BufferUsage["Vertex"] = 32] = "Vertex";\n BufferUsage[BufferUsage["Uniform"] = 64] = "Uniform";\n BufferUsage[BufferUsage["Storage"] = 128] = "Storage";\n BufferUsage[BufferUsage["Indirect"] = 256] = "Indirect";\n BufferUsage[BufferUsage["QueryResolve"] = 512] = "QueryResolve";\n})(BufferUsage = exports.BufferUsage || (exports.BufferUsage = {}));\nvar ColorWrite;\n(function (ColorWrite) {\n ColorWrite[ColorWrite["Red"] = 1] = "Red";\n ColorWrite[ColorWrite["Green"] = 2] = "Green";\n ColorWrite[ColorWrite["Blue"] = 4] = "Blue";\n ColorWrite[ColorWrite["Alpha"] = 8] = "Alpha";\n ColorWrite[ColorWrite["All"] = 15] = "All";\n})(ColorWrite = exports.ColorWrite || (exports.ColorWrite = {}));\nvar ShaderStage;\n(function (ShaderStage) {\n ShaderStage[ShaderStage["Vertex"] = 1] = "Vertex";\n ShaderStage[ShaderStage["Fragment"] = 2] = "Fragment";\n ShaderStage[ShaderStage["Compute"] = 4] = "Compute";\n})(ShaderStage = exports.ShaderStage || (exports.ShaderStage = {}));\nvar TextureUsage;\n(function (TextureUsage) {\n TextureUsage[TextureUsage["CopySrc"] = 1] = "CopySrc";\n TextureUsage[TextureUsage["CopyDst"] = 2] = "CopyDst";\n TextureUsage[TextureUsage["Sampled"] = 4] = "Sampled";\n TextureUsage[TextureUsage["Storage"] = 8] = "Storage";\n TextureUsage[TextureUsage["OutputAttachment"] = 16] = "OutputAttachment";\n})(TextureUsage = exports.TextureUsage || (exports.TextureUsage = {}));\nvar MapMode;\n(function (MapMode) {\n MapMode[MapMode["Read"] = 1] = "Read";\n MapMode[MapMode["Write"] = 2] = "Write";\n})(MapMode = exports.MapMode || (exports.MapMode = {}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQHdlYmdwdS90eXBlcy9kaXN0L2NvbnN0YW50cy5qcz81ZTQ1Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFhO0FBQ2I7QUFDQSw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxzRUFBc0U7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsZ0VBQWdFO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxnRUFBZ0U7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxnRUFBZ0U7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLHlFQUF5RTtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsNEVBQTRFO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLHVEQUF1RDtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsNkRBQTZEO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQywwREFBMEQ7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLGdFQUFnRTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsc0VBQXNFO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBLENBQUMsaURBQWlEO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxrRkFBa0Y7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLCtFQUErRTtBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsb0RBQW9EO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLCtFQUErRTtBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsc0VBQXNFO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLDJGQUEyRjtBQUM1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQywyRkFBMkY7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsbUVBQW1FO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLHNFQUFzRTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxpR0FBaUc7QUFDbEc7QUFDQTtBQUNBO0FBQ0EsQ0FBQywwREFBMEQ7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLGdFQUFnRTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsNkRBQTZEO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLGdFQUFnRTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsbUVBQW1FO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxvREFBb0QiLCJmaWxlIjoiOC5qcyIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2dwdXdlYi9ncHV3ZWIvYmxvYi8wMWIyMGI0YWQ5M2ZhYmFlMWU4ZTBkNzc1MjUxNWY2OTcwOGQzM2UwL3NwZWMvaW5kZXguYnNcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8vIHRzbGludDpkaXNhYmxlOnZhcmlhYmxlLW5hbWVcbi8vIFN0cmluZyBlbnVtc1xudmFyIEV4dGVuc2lvbk5hbWU7XG4oZnVuY3Rpb24gKEV4dGVuc2lvbk5hbWUpIHtcbiAgICBFeHRlbnNpb25OYW1lW1wiVGV4dHVyZUNvbXByZXNzaW9uQkNcIl0gPSBcInRleHR1cmUtY29tcHJlc3Npb24tYmNcIjtcbn0pKEV4dGVuc2lvbk5hbWUgPSBleHBvcnRzLkV4dGVuc2lvbk5hbWUgfHwgKGV4cG9ydHMuRXh0ZW5zaW9uTmFtZSA9IHt9KSk7XG52YXIgQWRkcmVzc01vZGU7XG4oZnVuY3Rpb24gKEFkZHJlc3NNb2RlKSB7XG4gICAgQWRkcmVzc01vZGVbXCJDbGFtcFRvRWRnZVwiXSA9IFwiY2xhbXAtdG8tZWRnZVwiO1xuICAgIEFkZHJlc3NNb2RlW1wiUmVwZWF0XCJdID0gXCJyZXBlYXRcIjtcbiAgICBBZGRyZXNzTW9kZVtcIk1pcnJvclJlcGVhdFwiXSA9IFwibWlycm9yLXJlcGVhdFwiO1xufSkoQWRkcmVzc01vZGUgPSBleHBvcnRzLkFkZHJlc3NNb2RlIHx8IChleHBvcnRzLkFkZHJlc3NNb2RlID0ge30pKTtcbnZhciBCaW5kaW5nVHlwZTtcbihmdW5jdGlvbiAoQmluZGluZ1R5cGUpIHtcbiAgICBCaW5kaW5nVHlwZVtcIlVuaWZvcm1CdWZmZXJcIl0gPSBcInVuaWZvcm0tYnVmZmVyXCI7XG4gICAgQmluZGluZ1R5cGVbXCJTdG9yYWdlQnVmZmVyXCJdID0gXCJzdG9yYWdlLWJ1ZmZlclwiO1xuICAgIEJpbmRpbmdUeXBlW1wiUmVhZG9ubHlTdG9yYWdlQnVmZmVyXCJdID0gXCJyZWFkb25seS1zdG9yYWdlLWJ1ZmZlclwiO1xuICAgIEJpbmRpbmdUeXBlW1wiU2FtcGxlclwiXSA9IFwic2FtcGxlclwiO1xuICAgIEJpbmRpbmdUeXBlW1wiQ29tcGFyaXNvblNhbXBsZXJcIl0gPSBcImNvbXBhcmlzb24tc2FtcGxlclwiO1xuICAgIEJpbmRpbmdUeXBlW1wiU2FtcGxlZFRleHR1cmVcIl0gPSBcInNhbXBsZWQtdGV4dHVyZVwiO1xuICAgIEJpbmRpbmdUeXBlW1wiUmVhZG9ubHlTdG9yYWdlVGV4dHVyZVwiXSA9IFwicmVhZG9ubHktc3RvcmFnZS10ZXh0dXJlXCI7XG4gICAgQmluZGluZ1R5cGVbXCJXcml0ZW9ubHlTdG9yYWdlVGV4dHVyZVwiXSA9IFwid3JpdGVvbmx5LXN0b3JhZ2UtdGV4dHVyZVwiO1xufSkoQmluZGluZ1R5cGUgPSBleHBvcnRzLkJpbmRpbmdUeXBlIHx8IChleHBvcnRzLkJpbmRpbmdUeXBlID0ge30pKTtcbnZhciBCbGVuZEZhY3RvcjtcbihmdW5jdGlvbiAoQmxlbmRGYWN0b3IpIHtcbiAgICBCbGVuZEZhY3RvcltcIlplcm9cIl0gPSBcInplcm9cIjtcbiAgICBCbGVuZEZhY3RvcltcIk9uZVwiXSA9IFwib25lXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJTcmNDb2xvclwiXSA9IFwic3JjLWNvbG9yXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJPbmVNaW51c1NyY0NvbG9yXCJdID0gXCJvbmUtbWludXMtc3JjLWNvbG9yXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJTcmNBbHBoYVwiXSA9IFwic3JjLWFscGhhXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJPbmVNaW51c1NyY0FscGhhXCJdID0gXCJvbmUtbWludXMtc3JjLWFscGhhXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJEc3RDb2xvclwiXSA9IFwiZHN0LWNvbG9yXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJPbmVNaW51c0RzdENvbG9yXCJdID0gXCJvbmUtbWludXMtZHN0LWNvbG9yXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJEc3RBbHBoYVwiXSA9IFwiZHN0LWFscGhhXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJPbmVNaW51c0RzdEFscGhhXCJdID0gXCJvbmUtbWludXMtZHN0LWFscGhhXCI7XG4gICAgQmxlbmRGYWN0b3JbXCJTcmNBbHBoYVNhdHVyYXRlZFwiXSA9IFwic3JjLWFscGhhLXNhdHVyYXRlZFwiO1xuICAgIEJsZW5kRmFjdG9yW1wiQmxlbmRDb2xvclwiXSA9IFwiYmxlbmQtY29sb3JcIjtcbiAgICBCbGVuZEZhY3RvcltcIk9uZU1pbnVzQmxlbmRDb2xvclwiXSA9IFwib25lLW1pbnVzLWJsZW5kLWNvbG9yXCI7XG59KShCbGVuZEZhY3RvciA9IGV4cG9ydHMuQmxlbmRGYWN0b3IgfHwgKGV4cG9ydHMuQmxlbmRGYWN0b3IgPSB7fSkpO1xudmFyIEJsZW5kT3BlcmF0aW9uO1xuKGZ1bmN0aW9uIChCbGVuZE9wZXJhdGlvbikge1xuICAgIEJsZW5kT3BlcmF0aW9uW1wiQWRkXCJdID0gXCJhZGRcIjtcbiAgICBCbGVuZE9wZXJhdGlvbltcIlN1YnRyYWN0XCJdID0gXCJzdWJ0cmFjdFwiO1xuICAgIEJsZW5kT3BlcmF0aW9uW1wiUmV2ZXJzZVN1YnRyYWN0XCJdID0gXCJyZXZlcnNlLXN1YnRyYWN0XCI7XG4gICAgQmxlbmRPcGVyYXRpb25bXCJNaW5cIl0gPSBcIm1pblwiO1xuICAgIEJsZW5kT3BlcmF0aW9uW1wiTWF4XCJdID0gXCJtYXhcIjtcbn0pKEJsZW5kT3BlcmF0aW9uID0gZXhwb3J0cy5CbGVuZE9wZXJhdGlvbiB8fCAoZXhwb3J0cy5CbGVuZE9wZXJhdGlvbiA9IHt9KSk7XG52YXIgQ29tcGFyZUZ1bmN0aW9uO1xuKGZ1bmN0aW9uIChDb21wYXJlRnVuY3Rpb24pIHtcbiAgICBDb21wYXJlRnVuY3Rpb25bXCJOZXZlclwiXSA9IFwibmV2ZXJcIjtcbiAgICBDb21wYXJlRnVuY3Rpb25bXCJMZXNzXCJdID0gXCJsZXNzXCI7XG4gICAgQ29tcGFyZUZ1bmN0aW9uW1wiRXF1YWxcIl0gPSBcImVxdWFsXCI7XG4gICAgQ29tcGFyZUZ1bmN0aW9uW1wiTGVzc0VxdWFsXCJdID0gXCJsZXNzLWVxdWFsXCI7XG4gICAgQ29tcGFyZUZ1bmN0aW9uW1wiR3JlYXRlclwiXSA9IFwiZ3JlYXRlclwiO1xuICAgIENvbXBhcmVGdW5jdGlvbltcIk5vdEVxdWFsXCJdID0gXCJub3QtZXF1YWxcIjtcbiAgICBDb21wYXJlRnVuY3Rpb25bXCJHcmVhdGVyRXF1YWxcIl0gPSBcImdyZWF0ZXItZXF1YWxcIjtcbiAgICBDb21wYXJlRnVuY3Rpb25bXCJBbHdheXNcIl0gPSBcImFsd2F5c1wiO1xufSkoQ29tcGFyZUZ1bmN0aW9uID0gZXhwb3J0cy5Db21wYXJlRnVuY3Rpb24gfHwgKGV4cG9ydHMuQ29tcGFyZUZ1bmN0aW9uID0ge30pKTtcbnZhciBDdWxsTW9kZTtcbihmdW5jdGlvbiAoQ3VsbE1vZGUpIHtcbiAgICBDdWxsTW9kZVtcIk5vbmVcIl0gPSBcIm5vbmVcIjtcbiAgICBDdWxsTW9kZVtcIkZyb250XCJdID0gXCJmcm9udFwiO1xuICAgIEN1bGxNb2RlW1wiQmFja1wiXSA9IFwiYmFja1wiO1xufSkoQ3VsbE1vZGUgPSBleHBvcnRzLkN1bGxNb2RlIHx8IChleHBvcnRzLkN1bGxNb2RlID0ge30pKTtcbnZhciBGaWx0ZXJNb2RlO1xuKGZ1bmN0aW9uIChGaWx0ZXJNb2RlKSB7XG4gICAgRmlsdGVyTW9kZVtcIk5lYXJlc3RcIl0gPSBcIm5lYXJlc3RcIjtcbiAgICBGaWx0ZXJNb2RlW1wiTGluZWFyXCJdID0gXCJsaW5lYXJcIjtcbn0pKEZpbHRlck1vZGUgPSBleHBvcnRzLkZpbHRlck1vZGUgfHwgKGV4cG9ydHMuRmlsdGVyTW9kZSA9IHt9KSk7XG52YXIgRnJvbnRGYWNlO1xuKGZ1bmN0aW9uIChGcm9udEZhY2UpIHtcbiAgICBGcm9udEZhY2VbXCJDQ1dcIl0gPSBcImNjd1wiO1xuICAgIEZyb250RmFjZVtcIkNXXCJdID0gXCJjd1wiO1xufSkoRnJvbnRGYWNlID0gZXhwb3J0cy5Gcm9udEZhY2UgfHwgKGV4cG9ydHMuRnJvbnRGYWNlID0ge30pKTtcbnZhciBJbmRleEZvcm1hdDtcbihmdW5jdGlvbiAoSW5kZXhGb3JtYXQpIHtcbiAgICBJbmRleEZvcm1hdFtcIlVpbnQxNlwiXSA9IFwidWludDE2XCI7XG4gICAgSW5kZXhGb3JtYXRbXCJVaW50MzJcIl0gPSBcInVpbnQzMlwiO1xufSkoSW5kZXhGb3JtYXQgPSBleHBvcnRzLkluZGV4Rm9ybWF0IHx8IChleHBvcnRzLkluZGV4Rm9ybWF0ID0ge30pKTtcbnZhciBJbnB1dFN0ZXBNb2RlO1xuKGZ1bmN0aW9uIChJbnB1dFN0ZXBNb2RlKSB7XG4gICAgSW5wdXRTdGVwTW9kZVtcIlZlcnRleFwiXSA9IFwidmVydGV4XCI7XG4gICAgSW5wdXRTdGVwTW9kZVtcIkluc3RhbmNlXCJdID0gXCJpbnN0YW5jZVwiO1xufSkoSW5wdXRTdGVwTW9kZSA9IGV4cG9ydHMuSW5wdXRTdGVwTW9kZSB8fCAoZXhwb3J0cy5JbnB1dFN0ZXBNb2RlID0ge30pKTtcbnZhciBMb2FkT3A7XG4oZnVuY3Rpb24gKExvYWRPcCkge1xuICAgIExvYWRPcFtcIkxvYWRcIl0gPSBcImxvYWRcIjtcbn0pKExvYWRPcCA9IGV4cG9ydHMuTG9hZE9wIHx8IChleHBvcnRzLkxvYWRPcCA9IHt9KSk7XG52YXIgUHJpbWl0aXZlVG9wb2xvZ3k7XG4oZnVuY3Rpb24gKFByaW1pdGl2ZVRvcG9sb2d5KSB7XG4gICAgUHJpbWl0aXZlVG9wb2xvZ3lbXCJQb2ludExpc3RcIl0gPSBcInBvaW50LWxpc3RcIjtcbiAgICBQcmltaXRpdmVUb3BvbG9neVtcIkxpbmVMaXN0XCJdID0gXCJsaW5lLWxpc3RcIjtcbiAgICBQcmltaXRpdmVUb3BvbG9neVtcIkxpbmVTdHJpcFwiXSA9IFwibGluZS1zdHJpcFwiO1xuICAgIFByaW1pdGl2ZVRvcG9sb2d5W1wiVHJpYW5nbGVMaXN0XCJdID0gXCJ0cmlhbmdsZS1saXN0XCI7XG4gICAgUHJpbWl0aXZlVG9wb2xvZ3lbXCJUcmlhbmdsZVN0cmlwXCJdID0gXCJ0cmlhbmdsZS1zdHJpcFwiO1xufSkoUHJpbWl0aXZlVG9wb2xvZ3kgPSBleHBvcnRzLlByaW1pdGl2ZVRvcG9sb2d5IHx8IChleHBvcnRzLlByaW1pdGl2ZVRvcG9sb2d5ID0ge30pKTtcbnZhciBTdGVuY2lsT3BlcmF0aW9uO1xuKGZ1bmN0aW9uIChTdGVuY2lsT3BlcmF0aW9uKSB7XG4gICAgU3RlbmNpbE9wZXJhdGlvbltcIktlZXBcIl0gPSBcImtlZXBcIjtcbiAgICBTdGVuY2lsT3BlcmF0aW9uW1wiWmVyb1wiXSA9IFwiemVyb1wiO1xuICAgIFN0ZW5jaWxPcGVyYXRpb25bXCJSZXBsYWNlXCJdID0gXCJyZXBsYWNlXCI7XG4gICAgU3RlbmNpbE9wZXJhdGlvbltcIkludmVydFwiXSA9IFwiaW52ZXJ0XCI7XG4gICAgU3RlbmNpbE9wZXJhdGlvbltcIkluY3JlbWVudENsYW1wXCJdID0gXCJpbmNyZW1lbnQtY2xhbXBcIjtcbiAgICBTdGVuY2lsT3BlcmF0aW9uW1wiRGVjcmVtZW50Q2xhbXBcIl0gPSBcImRlY3JlbWVudC1jbGFtcFwiO1xuICAgIFN0ZW5jaWxPcGVyYXRpb25bXCJJbmNyZW1lbnRXcmFwXCJdID0gXCJpbmNyZW1lbnQtd3JhcFwiO1xuICAgIFN0ZW5jaWxPcGVyYXRpb25bXCJEZWNyZW1lbnRXcmFwXCJdID0gXCJkZWNyZW1lbnQtd3JhcFwiO1xufSkoU3RlbmNpbE9wZXJhdGlvbiA9IGV4cG9ydHMuU3RlbmNpbE9wZXJhdGlvbiB8fCAoZXhwb3J0cy5TdGVuY2lsT3BlcmF0aW9uID0ge30pKTtcbnZhciBTdG9yZU9wO1xuKGZ1bmN0aW9uIChTdG9yZU9wKSB7XG4gICAgU3RvcmVPcFtcIlN0b3JlXCJdID0gXCJzdG9yZVwiO1xuICAgIFN0b3JlT3BbXCJDbGVhclwiXSA9IFwiY2xlYXJcIjtcbn0pKFN0b3JlT3AgPSBleHBvcnRzLlN0b3JlT3AgfHwgKGV4cG9ydHMuU3RvcmVPcCA9IHt9KSk7XG52YXIgVGV4dHVyZURpbWVuc2lvbjtcbihmdW5jdGlvbiAoVGV4dHVyZURpbWVuc2lvbikge1xuICAgIFRleHR1cmVEaW1lbnNpb25bXCJFMWRcIl0gPSBcIjFkXCI7XG4gICAgVGV4dHVyZURpbWVuc2lvbltcIkUyZFwiXSA9IFwiMmRcIjtcbiAgICBUZXh0dXJlRGltZW5zaW9uW1wiRTNkXCJdID0gXCIzZFwiO1xufSkoVGV4dHVyZURpbWVuc2lvbiA9IGV4cG9ydHMuVGV4dHVyZURpbWVuc2lvbiB8fCAoZXhwb3J0cy5UZXh0dXJlRGltZW5zaW9uID0ge30pKTtcbnZhciBUZXh0dXJlRm9ybWF0O1xuKGZ1bmN0aW9uIChUZXh0dXJlRm9ybWF0KSB7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlI4VW5vcm1cIl0gPSBcInI4dW5vcm1cIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUjhTbm9ybVwiXSA9IFwicjhzbm9ybVwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSOFVpbnRcIl0gPSBcInI4dWludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSOFNpbnRcIl0gPSBcInI4c2ludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSMTZVaW50XCJdID0gXCJyMTZ1aW50XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlIxNlNpbnRcIl0gPSBcInIxNnNpbnRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUjE2RmxvYXRcIl0gPSBcInIxNmZsb2F0XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlJHOFVub3JtXCJdID0gXCJyZzh1bm9ybVwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSRzhTbm9ybVwiXSA9IFwicmc4c25vcm1cIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkc4VWludFwiXSA9IFwicmc4dWludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSRzhTaW50XCJdID0gXCJyZzhzaW50XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlIzMlVpbnRcIl0gPSBcInIzMnVpbnRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUjMyU2ludFwiXSA9IFwicjMyc2ludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSMzJGbG9hdFwiXSA9IFwicjMyZmxvYXRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkcxNlVpbnRcIl0gPSBcInJnMTZ1aW50XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlJHMTZTaW50XCJdID0gXCJyZzE2c2ludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSRzE2RmxvYXRcIl0gPSBcInJnMTZmbG9hdFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSR0JBOFVub3JtXCJdID0gXCJyZ2JhOHVub3JtXCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlJHQkE4VW5vcm1TUkdCXCJdID0gXCJyZ2JhOHVub3JtLXNyZ2JcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkdCQThTbm9ybVwiXSA9IFwicmdiYThzbm9ybVwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSR0JBOFVpbnRcIl0gPSBcInJnYmE4dWludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSR0JBOFNpbnRcIl0gPSBcInJnYmE4c2ludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJCR1JBOFVub3JtXCJdID0gXCJiZ3JhOHVub3JtXCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIkJHUkE4VW5vcm1TUkdCXCJdID0gXCJiZ3JhOHVub3JtLXNyZ2JcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkdCMTBBMlVub3JtXCJdID0gXCJyZ2IxMGEydW5vcm1cIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkcxMUIxMEZsb2F0XCJdID0gXCJyZzExYjEwZmxvYXRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkczMlVpbnRcIl0gPSBcInJnMzJ1aW50XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlJHMzJTaW50XCJdID0gXCJyZzMyc2ludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSRzMyRmxvYXRcIl0gPSBcInJnMzJmbG9hdFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSR0JBMTZVaW50XCJdID0gXCJyZ2JhMTZ1aW50XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlJHQkExNlNpbnRcIl0gPSBcInJnYmExNnNpbnRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkdCQTE2RmxvYXRcIl0gPSBcInJnYmExNmZsb2F0XCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIlJHQkEzMlVpbnRcIl0gPSBcInJnYmEzMnVpbnRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiUkdCQTMyU2ludFwiXSA9IFwicmdiYTMyc2ludFwiO1xuICAgIFRleHR1cmVGb3JtYXRbXCJSR0JBMzJGbG9hdFwiXSA9IFwicmdiYTMyZmxvYXRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiRGVwdGgzMkZsb2F0XCJdID0gXCJkZXB0aDMyZmxvYXRcIjtcbiAgICBUZXh0dXJlRm9ybWF0W1wiRGVwdGgyNFBsdXNcIl0gPSBcImRlcHRoMjRwbHVzXCI7XG4gICAgVGV4dHVyZUZvcm1hdFtcIkRlcHRoMjRQbHVzU3RlbmNpbDhcIl0gPSBcImRlcHRoMjRwbHVzLXN0ZW5jaWw4XCI7XG59KShUZXh0dXJlRm9ybWF0ID0gZXhwb3J0cy5UZXh0dXJlRm9ybWF0IHx8IChleHBvcnRzLlRleHR1cmVGb3JtYXQgPSB7fSkpO1xudmFyIFRleHR1cmVDb21wb25lbnRUeXBlO1xuKGZ1bmN0aW9uIChUZXh0dXJlQ29tcG9uZW50VHlwZSkge1xuICAgIFRleHR1cmVDb21wb25lbnRUeXBlW1wiRmxvYXRcIl0gPSBcImZsb2F0XCI7XG4gICAgVGV4dHVyZUNvbXBvbmVudFR5cGVbXCJTaW50XCJdID0gXCJzaW50XCI7XG4gICAgVGV4dHVyZUNvbXBvbmVudFR5cGVbXCJVaW50XCJdID0gXCJ1aW50XCI7XG59KShUZXh0dXJlQ29tcG9uZW50VHlwZSA9IGV4cG9ydHMuVGV4dHVyZUNvbXBvbmVudFR5cGUgfHwgKGV4cG9ydHMuVGV4dHVyZUNvbXBvbmVudFR5cGUgPSB7fSkpO1xudmFyIFRleHR1cmVWaWV3RGltZW5zaW9uO1xuKGZ1bmN0aW9uIChUZXh0dXJlVmlld0RpbWVuc2lvbikge1xuICAgIFRleHR1cmVWaWV3RGltZW5zaW9uW1wiRTFkXCJdID0gXCIxZFwiO1xuICAgIFRleHR1cmVWaWV3RGltZW5zaW9uW1wiRTJkXCJdID0gXCIyZFwiO1xuICAgIFRleHR1cmVWaWV3RGltZW5zaW9uW1wiRTJkQXJyYXlcIl0gPSBcIjJkLWFycmF5XCI7XG4gICAgVGV4dHVyZVZpZXdEaW1lbnNpb25bXCJDdWJlXCJdID0gXCJjdWJlXCI7XG4gICAgVGV4dHVyZVZpZXdEaW1lbnNpb25bXCJDdWJlQXJyYXlcIl0gPSBcImN1YmUtYXJyYXlcIjtcbiAgICBUZXh0dXJlVmlld0RpbWVuc2lvbltcIkUzZFwiXSA9IFwiM2RcIjtcbn0pKFRleHR1cmVWaWV3RGltZW5zaW9uID0gZXhwb3J0cy5UZXh0dXJlVmlld0RpbWVuc2lvbiB8fCAoZXhwb3J0cy5UZXh0dXJlVmlld0RpbWVuc2lvbiA9IHt9KSk7XG52YXIgVmVydGV4Rm9ybWF0O1xuKGZ1bmN0aW9uIChWZXJ0ZXhGb3JtYXQpIHtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJVY2hhcjJcIl0gPSBcInVjaGFyMlwiO1xuICAgIFZlcnRleEZvcm1hdFtcIlVjaGFyNFwiXSA9IFwidWNoYXI0XCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiQ2hhcjJcIl0gPSBcImNoYXIyXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiQ2hhcjRcIl0gPSBcImNoYXI0XCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVWNoYXIyTm9ybVwiXSA9IFwidWNoYXIybm9ybVwiO1xuICAgIFZlcnRleEZvcm1hdFtcIlVjaGFyNE5vcm1cIl0gPSBcInVjaGFyNG5vcm1cIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJDaGFyMk5vcm1cIl0gPSBcImNoYXIybm9ybVwiO1xuICAgIFZlcnRleEZvcm1hdFtcIkNoYXI0Tm9ybVwiXSA9IFwiY2hhcjRub3JtXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVXNob3J0MlwiXSA9IFwidXNob3J0MlwiO1xuICAgIFZlcnRleEZvcm1hdFtcIlVzaG9ydDRcIl0gPSBcInVzaG9ydDRcIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJTaG9ydDJcIl0gPSBcInNob3J0MlwiO1xuICAgIFZlcnRleEZvcm1hdFtcIlNob3J0NFwiXSA9IFwic2hvcnQ0XCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVXNob3J0Mk5vcm1cIl0gPSBcInVzaG9ydDJub3JtXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVXNob3J0NE5vcm1cIl0gPSBcInVzaG9ydDRub3JtXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiU2hvcnQyTm9ybVwiXSA9IFwic2hvcnQybm9ybVwiO1xuICAgIFZlcnRleEZvcm1hdFtcIlNob3J0NE5vcm1cIl0gPSBcInNob3J0NG5vcm1cIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJIYWxmMlwiXSA9IFwiaGFsZjJcIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJIYWxmNFwiXSA9IFwiaGFsZjRcIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJGbG9hdFwiXSA9IFwiZmxvYXRcIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJGbG9hdDJcIl0gPSBcImZsb2F0MlwiO1xuICAgIFZlcnRleEZvcm1hdFtcIkZsb2F0M1wiXSA9IFwiZmxvYXQzXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiRmxvYXQ0XCJdID0gXCJmbG9hdDRcIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJVaW50XCJdID0gXCJ1aW50XCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVWludDJcIl0gPSBcInVpbnQyXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVWludDNcIl0gPSBcInVpbnQzXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiVWludDRcIl0gPSBcInVpbnQ0XCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiSW50XCJdID0gXCJpbnRcIjtcbiAgICBWZXJ0ZXhGb3JtYXRbXCJJbnQyXCJdID0gXCJpbnQyXCI7XG4gICAgVmVydGV4Rm9ybWF0W1wiSW50M1wiXSA9IFwiaW50M1wiO1xuICAgIFZlcnRleEZvcm1hdFtcIkludDRcIl0gPSBcImludDRcIjtcbn0pKFZlcnRleEZvcm1hdCA9IGV4cG9ydHMuVmVydGV4Rm9ybWF0IHx8IChleHBvcnRzLlZlcnRleEZvcm1hdCA9IHt9KSk7XG52YXIgVGV4dHVyZUFzcGVjdDtcbihmdW5jdGlvbiAoVGV4dHVyZUFzcGVjdCkge1xuICAgIFRleHR1cmVBc3BlY3RbXCJBbGxcIl0gPSBcImFsbFwiO1xuICAgIFRleHR1cmVBc3BlY3RbXCJTdGVuY2lsT25seVwiXSA9IFwic3RlbmNpbC1vbmx5XCI7XG4gICAgVGV4dHVyZUFzcGVjdFtcIkRlcHRoT25seVwiXSA9IFwiZGVwdGgtb25seVwiO1xufSkoVGV4dHVyZUFzcGVjdCA9IGV4cG9ydHMuVGV4dHVyZUFzcGVjdCB8fCAoZXhwb3J0cy5UZXh0dXJlQXNwZWN0ID0ge30pKTtcbnZhciBDb21waWxhdGlvbk1lc3NhZ2VUeXBlO1xuKGZ1bmN0aW9uIChDb21waWxhdGlvbk1lc3NhZ2VUeXBlKSB7XG4gICAgQ29tcGlsYXRpb25NZXNzYWdlVHlwZVtcIkVycm9yXCJdID0gXCJlcnJvclwiO1xuICAgIENvbXBpbGF0aW9uTWVzc2FnZVR5cGVbXCJXYXJuaW5nXCJdID0gXCJ3YXJuaW5nXCI7XG4gICAgQ29tcGlsYXRpb25NZXNzYWdlVHlwZVtcIkluZm9cIl0gPSBcImluZm9cIjtcbn0pKENvbXBpbGF0aW9uTWVzc2FnZVR5cGUgPSBleHBvcnRzLkNvbXBpbGF0aW9uTWVzc2FnZVR5cGUgfHwgKGV4cG9ydHMuQ29tcGlsYXRpb25NZXNzYWdlVHlwZSA9IHt9KSk7XG52YXIgUXVlcnlUeXBlO1xuKGZ1bmN0aW9uIChRdWVyeVR5cGUpIHtcbiAgICBRdWVyeVR5cGVbXCJPY2NsdXNpb25cIl0gPSBcIm9jY2x1c2lvblwiO1xufSkoUXVlcnlUeXBlID0gZXhwb3J0cy5RdWVyeVR5cGUgfHwgKGV4cG9ydHMuUXVlcnlUeXBlID0ge30pKTtcbi8vIEJpdCBmaWVsZHNcbnZhciBCdWZmZXJVc2FnZTtcbihmdW5jdGlvbiAoQnVmZmVyVXNhZ2UpIHtcbiAgICBCdWZmZXJVc2FnZVtCdWZmZXJVc2FnZVtcIk1hcFJlYWRcIl0gPSAxXSA9IFwiTWFwUmVhZFwiO1xuICAgIEJ1ZmZlclVzYWdlW0J1ZmZlclVzYWdlW1wiTWFwV3JpdGVcIl0gPSAyXSA9IFwiTWFwV3JpdGVcIjtcbiAgICBCdWZmZXJVc2FnZVtCdWZmZXJVc2FnZVtcIkNvcHlTcmNcIl0gPSA0XSA9IFwiQ29weVNyY1wiO1xuICAgIEJ1ZmZlclVzYWdlW0J1ZmZlclVzYWdlW1wiQ29weURzdFwiXSA9IDhdID0gXCJDb3B5RHN0XCI7XG4gICAgQnVmZmVyVXNhZ2VbQnVmZmVyVXNhZ2VbXCJJbmRleFwiXSA9IDE2XSA9IFwiSW5kZXhcIjtcbiAgICBCdWZmZXJVc2FnZVtCdWZmZXJVc2FnZVtcIlZlcnRleFwiXSA9IDMyXSA9IFwiVmVydGV4XCI7XG4gICAgQnVmZmVyVXNhZ2VbQnVmZmVyVXNhZ2VbXCJVbmlmb3JtXCJdID0gNjRdID0gXCJVbmlmb3JtXCI7XG4gICAgQnVmZmVyVXNhZ2VbQnVmZmVyVXNhZ2VbXCJTdG9yYWdlXCJdID0gMTI4XSA9IFwiU3RvcmFnZVwiO1xuICAgIEJ1ZmZlclVzYWdlW0J1ZmZlclVzYWdlW1wiSW5kaXJlY3RcIl0gPSAyNTZdID0gXCJJbmRpcmVjdFwiO1xuICAgIEJ1ZmZlclVzYWdlW0J1ZmZlclVzYWdlW1wiUXVlcnlSZXNvbHZlXCJdID0gNTEyXSA9IFwiUXVlcnlSZXNvbHZlXCI7XG59KShCdWZmZXJVc2FnZSA9IGV4cG9ydHMuQnVmZmVyVXNhZ2UgfHwgKGV4cG9ydHMuQnVmZmVyVXNhZ2UgPSB7fSkpO1xudmFyIENvbG9yV3JpdGU7XG4oZnVuY3Rpb24gKENvbG9yV3JpdGUpIHtcbiAgICBDb2xvcldyaXRlW0NvbG9yV3JpdGVbXCJSZWRcIl0gPSAxXSA9IFwiUmVkXCI7XG4gICAgQ29sb3JXcml0ZVtDb2xvcldyaXRlW1wiR3JlZW5cIl0gPSAyXSA9IFwiR3JlZW5cIjtcbiAgICBDb2xvcldyaXRlW0NvbG9yV3JpdGVbXCJCbHVlXCJdID0gNF0gPSBcIkJsdWVcIjtcbiAgICBDb2xvcldyaXRlW0NvbG9yV3JpdGVbXCJBbHBoYVwiXSA9IDhdID0gXCJBbHBoYVwiO1xuICAgIENvbG9yV3JpdGVbQ29sb3JXcml0ZVtcIkFsbFwiXSA9IDE1XSA9IFwiQWxsXCI7XG59KShDb2xvcldyaXRlID0gZXhwb3J0cy5Db2xvcldyaXRlIHx8IChleHBvcnRzLkNvbG9yV3JpdGUgPSB7fSkpO1xudmFyIFNoYWRlclN0YWdlO1xuKGZ1bmN0aW9uIChTaGFkZXJTdGFnZSkge1xuICAgIFNoYWRlclN0YWdlW1NoYWRlclN0YWdlW1wiVmVydGV4XCJdID0gMV0gPSBcIlZlcnRleFwiO1xuICAgIFNoYWRlclN0YWdlW1NoYWRlclN0YWdlW1wiRnJhZ21lbnRcIl0gPSAyXSA9IFwiRnJhZ21lbnRcIjtcbiAgICBTaGFkZXJTdGFnZVtTaGFkZXJTdGFnZVtcIkNvbXB1dGVcIl0gPSA0XSA9IFwiQ29tcHV0ZVwiO1xufSkoU2hhZGVyU3RhZ2UgPSBleHBvcnRzLlNoYWRlclN0YWdlIHx8IChleHBvcnRzLlNoYWRlclN0YWdlID0ge30pKTtcbnZhciBUZXh0dXJlVXNhZ2U7XG4oZnVuY3Rpb24gKFRleHR1cmVVc2FnZSkge1xuICAgIFRleHR1cmVVc2FnZVtUZXh0dXJlVXNhZ2VbXCJDb3B5U3JjXCJdID0gMV0gPSBcIkNvcHlTcmNcIjtcbiAgICBUZXh0dXJlVXNhZ2VbVGV4dHVyZVVzYWdlW1wiQ29weURzdFwiXSA9IDJdID0gXCJDb3B5RHN0XCI7XG4gICAgVGV4dHVyZVVzYWdlW1RleHR1cmVVc2FnZVtcIlNhbXBsZWRcIl0gPSA0XSA9IFwiU2FtcGxlZFwiO1xuICAgIFRleHR1cmVVc2FnZVtUZXh0dXJlVXNhZ2VbXCJTdG9yYWdlXCJdID0gOF0gPSBcIlN0b3JhZ2VcIjtcbiAgICBUZXh0dXJlVXNhZ2VbVGV4dHVyZVVzYWdlW1wiT3V0cHV0QXR0YWNobWVudFwiXSA9IDE2XSA9IFwiT3V0cHV0QXR0YWNobWVudFwiO1xufSkoVGV4dHVyZVVzYWdlID0gZXhwb3J0cy5UZXh0dXJlVXNhZ2UgfHwgKGV4cG9ydHMuVGV4dHVyZVVzYWdlID0ge30pKTtcbnZhciBNYXBNb2RlO1xuKGZ1bmN0aW9uIChNYXBNb2RlKSB7XG4gICAgTWFwTW9kZVtNYXBNb2RlW1wiUmVhZFwiXSA9IDFdID0gXCJSZWFkXCI7XG4gICAgTWFwTW9kZVtNYXBNb2RlW1wiV3JpdGVcIl0gPSAyXSA9IFwiV3JpdGVcIjtcbn0pKE1hcE1vZGUgPSBleHBvcnRzLk1hcE1vZGUgfHwgKGV4cG9ydHMuTWFwTW9kZSA9IHt9KSk7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8\n')},function(module,exports,__webpack_require__){eval("module.exports = __webpack_require__(498);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3IvaW5kZXguanM/YTM0YSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxpQkFBaUIsbUJBQU8sQ0FBQyxHQUFxQiIsImZpbGUiOiI5LmpzIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVnZW5lcmF0b3ItcnVudGltZVwiKTtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9\n")},function(module,exports){eval('function _initializerDefineProperty(target, property, descriptor, context) {\n if (!descriptor) return;\n Object.defineProperty(target, property, {\n enumerable: descriptor.enumerable,\n configurable: descriptor.configurable,\n writable: descriptor.writable,\n value: descriptor.initializer ? descriptor.initializer.call(context) : void 0\n });\n}\n\nmodule.exports = _initializerDefineProperty;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbml0aWFsaXplckRlZmluZVByb3BlcnR5LmpzP2M4NmYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQSIsImZpbGUiOiIxMC5qcyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9pbml0aWFsaXplckRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIGRlc2NyaXB0b3IsIGNvbnRleHQpIHtcbiAgaWYgKCFkZXNjcmlwdG9yKSByZXR1cm47XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7XG4gICAgZW51bWVyYWJsZTogZGVzY3JpcHRvci5lbnVtZXJhYmxlLFxuICAgIGNvbmZpZ3VyYWJsZTogZGVzY3JpcHRvci5jb25maWd1cmFibGUsXG4gICAgd3JpdGFibGU6IGRlc2NyaXB0b3Iud3JpdGFibGUsXG4gICAgdmFsdWU6IGRlc2NyaXB0b3IuaW5pdGlhbGl6ZXIgPyBkZXNjcmlwdG9yLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDBcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2luaXRpYWxpemVyRGVmaW5lUHJvcGVydHk7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///10\n')},function(module,exports){eval("function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {\n var desc = {};\n Object.keys(descriptor).forEach(function (key) {\n desc[key] = descriptor[key];\n });\n desc.enumerable = !!desc.enumerable;\n desc.configurable = !!desc.configurable;\n\n if ('value' in desc || desc.initializer) {\n desc.writable = true;\n }\n\n desc = decorators.slice().reverse().reduce(function (desc, decorator) {\n return decorator(target, property, desc) || desc;\n }, desc);\n\n if (context && desc.initializer !== void 0) {\n desc.value = desc.initializer ? desc.initializer.call(context) : void 0;\n desc.initializer = undefined;\n }\n\n if (desc.initializer === void 0) {\n Object.defineProperty(target, property, desc);\n desc = null;\n }\n\n return desc;\n}\n\nmodule.exports = _applyDecoratedDescriptor;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcHBseURlY29yYXRlZERlc2NyaXB0b3IuanM/NTNlYyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EiLCJmaWxlIjoiMTEuanMiLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHksIGRlY29yYXRvcnMsIGRlc2NyaXB0b3IsIGNvbnRleHQpIHtcbiAgdmFyIGRlc2MgPSB7fTtcbiAgT2JqZWN0LmtleXMoZGVzY3JpcHRvcikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgZGVzY1trZXldID0gZGVzY3JpcHRvcltrZXldO1xuICB9KTtcbiAgZGVzYy5lbnVtZXJhYmxlID0gISFkZXNjLmVudW1lcmFibGU7XG4gIGRlc2MuY29uZmlndXJhYmxlID0gISFkZXNjLmNvbmZpZ3VyYWJsZTtcblxuICBpZiAoJ3ZhbHVlJyBpbiBkZXNjIHx8IGRlc2MuaW5pdGlhbGl6ZXIpIHtcbiAgICBkZXNjLndyaXRhYmxlID0gdHJ1ZTtcbiAgfVxuXG4gIGRlc2MgPSBkZWNvcmF0b3JzLnNsaWNlKCkucmV2ZXJzZSgpLnJlZHVjZShmdW5jdGlvbiAoZGVzYywgZGVjb3JhdG9yKSB7XG4gICAgcmV0dXJuIGRlY29yYXRvcih0YXJnZXQsIHByb3BlcnR5LCBkZXNjKSB8fCBkZXNjO1xuICB9LCBkZXNjKTtcblxuICBpZiAoY29udGV4dCAmJiBkZXNjLmluaXRpYWxpemVyICE9PSB2b2lkIDApIHtcbiAgICBkZXNjLnZhbHVlID0gZGVzYy5pbml0aWFsaXplciA/IGRlc2MuaW5pdGlhbGl6ZXIuY2FsbChjb250ZXh0KSA6IHZvaWQgMDtcbiAgICBkZXNjLmluaXRpYWxpemVyID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKGRlc2MuaW5pdGlhbGl6ZXIgPT09IHZvaWQgMCkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCBkZXNjKTtcbiAgICBkZXNjID0gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBkZXNjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3I7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///11\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return EPSILON; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ARRAY_TYPE; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return RANDOM; });\n/* unused harmony export setMatrixArrayType */\n/* unused harmony export toRadian */\n/* unused harmony export equals */\n/**\n * Common utilities\n * @module glMatrix\n */\n// Configuration Constants\nvar EPSILON = 0.000001;\nvar ARRAY_TYPE = typeof Float32Array !== \'undefined\' ? Float32Array : Array;\nvar RANDOM = Math.random;\n/**\n * Sets the type of array used when creating new vectors and matrices\n *\n * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array\n */\n\nfunction setMatrixArrayType(type) {\n ARRAY_TYPE = type;\n}\nvar degree = Math.PI / 180;\n/**\n * Convert Degree To Radian\n *\n * @param {Number} a Angle in Degrees\n */\n\nfunction toRadian(a) {\n return a * degree;\n}\n/**\n * Tests whether or not the arguments have approximately the same value, within an absolute\n * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less\n * than or equal to 1.0, and a relative tolerance is used for larger values)\n *\n * @param {Number} a The first number to test.\n * @param {Number} b The second number to test.\n * @returns {Boolean} True if the numbers are approximately equal, false otherwise.\n */\n\nfunction equals(a, b) {\n return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b));\n}\nif (!Math.hypot) Math.hypot = function () {\n var y = 0,\n i = arguments.length;\n\n while (i--) {\n y += arguments[i] * arguments[i];\n }\n\n return Math.sqrt(y);\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS9jb21tb24uanM/Yzk0ZCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDQTtBQUNBO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsV0FBVywyQ0FBMkM7QUFDdEQ7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsYUFBYSxRQUFRO0FBQ3JCOztBQUVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiIxMi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tbW9uIHV0aWxpdGllc1xuICogQG1vZHVsZSBnbE1hdHJpeFxuICovXG4vLyBDb25maWd1cmF0aW9uIENvbnN0YW50c1xuZXhwb3J0IHZhciBFUFNJTE9OID0gMC4wMDAwMDE7XG5leHBvcnQgdmFyIEFSUkFZX1RZUEUgPSB0eXBlb2YgRmxvYXQzMkFycmF5ICE9PSAndW5kZWZpbmVkJyA/IEZsb2F0MzJBcnJheSA6IEFycmF5O1xuZXhwb3J0IHZhciBSQU5ET00gPSBNYXRoLnJhbmRvbTtcbi8qKlxuICogU2V0cyB0aGUgdHlwZSBvZiBhcnJheSB1c2VkIHdoZW4gY3JlYXRpbmcgbmV3IHZlY3RvcnMgYW5kIG1hdHJpY2VzXG4gKlxuICogQHBhcmFtIHtGbG9hdDMyQXJyYXlDb25zdHJ1Y3RvciB8IEFycmF5Q29uc3RydWN0b3J9IHR5cGUgQXJyYXkgdHlwZSwgc3VjaCBhcyBGbG9hdDMyQXJyYXkgb3IgQXJyYXlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0TWF0cml4QXJyYXlUeXBlKHR5cGUpIHtcbiAgQVJSQVlfVFlQRSA9IHR5cGU7XG59XG52YXIgZGVncmVlID0gTWF0aC5QSSAvIDE4MDtcbi8qKlxuICogQ29udmVydCBEZWdyZWUgVG8gUmFkaWFuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGEgQW5nbGUgaW4gRGVncmVlc1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1JhZGlhbihhKSB7XG4gIHJldHVybiBhICogZGVncmVlO1xufVxuLyoqXG4gKiBUZXN0cyB3aGV0aGVyIG9yIG5vdCB0aGUgYXJndW1lbnRzIGhhdmUgYXBwcm94aW1hdGVseSB0aGUgc2FtZSB2YWx1ZSwgd2l0aGluIGFuIGFic29sdXRlXG4gKiBvciByZWxhdGl2ZSB0b2xlcmFuY2Ugb2YgZ2xNYXRyaXguRVBTSUxPTiAoYW4gYWJzb2x1dGUgdG9sZXJhbmNlIGlzIHVzZWQgZm9yIHZhbHVlcyBsZXNzXG4gKiB0aGFuIG9yIGVxdWFsIHRvIDEuMCwgYW5kIGEgcmVsYXRpdmUgdG9sZXJhbmNlIGlzIHVzZWQgZm9yIGxhcmdlciB2YWx1ZXMpXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGEgVGhlIGZpcnN0IG51bWJlciB0byB0ZXN0LlxuICogQHBhcmFtIHtOdW1iZXJ9IGIgVGhlIHNlY29uZCBudW1iZXIgdG8gdGVzdC5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSBudW1iZXJzIGFyZSBhcHByb3hpbWF0ZWx5IGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBNYXRoLmFicyhhIC0gYikgPD0gRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYSksIE1hdGguYWJzKGIpKTtcbn1cbmlmICghTWF0aC5oeXBvdCkgTWF0aC5oeXBvdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHkgPSAwLFxuICAgICAgaSA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgd2hpbGUgKGktLSkge1xuICAgIHkgKz0gYXJndW1lbnRzW2ldICogYXJndW1lbnRzW2ldO1xuICB9XG5cbiAgcmV0dXJuIE1hdGguc3FydCh5KTtcbn07Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///12\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return IDENTIFIER; });\nvar IDENTIFIER = {\n // SceneGraph\n HierarchyComponentManager: Symbol('HierarchyComponentManager'),\n TransformComponentManager: Symbol('TransformComponentManager'),\n NameComponentManager: Symbol('NameComponentManager'),\n SceneGraphSystem: Symbol('SceneGraphSystem'),\n // FrameGraph\n FrameGraphSystem: Symbol('FrameGraphSystem'),\n ResourcePool: Symbol('ResourcePool'),\n ResourceHandleComponentManager: Symbol('ResourceHandleComponentManager'),\n PassNodeComponentManager: Symbol('PassNodeComponentManager'),\n // Renderer\n RendererSystem: Symbol('RendererSystem'),\n RenderPass: Symbol('RenderPass'),\n RenderPassFactory: Symbol('Factory'),\n Renderable: Symbol('Factory'),\n // Mesh\n MeshSystem: Symbol('MeshSystem'),\n MeshComponentManager: Symbol('MeshComponentManager'),\n CullableComponentManager: Symbol('CullableComponentManager'),\n // Geometry\n Geometry: Symbol('Geometry'),\n GeometrySystem: Symbol('GeometrySystem'),\n GeometryComponentManager: Symbol('GeometryComponentManager'),\n // Material\n Material: Symbol('Material'),\n MaterialSystem: Symbol('MaterialSystem'),\n MaterialComponentManager: Symbol('MaterialComponentManager'),\n // RenderPath\n ForwardRenderPath: Symbol('ForwardRenderPath'),\n // ComputeSystem\n ComputeSystem: Symbol('ComputeSystem'),\n ComputeComponentManager: Symbol('ComputeComponentManager'),\n ComputeStrategy: Symbol('ComputeStrategy'),\n Systems: Symbol('Systems'),\n World: Symbol('World'),\n // RenderEngine\n RenderEngine: Symbol('RenderEngine'),\n WebGPUEngine: Symbol('WebGPUEngine'),\n WebGLEngine: Symbol('WebGLEngine'),\n // Shader Module\n ShaderModuleService: Symbol('ShaderModuleService'),\n ConfigService: Symbol('ConfigService'),\n InteractorService: Symbol('InteractorService'),\n IEventEmitter: Symbol('IEventEmitter'),\n // Light\n Light: Symbol('Light')\n};\n//# sourceMappingURL=identifier.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy13ZWJncHUtY29yZS9lcy9pZGVudGlmaWVyLmpzP2ZhZTEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIxMy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB2YXIgSURFTlRJRklFUiA9IHtcbiAgLy8gU2NlbmVHcmFwaFxuICBIaWVyYXJjaHlDb21wb25lbnRNYW5hZ2VyOiBTeW1ib2woJ0hpZXJhcmNoeUNvbXBvbmVudE1hbmFnZXInKSxcbiAgVHJhbnNmb3JtQ29tcG9uZW50TWFuYWdlcjogU3ltYm9sKCdUcmFuc2Zvcm1Db21wb25lbnRNYW5hZ2VyJyksXG4gIE5hbWVDb21wb25lbnRNYW5hZ2VyOiBTeW1ib2woJ05hbWVDb21wb25lbnRNYW5hZ2VyJyksXG4gIFNjZW5lR3JhcGhTeXN0ZW06IFN5bWJvbCgnU2NlbmVHcmFwaFN5c3RlbScpLFxuICAvLyBGcmFtZUdyYXBoXG4gIEZyYW1lR3JhcGhTeXN0ZW06IFN5bWJvbCgnRnJhbWVHcmFwaFN5c3RlbScpLFxuICBSZXNvdXJjZVBvb2w6IFN5bWJvbCgnUmVzb3VyY2VQb29sJyksXG4gIFJlc291cmNlSGFuZGxlQ29tcG9uZW50TWFuYWdlcjogU3ltYm9sKCdSZXNvdXJjZUhhbmRsZUNvbXBvbmVudE1hbmFnZXInKSxcbiAgUGFzc05vZGVDb21wb25lbnRNYW5hZ2VyOiBTeW1ib2woJ1Bhc3NOb2RlQ29tcG9uZW50TWFuYWdlcicpLFxuICAvLyBSZW5kZXJlclxuICBSZW5kZXJlclN5c3RlbTogU3ltYm9sKCdSZW5kZXJlclN5c3RlbScpLFxuICBSZW5kZXJQYXNzOiBTeW1ib2woJ1JlbmRlclBhc3MnKSxcbiAgUmVuZGVyUGFzc0ZhY3Rvcnk6IFN5bWJvbCgnRmFjdG9yeTxJUmVuZGVyUGFzcz4nKSxcbiAgUmVuZGVyYWJsZTogU3ltYm9sKCdGYWN0b3J5PElSZW5kZXJQYXNzPicpLFxuICAvLyBNZXNoXG4gIE1lc2hTeXN0ZW06IFN5bWJvbCgnTWVzaFN5c3RlbScpLFxuICBNZXNoQ29tcG9uZW50TWFuYWdlcjogU3ltYm9sKCdNZXNoQ29tcG9uZW50TWFuYWdlcicpLFxuICBDdWxsYWJsZUNvbXBvbmVudE1hbmFnZXI6IFN5bWJvbCgnQ3VsbGFibGVDb21wb25lbnRNYW5hZ2VyJyksXG4gIC8vIEdlb21ldHJ5XG4gIEdlb21ldHJ5OiBTeW1ib2woJ0dlb21ldHJ5JyksXG4gIEdlb21ldHJ5U3lzdGVtOiBTeW1ib2woJ0dlb21ldHJ5U3lzdGVtJyksXG4gIEdlb21ldHJ5Q29tcG9uZW50TWFuYWdlcjogU3ltYm9sKCdHZW9tZXRyeUNvbXBvbmVudE1hbmFnZXInKSxcbiAgLy8gTWF0ZXJpYWxcbiAgTWF0ZXJpYWw6IFN5bWJvbCgnTWF0ZXJpYWwnKSxcbiAgTWF0ZXJpYWxTeXN0ZW06IFN5bWJvbCgnTWF0ZXJpYWxTeXN0ZW0nKSxcbiAgTWF0ZXJpYWxDb21wb25lbnRNYW5hZ2VyOiBTeW1ib2woJ01hdGVyaWFsQ29tcG9uZW50TWFuYWdlcicpLFxuICAvLyBSZW5kZXJQYXRoXG4gIEZvcndhcmRSZW5kZXJQYXRoOiBTeW1ib2woJ0ZvcndhcmRSZW5kZXJQYXRoJyksXG4gIC8vIENvbXB1dGVTeXN0ZW1cbiAgQ29tcHV0ZVN5c3RlbTogU3ltYm9sKCdDb21wdXRlU3lzdGVtJyksXG4gIENvbXB1dGVDb21wb25lbnRNYW5hZ2VyOiBTeW1ib2woJ0NvbXB1dGVDb21wb25lbnRNYW5hZ2VyJyksXG4gIENvbXB1dGVTdHJhdGVneTogU3ltYm9sKCdDb21wdXRlU3RyYXRlZ3knKSxcbiAgU3lzdGVtczogU3ltYm9sKCdTeXN0ZW1zJyksXG4gIFdvcmxkOiBTeW1ib2woJ1dvcmxkJyksXG4gIC8vIFJlbmRlckVuZ2luZVxuICBSZW5kZXJFbmdpbmU6IFN5bWJvbCgnUmVuZGVyRW5naW5lJyksXG4gIFdlYkdQVUVuZ2luZTogU3ltYm9sKCdXZWJHUFVFbmdpbmUnKSxcbiAgV2ViR0xFbmdpbmU6IFN5bWJvbCgnV2ViR0xFbmdpbmUnKSxcbiAgLy8gU2hhZGVyIE1vZHVsZVxuICBTaGFkZXJNb2R1bGVTZXJ2aWNlOiBTeW1ib2woJ1NoYWRlck1vZHVsZVNlcnZpY2UnKSxcbiAgQ29uZmlnU2VydmljZTogU3ltYm9sKCdDb25maWdTZXJ2aWNlJyksXG4gIEludGVyYWN0b3JTZXJ2aWNlOiBTeW1ib2woJ0ludGVyYWN0b3JTZXJ2aWNlJyksXG4gIElFdmVudEVtaXR0ZXI6IFN5bWJvbCgnSUV2ZW50RW1pdHRlcicpLFxuICAvLyBMaWdodFxuICBMaWdodDogU3ltYm9sKCdMaWdodCcpXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWRlbnRpZmllci5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///13\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, "mat3", function() { return /* reexport */ esm["a" /* mat3 */]; });\n__webpack_require__.d(__webpack_exports__, "vec2", function() { return /* reexport */ esm["d" /* vec2 */]; });\n__webpack_require__.d(__webpack_exports__, "vec3", function() { return /* reexport */ esm["e" /* vec3 */]; });\n__webpack_require__.d(__webpack_exports__, "ext", function() { return /* reexport */ ext_namespaceObject; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/matrix-util/esm/ext.js\nvar ext_namespaceObject = {};\n__webpack_require__.r(ext_namespaceObject);\n__webpack_require__.d(ext_namespaceObject, "leftTranslate", function() { return leftTranslate; });\n__webpack_require__.d(ext_namespaceObject, "leftRotate", function() { return leftRotate; });\n__webpack_require__.d(ext_namespaceObject, "leftScale", function() { return leftScale; });\n__webpack_require__.d(ext_namespaceObject, "transform", function() { return transform; });\n__webpack_require__.d(ext_namespaceObject, "direction", function() { return direction; });\n__webpack_require__.d(ext_namespaceObject, "angleTo", function() { return angleTo; });\n__webpack_require__.d(ext_namespaceObject, "vertical", function() { return vertical; });\n\n// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/index.js + 4 modules\nvar esm = __webpack_require__(2);\n\n// CONCATENATED MODULE: ./node_modules/@antv/matrix-util/esm/ext.js\n/**\n * @description 扩展方法,提供 gl-matrix 为提供的方法\n * */\n\nfunction leftTranslate(out, a, v) {\n var transMat = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n esm["a" /* mat3 */].fromTranslation(transMat, v);\n return esm["a" /* mat3 */].multiply(out, transMat, a);\n}\nfunction leftRotate(out, a, rad) {\n var rotateMat = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n esm["a" /* mat3 */].fromRotation(rotateMat, rad);\n return esm["a" /* mat3 */].multiply(out, rotateMat, a);\n}\nfunction leftScale(out, a, v) {\n var scaleMat = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n esm["a" /* mat3 */].fromScaling(scaleMat, v);\n return esm["a" /* mat3 */].multiply(out, scaleMat, a);\n}\nfunction leftMultiply(out, a, a1) {\n return esm["a" /* mat3 */].multiply(out, a1, a);\n}\n/**\n * 根据 actions 来做 transform\n * @param m\n * @param actions\n */\nfunction transform(m, actions) {\n var matrix = m ? [].concat(m) : [1, 0, 0, 0, 1, 0, 0, 0, 1];\n for (var i = 0, len = actions.length; i < len; i++) {\n var action = actions[i];\n switch (action[0]) {\n case \'t\':\n leftTranslate(matrix, matrix, [action[1], action[2]]);\n break;\n case \'s\':\n leftScale(matrix, matrix, [action[1], action[2]]);\n break;\n case \'r\':\n leftRotate(matrix, matrix, action[1]);\n break;\n case \'m\':\n leftMultiply(matrix, matrix, action[1]);\n break;\n default:\n break;\n }\n }\n return matrix;\n}\n/**\n * 向量 v1 到 向量 v2 夹角的方向\n * @param {Array} v1 向量\n * @param {Array} v2 向量\n * @return {Boolean} >= 0 顺时针 < 0 逆时针\n */\nfunction direction(v1, v2) {\n return v1[0] * v2[1] - v2[0] * v1[1];\n}\n/**\n * 二维向量 v1 到 v2 的夹角\n * @param v1\n * @param v2\n * @param direct\n */\nfunction angleTo(v1, v2, direct) {\n var ang = esm["d" /* vec2 */].angle(v1, v2);\n var angleLargeThanPI = direction(v1, v2) >= 0;\n if (direct) {\n if (angleLargeThanPI) {\n return Math.PI * 2 - ang;\n }\n return ang;\n }\n if (angleLargeThanPI) {\n return ang;\n }\n return Math.PI * 2 - ang;\n}\n/**\n * 计算二维向量的垂直向量\n * @param out\n * @param v\n * @param flag\n */\nfunction vertical(out, v, flag) {\n if (flag) {\n out[0] = v[1];\n out[1] = -1 * v[0];\n }\n else {\n out[0] = -1 * v[1];\n out[1] = v[0];\n }\n return out;\n}\n//# sourceMappingURL=ext.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/matrix-util/esm/index.js\n\n\n\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvbWF0cml4LXV0aWwvZXNtL2V4dC5qcz9iZmU2Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9tYXRyaXgtdXRpbC9lc20vaW5kZXguanM/ZTg5NyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDdUM7QUFDaEM7QUFDUDtBQUNBLElBQUksbUJBQUk7QUFDUixXQUFXLG1CQUFJO0FBQ2Y7QUFDTztBQUNQO0FBQ0EsSUFBSSxtQkFBSTtBQUNSLFdBQVcsbUJBQUk7QUFDZjtBQUNPO0FBQ1A7QUFDQSxJQUFJLG1CQUFJO0FBQ1IsV0FBVyxtQkFBSTtBQUNmO0FBQ0E7QUFDQSxXQUFXLG1CQUFJO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBLHlDQUF5QyxTQUFTO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxNQUFNO0FBQ2xCLFlBQVksTUFBTTtBQUNsQixZQUFZLFFBQVE7QUFDcEI7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQLGNBQWMsbUJBQUk7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCOztBQ2hHNkM7QUFDaEI7QUFDSTtBQUNqQyIsImZpbGUiOiIxNC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIOaJqeWxleaWueazle+8jOaPkOS+myBnbC1tYXRyaXgg5Li65o+Q5L6b55qE5pa55rOVXG4gKiAqL1xuaW1wb3J0IHsgbWF0MywgdmVjMiB9IGZyb20gJ2dsLW1hdHJpeCc7XG5leHBvcnQgZnVuY3Rpb24gbGVmdFRyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgICB2YXIgdHJhbnNNYXQgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgbWF0My5mcm9tVHJhbnNsYXRpb24odHJhbnNNYXQsIHYpO1xuICAgIHJldHVybiBtYXQzLm11bHRpcGx5KG91dCwgdHJhbnNNYXQsIGEpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGxlZnRSb3RhdGUob3V0LCBhLCByYWQpIHtcbiAgICB2YXIgcm90YXRlTWF0ID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgIG1hdDMuZnJvbVJvdGF0aW9uKHJvdGF0ZU1hdCwgcmFkKTtcbiAgICByZXR1cm4gbWF0My5tdWx0aXBseShvdXQsIHJvdGF0ZU1hdCwgYSk7XG59XG5leHBvcnQgZnVuY3Rpb24gbGVmdFNjYWxlKG91dCwgYSwgdikge1xuICAgIHZhciBzY2FsZU1hdCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgICBtYXQzLmZyb21TY2FsaW5nKHNjYWxlTWF0LCB2KTtcbiAgICByZXR1cm4gbWF0My5tdWx0aXBseShvdXQsIHNjYWxlTWF0LCBhKTtcbn1cbmZ1bmN0aW9uIGxlZnRNdWx0aXBseShvdXQsIGEsIGExKSB7XG4gICAgcmV0dXJuIG1hdDMubXVsdGlwbHkob3V0LCBhMSwgYSk7XG59XG4vKipcbiAqIOagueaNriBhY3Rpb25zIOadpeWBmiB0cmFuc2Zvcm1cbiAqIEBwYXJhbSBtXG4gKiBAcGFyYW0gYWN0aW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtKG0sIGFjdGlvbnMpIHtcbiAgICB2YXIgbWF0cml4ID0gbSA/IFtdLmNvbmNhdChtKSA6IFsxLCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAxXTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYWN0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgYWN0aW9uID0gYWN0aW9uc1tpXTtcbiAgICAgICAgc3dpdGNoIChhY3Rpb25bMF0pIHtcbiAgICAgICAgICAgIGNhc2UgJ3QnOlxuICAgICAgICAgICAgICAgIGxlZnRUcmFuc2xhdGUobWF0cml4LCBtYXRyaXgsIFthY3Rpb25bMV0sIGFjdGlvblsyXV0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncyc6XG4gICAgICAgICAgICAgICAgbGVmdFNjYWxlKG1hdHJpeCwgbWF0cml4LCBbYWN0aW9uWzFdLCBhY3Rpb25bMl1dKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3InOlxuICAgICAgICAgICAgICAgIGxlZnRSb3RhdGUobWF0cml4LCBtYXRyaXgsIGFjdGlvblsxXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtJzpcbiAgICAgICAgICAgICAgICBsZWZ0TXVsdGlwbHkobWF0cml4LCBtYXRyaXgsIGFjdGlvblsxXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXRyaXg7XG59XG4vKipcbiAqIOWQkemHjyB2MSDliLAg5ZCR6YePIHYyIOWkueinkueahOaWueWQkVxuICogQHBhcmFtICB7QXJyYXl9IHYxIOWQkemHj1xuICogQHBhcmFtICB7QXJyYXl9IHYyIOWQkemHj1xuICogQHJldHVybiB7Qm9vbGVhbn0gPj0gMCDpobrml7bpkoggPCAwIOmAhuaXtumSiFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlyZWN0aW9uKHYxLCB2Mikge1xuICAgIHJldHVybiB2MVswXSAqIHYyWzFdIC0gdjJbMF0gKiB2MVsxXTtcbn1cbi8qKlxuICog5LqM57u05ZCR6YePIHYxIOWIsCB2MiDnmoTlpLnop5JcbiAqIEBwYXJhbSB2MVxuICogQHBhcmFtIHYyXG4gKiBAcGFyYW0gZGlyZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmdsZVRvKHYxLCB2MiwgZGlyZWN0KSB7XG4gICAgdmFyIGFuZyA9IHZlYzIuYW5nbGUodjEsIHYyKTtcbiAgICB2YXIgYW5nbGVMYXJnZVRoYW5QSSA9IGRpcmVjdGlvbih2MSwgdjIpID49IDA7XG4gICAgaWYgKGRpcmVjdCkge1xuICAgICAgICBpZiAoYW5nbGVMYXJnZVRoYW5QSSkge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGguUEkgKiAyIC0gYW5nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhbmc7XG4gICAgfVxuICAgIGlmIChhbmdsZUxhcmdlVGhhblBJKSB7XG4gICAgICAgIHJldHVybiBhbmc7XG4gICAgfVxuICAgIHJldHVybiBNYXRoLlBJICogMiAtIGFuZztcbn1cbi8qKlxuICog6K6h566X5LqM57u05ZCR6YeP55qE5Z6C55u05ZCR6YePXG4gKiBAcGFyYW0gb3V0XG4gKiBAcGFyYW0gdlxuICogQHBhcmFtIGZsYWdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnRpY2FsKG91dCwgdiwgZmxhZykge1xuICAgIGlmIChmbGFnKSB7XG4gICAgICAgIG91dFswXSA9IHZbMV07XG4gICAgICAgIG91dFsxXSA9IC0xICogdlswXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG91dFswXSA9IC0xICogdlsxXTtcbiAgICAgICAgb3V0WzFdID0gdlswXTtcbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV4dC5qcy5tYXAiLCJpbXBvcnQgeyBtYXQzLCB2ZWMyLCB2ZWMzIH0gZnJvbSAnZ2wtbWF0cml4JztcbmltcG9ydCAqIGFzIGV4dCBmcm9tICcuL2V4dCc7XG5leHBvcnQgeyBtYXQzLCB2ZWMyLCB2ZWMzLCBleHQgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///14\n')},function(module,exports){eval('function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nfunction _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);\n }\n\n _next(undefined);\n });\n };\n}\n\nmodule.exports = _asyncToGenerator;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yLmpzP2M5NzMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiIxNS5qcyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIGFzeW5jR2VuZXJhdG9yU3RlcChnZW4sIHJlc29sdmUsIHJlamVjdCwgX25leHQsIF90aHJvdywga2V5LCBhcmcpIHtcbiAgdHJ5IHtcbiAgICB2YXIgaW5mbyA9IGdlbltrZXldKGFyZyk7XG4gICAgdmFyIHZhbHVlID0gaW5mby52YWx1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZWplY3QoZXJyb3IpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChpbmZvLmRvbmUpIHtcbiAgICByZXNvbHZlKHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICBQcm9taXNlLnJlc29sdmUodmFsdWUpLnRoZW4oX25leHQsIF90aHJvdyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX2FzeW5jVG9HZW5lcmF0b3IoZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBnZW4gPSBmbi5hcHBseShzZWxmLCBhcmdzKTtcblxuICAgICAgZnVuY3Rpb24gX25leHQodmFsdWUpIHtcbiAgICAgICAgYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBcIm5leHRcIiwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBfdGhyb3coZXJyKSB7XG4gICAgICAgIGFzeW5jR2VuZXJhdG9yU3RlcChnZW4sIHJlc29sdmUsIHJlamVjdCwgX25leHQsIF90aHJvdywgXCJ0aHJvd1wiLCBlcnIpO1xuICAgICAgfVxuXG4gICAgICBfbmV4dCh1bmRlZmluZWQpO1xuICAgIH0pO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hc3luY1RvR2VuZXJhdG9yO1xubW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHMsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///15\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return getPixelRatio; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return distance; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return inBox; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return intersectRect; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return mergeRegion; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return isSamePoint; });\n/* harmony import */ var _antv_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "i", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isNil"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "k", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isString"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "h", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isFunction"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "g", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isArray"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "c", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["each"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "o", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["toRadian"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "m", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["mod"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "n", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["requestAnimationFrame"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["clearAnimationFrame"]; });\n\nfunction getPixelRatio() {\n return window ? window.devicePixelRatio : 1;\n}\n/**\n * 两点之间的距离\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n */\nfunction distance(x1, y1, x2, y2) {\n var dx = x1 - x2;\n var dy = y1 - y2;\n return Math.sqrt(dx * dx + dy * dy);\n}\n/**\n * 是否在包围盒内\n * @param {number} minX 包围盒开始的点 x\n * @param {number} minY 包围盒开始的点 y\n * @param {number} width 宽度\n * @param {number} height 高度\n * @param {[type]} x 检测点的 x\n * @param {[type]} y 监测点的 y\n */\nfunction inBox(minX, minY, width, height, x, y) {\n return x >= minX && x <= minX + width && y >= minY && y <= minY + height;\n}\nfunction intersectRect(box1, box2) {\n return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY);\n}\n// 合并两个区域\nfunction mergeRegion(region1, region2) {\n if (!region1 || !region2) {\n return region1 || region2;\n }\n return {\n minX: Math.min(region1.minX, region2.minX),\n minY: Math.min(region1.minY, region2.minY),\n maxX: Math.max(region1.maxX, region2.maxX),\n maxY: Math.max(region1.maxY, region2.maxY),\n };\n}\n/**\n * 判断两个点是否重合,点坐标的格式为 [x, y]\n * @param {Array} point1 第一个点\n * @param {Array} point2 第二个点\n */\nfunction isSamePoint(point1, point2) {\n return point1[0] === point2[0] && point1[1] === point2[1];\n}\n\n//# sourceMappingURL=util.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvZXNtL3V0aWwvdXRpbC5qcz83MzI2Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQjtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEI7QUFDTztBQUNQO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFdBQVcsTUFBTTtBQUNqQjtBQUNPO0FBQ1A7QUFDQTtBQUNtSjtBQUNuSiIsImZpbGUiOiIxNi5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBnZXRQaXhlbFJhdGlvKCkge1xuICAgIHJldHVybiB3aW5kb3cgPyB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyA6IDE7XG59XG4vKipcbiAqIOS4pOeCueS5i+mXtOeahOi3neemu1xuICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXN0YW5jZSh4MSwgeTEsIHgyLCB5Mikge1xuICAgIHZhciBkeCA9IHgxIC0geDI7XG4gICAgdmFyIGR5ID0geTEgLSB5MjtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbn1cbi8qKlxuICog5piv5ZCm5Zyo5YyF5Zu055uS5YaFXG4gKiBAcGFyYW0ge251bWJlcn0gbWluWCAgIOWMheWbtOebkuW8gOWni+eahOeCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0gbWluWSAgIOWMheWbtOebkuW8gOWni+eahOeCuSB5XG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggIOWuveW6plxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCDpq5jluqZcbiAqIEBwYXJhbSB7W3R5cGVdfSB4ICAgICAg5qOA5rWL54K555qEIHhcbiAqIEBwYXJhbSB7W3R5cGVdfSB5ICAgICAg55uR5rWL54K555qEIHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluQm94KG1pblgsIG1pblksIHdpZHRoLCBoZWlnaHQsIHgsIHkpIHtcbiAgICByZXR1cm4geCA+PSBtaW5YICYmIHggPD0gbWluWCArIHdpZHRoICYmIHkgPj0gbWluWSAmJiB5IDw9IG1pblkgKyBoZWlnaHQ7XG59XG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0UmVjdChib3gxLCBib3gyKSB7XG4gICAgcmV0dXJuICEoYm94Mi5taW5YID4gYm94MS5tYXhYIHx8IGJveDIubWF4WCA8IGJveDEubWluWCB8fCBib3gyLm1pblkgPiBib3gxLm1heFkgfHwgYm94Mi5tYXhZIDwgYm94MS5taW5ZKTtcbn1cbi8vIOWQiOW5tuS4pOS4quWMuuWfn1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlUmVnaW9uKHJlZ2lvbjEsIHJlZ2lvbjIpIHtcbiAgICBpZiAoIXJlZ2lvbjEgfHwgIXJlZ2lvbjIpIHtcbiAgICAgICAgcmV0dXJuIHJlZ2lvbjEgfHwgcmVnaW9uMjtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluWDogTWF0aC5taW4ocmVnaW9uMS5taW5YLCByZWdpb24yLm1pblgpLFxuICAgICAgICBtaW5ZOiBNYXRoLm1pbihyZWdpb24xLm1pblksIHJlZ2lvbjIubWluWSksXG4gICAgICAgIG1heFg6IE1hdGgubWF4KHJlZ2lvbjEubWF4WCwgcmVnaW9uMi5tYXhYKSxcbiAgICAgICAgbWF4WTogTWF0aC5tYXgocmVnaW9uMS5tYXhZLCByZWdpb24yLm1heFkpLFxuICAgIH07XG59XG4vKipcbiAqIOWIpOaWreS4pOS4queCueaYr+WQpumHjeWQiO+8jOeCueWdkOagh+eahOagvOW8j+S4uiBbeCwgeV1cbiAqIEBwYXJhbSB7QXJyYXl9IHBvaW50MSDnrKzkuIDkuKrngrlcbiAqIEBwYXJhbSB7QXJyYXl9IHBvaW50MiDnrKzkuozkuKrngrlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2FtZVBvaW50KHBvaW50MSwgcG9pbnQyKSB7XG4gICAgcmV0dXJuIHBvaW50MVswXSA9PT0gcG9pbnQyWzBdICYmIHBvaW50MVsxXSA9PT0gcG9pbnQyWzFdO1xufVxuZXhwb3J0IHsgaXNOaWwsIGlzU3RyaW5nLCBpc0Z1bmN0aW9uLCBpc0FycmF5LCBlYWNoLCB0b1JhZGlhbiwgbW9kLCBpc051bWJlckVxdWFsLCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUsIGNsZWFyQW5pbWF0aW9uRnJhbWUsIH0gZnJvbSAnQGFudHYvdXRpbCc7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11dGlsLmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///16\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return SHAPE_TO_TAGS; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return SVG_ATTR_MAP; });\n/* unused harmony export EVENTS */\nvar SHAPE_TO_TAGS = {\n rect: 'path',\n circle: 'circle',\n line: 'line',\n path: 'path',\n marker: 'path',\n text: 'text',\n polyline: 'polyline',\n polygon: 'polygon',\n image: 'image',\n ellipse: 'ellipse',\n dom: 'foreignObject',\n};\nvar SVG_ATTR_MAP = {\n opacity: 'opacity',\n fillStyle: 'fill',\n fill: 'fill',\n fillOpacity: 'fill-opacity',\n strokeStyle: 'stroke',\n strokeOpacity: 'stroke-opacity',\n stroke: 'stroke',\n x: 'x',\n y: 'y',\n r: 'r',\n rx: 'rx',\n ry: 'ry',\n width: 'width',\n height: 'height',\n x1: 'x1',\n x2: 'x2',\n y1: 'y1',\n y2: 'y2',\n lineCap: 'stroke-linecap',\n lineJoin: 'stroke-linejoin',\n lineWidth: 'stroke-width',\n lineDash: 'stroke-dasharray',\n lineDashOffset: 'stroke-dashoffset',\n miterLimit: 'stroke-miterlimit',\n font: 'font',\n fontSize: 'font-size',\n fontStyle: 'font-style',\n fontVariant: 'font-variant',\n fontWeight: 'font-weight',\n fontFamily: 'font-family',\n startArrow: 'marker-start',\n endArrow: 'marker-end',\n path: 'd',\n class: 'class',\n id: 'id',\n style: 'style',\n preserveAspectRatio: 'preserveAspectRatio',\n};\nvar EVENTS = [\n 'click',\n 'mousedown',\n 'mouseup',\n 'dblclick',\n 'contextmenu',\n 'mouseenter',\n 'mouseleave',\n 'mouseover',\n 'mouseout',\n 'mousemove',\n 'wheel',\n];\n//# sourceMappingURL=constant.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvZXNtL2NvbnN0YW50LmpzPzIyZjkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjE3LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHZhciBTSEFQRV9UT19UQUdTID0ge1xuICAgIHJlY3Q6ICdwYXRoJyxcbiAgICBjaXJjbGU6ICdjaXJjbGUnLFxuICAgIGxpbmU6ICdsaW5lJyxcbiAgICBwYXRoOiAncGF0aCcsXG4gICAgbWFya2VyOiAncGF0aCcsXG4gICAgdGV4dDogJ3RleHQnLFxuICAgIHBvbHlsaW5lOiAncG9seWxpbmUnLFxuICAgIHBvbHlnb246ICdwb2x5Z29uJyxcbiAgICBpbWFnZTogJ2ltYWdlJyxcbiAgICBlbGxpcHNlOiAnZWxsaXBzZScsXG4gICAgZG9tOiAnZm9yZWlnbk9iamVjdCcsXG59O1xuZXhwb3J0IHZhciBTVkdfQVRUUl9NQVAgPSB7XG4gICAgb3BhY2l0eTogJ29wYWNpdHknLFxuICAgIGZpbGxTdHlsZTogJ2ZpbGwnLFxuICAgIGZpbGw6ICdmaWxsJyxcbiAgICBmaWxsT3BhY2l0eTogJ2ZpbGwtb3BhY2l0eScsXG4gICAgc3Ryb2tlU3R5bGU6ICdzdHJva2UnLFxuICAgIHN0cm9rZU9wYWNpdHk6ICdzdHJva2Utb3BhY2l0eScsXG4gICAgc3Ryb2tlOiAnc3Ryb2tlJyxcbiAgICB4OiAneCcsXG4gICAgeTogJ3knLFxuICAgIHI6ICdyJyxcbiAgICByeDogJ3J4JyxcbiAgICByeTogJ3J5JyxcbiAgICB3aWR0aDogJ3dpZHRoJyxcbiAgICBoZWlnaHQ6ICdoZWlnaHQnLFxuICAgIHgxOiAneDEnLFxuICAgIHgyOiAneDInLFxuICAgIHkxOiAneTEnLFxuICAgIHkyOiAneTInLFxuICAgIGxpbmVDYXA6ICdzdHJva2UtbGluZWNhcCcsXG4gICAgbGluZUpvaW46ICdzdHJva2UtbGluZWpvaW4nLFxuICAgIGxpbmVXaWR0aDogJ3N0cm9rZS13aWR0aCcsXG4gICAgbGluZURhc2g6ICdzdHJva2UtZGFzaGFycmF5JyxcbiAgICBsaW5lRGFzaE9mZnNldDogJ3N0cm9rZS1kYXNob2Zmc2V0JyxcbiAgICBtaXRlckxpbWl0OiAnc3Ryb2tlLW1pdGVybGltaXQnLFxuICAgIGZvbnQ6ICdmb250JyxcbiAgICBmb250U2l6ZTogJ2ZvbnQtc2l6ZScsXG4gICAgZm9udFN0eWxlOiAnZm9udC1zdHlsZScsXG4gICAgZm9udFZhcmlhbnQ6ICdmb250LXZhcmlhbnQnLFxuICAgIGZvbnRXZWlnaHQ6ICdmb250LXdlaWdodCcsXG4gICAgZm9udEZhbWlseTogJ2ZvbnQtZmFtaWx5JyxcbiAgICBzdGFydEFycm93OiAnbWFya2VyLXN0YXJ0JyxcbiAgICBlbmRBcnJvdzogJ21hcmtlci1lbmQnLFxuICAgIHBhdGg6ICdkJyxcbiAgICBjbGFzczogJ2NsYXNzJyxcbiAgICBpZDogJ2lkJyxcbiAgICBzdHlsZTogJ3N0eWxlJyxcbiAgICBwcmVzZXJ2ZUFzcGVjdFJhdGlvOiAncHJlc2VydmVBc3BlY3RSYXRpbycsXG59O1xuZXhwb3J0IHZhciBFVkVOVFMgPSBbXG4gICAgJ2NsaWNrJyxcbiAgICAnbW91c2Vkb3duJyxcbiAgICAnbW91c2V1cCcsXG4gICAgJ2RibGNsaWNrJyxcbiAgICAnY29udGV4dG1lbnUnLFxuICAgICdtb3VzZWVudGVyJyxcbiAgICAnbW91c2VsZWF2ZScsXG4gICAgJ21vdXNlb3ZlcicsXG4gICAgJ21vdXNlb3V0JyxcbiAgICAnbW91c2Vtb3ZlJyxcbiAgICAnd2hlZWwnLFxuXTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///17\n")},function(module,exports){eval('function _getPrototypeOf(o) {\n module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n module.exports["default"] = module.exports, module.exports.__esModule = true;\n return _getPrototypeOf(o);\n}\n\nmodule.exports = _getPrototypeOf;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9nZXRQcm90b3R5cGVPZi5qcz8zNmM2Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EiLCJmaWxlIjoiMTguanMiLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICBtb2R1bGUuZXhwb3J0cyA9IF9nZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5nZXRQcm90b3R5cGVPZiA6IGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7XG4gICAgcmV0dXJuIG8uX19wcm90b19fIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihvKTtcbiAgfTtcbiAgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHMsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuICByZXR1cm4gX2dldFByb3RvdHlwZU9mKG8pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9nZXRQcm90b3R5cGVPZjtcbm1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///18\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return removeFromArray; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return isBrowser; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return isParent; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return isAllowCapture; });\n/* harmony import */ var _antv_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "e", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isNil"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "d", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isFunction"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "h", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isString"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "f", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["isObject"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "i", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["mix"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["each"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "k", function() { return _antv_util__WEBPACK_IMPORTED_MODULE_0__["upperFirst"]; });\n\nfunction removeFromArray(arr, obj) {\n var index = arr.indexOf(obj);\n if (index !== -1) {\n arr.splice(index, 1);\n }\n}\nvar isBrowser = typeof window !== \'undefined\' && typeof window.document !== \'undefined\';\n\n// 是否元素的父容器\nfunction isParent(container, shape) {\n // 所有 shape 都是 canvas 的子元素\n if (container.isCanvas()) {\n return true;\n }\n var parent = shape.getParent();\n var isParent = false;\n while (parent) {\n if (parent === container) {\n isParent = true;\n break;\n }\n parent = parent.getParent();\n }\n return isParent;\n}\nfunction isAllowCapture(element) {\n // @ts-ignore\n return element.cfg.visible && element.cfg.capture;\n}\n//# sourceMappingURL=util.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2VzbS91dGlsL3V0aWwuanM/YjJjYiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQzRGO0FBQ25HO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjE5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZyb21BcnJheShhcnIsIG9iaikge1xuICAgIHZhciBpbmRleCA9IGFyci5pbmRleE9mKG9iaik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICBhcnIuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG59XG5leHBvcnQgdmFyIGlzQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnO1xuZXhwb3J0IHsgaXNOaWwsIGlzRnVuY3Rpb24sIGlzU3RyaW5nLCBpc09iamVjdCwgaXNBcnJheSwgbWl4LCBlYWNoLCB1cHBlckZpcnN0IH0gZnJvbSAnQGFudHYvdXRpbCc7XG4vLyDmmK/lkKblhYPntKDnmoTniLblrrnlmahcbmV4cG9ydCBmdW5jdGlvbiBpc1BhcmVudChjb250YWluZXIsIHNoYXBlKSB7XG4gICAgLy8g5omA5pyJIHNoYXBlIOmDveaYryBjYW52YXMg55qE5a2Q5YWD57SgXG4gICAgaWYgKGNvbnRhaW5lci5pc0NhbnZhcygpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB2YXIgcGFyZW50ID0gc2hhcGUuZ2V0UGFyZW50KCk7XG4gICAgdmFyIGlzUGFyZW50ID0gZmFsc2U7XG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgICBpZiAocGFyZW50ID09PSBjb250YWluZXIpIHtcbiAgICAgICAgICAgIGlzUGFyZW50ID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHBhcmVudCA9IHBhcmVudC5nZXRQYXJlbnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIGlzUGFyZW50O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzQWxsb3dDYXB0dXJlKGVsZW1lbnQpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIGVsZW1lbnQuY2ZnLnZpc2libGUgJiYgZWxlbWVudC5jZmcuY2FwdHVyZTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///19\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, "e", function() { return /* reexport */ quadratic; });\n__webpack_require__.d(__webpack_exports__, "b", function() { return /* reexport */ cubic; });\n__webpack_require__.d(__webpack_exports__, "a", function() { return /* reexport */ arc; });\n__webpack_require__.d(__webpack_exports__, "c", function() { return /* reexport */ line; });\n__webpack_require__.d(__webpack_exports__, "d", function() { return /* reexport */ polyline; });\n__webpack_require__.d(__webpack_exports__, "f", function() { return /* reexport */ util_namespaceObject; });\n\n// UNUSED EXPORTS: Polygon\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g-math/esm/util.js\nvar util_namespaceObject = {};\n__webpack_require__.r(util_namespaceObject);\n__webpack_require__.d(util_namespaceObject, "distance", function() { return distance; });\n__webpack_require__.d(util_namespaceObject, "isNumberEqual", function() { return isNumberEqual; });\n__webpack_require__.d(util_namespaceObject, "getBBoxByArray", function() { return getBBoxByArray; });\n__webpack_require__.d(util_namespaceObject, "getBBoxRange", function() { return getBBoxRange; });\n__webpack_require__.d(util_namespaceObject, "piMod", function() { return piMod; });\n\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/util.js\nfunction minNum(array) {\n return Math.min.apply(null, array);\n}\nfunction maxNum(array) {\n return Math.max.apply(null, array);\n}\n/**\n * 两点之间的距离\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @return {number} 距离\n */\nfunction distance(x1, y1, x2, y2) {\n var dx = x1 - x2;\n var dy = y1 - y2;\n return Math.sqrt(dx * dx + dy * dy);\n}\nfunction isNumberEqual(v1, v2) {\n return Math.abs(v1 - v2) < 0.001;\n}\nfunction getBBoxByArray(xArr, yArr) {\n var minX = minNum(xArr);\n var minY = minNum(yArr);\n var maxX = maxNum(xArr);\n var maxY = maxNum(yArr);\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\nfunction getBBoxRange(x1, y1, x2, y2) {\n return {\n minX: minNum([x1, x2]),\n maxX: maxNum([x1, x2]),\n minY: minNum([y1, y2]),\n maxY: maxNum([y1, y2]),\n };\n}\nfunction piMod(angle) {\n return (angle + Math.PI * 2) % (Math.PI * 2);\n}\n//# sourceMappingURL=util.js.map\n// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/vec2.js\nvar vec2 = __webpack_require__(81);\n\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/line.js\n\n\n/* harmony default export */ var line = ({\n /**\n * 计算线段的包围盒\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @return {object} 包围盒对象\n */\n box: function (x1, y1, x2, y2) {\n return getBBoxByArray([x1, x2], [y1, y2]);\n },\n /**\n * 线段的长度\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @return {number} 距离\n */\n length: function (x1, y1, x2, y2) {\n return distance(x1, y1, x2, y2);\n },\n /**\n * 根据比例获取点\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @param {number} t 指定比例\n * @return {object} 包含 x, y 的点\n */\n pointAt: function (x1, y1, x2, y2, t) {\n return {\n x: (1 - t) * x1 + t * x2,\n y: (1 - t) * y1 + t * y2,\n };\n },\n /**\n * 点到线段的距离\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @param {number} x 测试点 x\n * @param {number} y 测试点 y\n * @return {number} 距离\n */\n pointDistance: function (x1, y1, x2, y2, x, y) {\n // 投影距离 x1, y1 的向量,假设 p, p1, p2 三个点,投影点为 a\n // p1a = p1p.p1p2/|p1p2| * (p1p 的单位向量)\n var cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);\n if (cross < 0) {\n return distance(x1, y1, x, y);\n }\n var lengthSquare = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);\n if (cross > lengthSquare) {\n return distance(x2, y2, x, y);\n }\n return this.pointToLine(x1, y1, x2, y2, x, y);\n },\n /**\n * 点到直线的距离,而不是点到线段的距离\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @param {number} x 测试点 x\n * @param {number} y 测试点 y\n * @return {number} 距离\n */\n pointToLine: function (x1, y1, x2, y2, x, y) {\n var d = [x2 - x1, y2 - y1];\n // 如果端点相等,则判定点到点的距离\n if (vec2["exactEquals"](d, [0, 0])) {\n return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));\n }\n var u = [-d[1], d[0]];\n vec2["normalize"](u, u);\n var a = [x - x1, y - y1];\n return Math.abs(vec2["dot"](a, u));\n },\n /**\n * 线段的角度\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 结束点 x\n * @param {number} y2 结束点 y\n * @return {number} 导数\n */\n tangentAngle: function (x1, y1, x2, y2) {\n return Math.atan2(y2 - y1, x2 - x1);\n },\n});\n//# sourceMappingURL=line.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/bezier.js\n\nvar EPSILON = 0.0001;\n/**\n * 使用牛顿切割法求最近的点\n * @param {number[]} xArr 点的 x 数组\n * @param {number[]} yArr 点的 y 数组\n * @param {number} x 指定的点 x\n * @param {number} y 指定的点 y\n * @param {Function} tCallback 差值函数\n */\nfunction bezier_nearestPoint(xArr, yArr, x, y, tCallback, length) {\n var t;\n var d = Infinity;\n var v0 = [x, y];\n var segNum = 20;\n if (length && length > 200) {\n segNum = length / 10;\n }\n var increaseRate = 1 / segNum;\n var interval = increaseRate / 10;\n for (var i = 0; i <= segNum; i++) {\n var _t = i * increaseRate;\n var v1 = [tCallback.apply(null, xArr.concat([_t])), tCallback.apply(null, yArr.concat([_t]))];\n var d1 = distance(v0[0], v0[1], v1[0], v1[1]);\n if (d1 < d) {\n t = _t;\n d = d1;\n }\n }\n // 提前终止\n if (t === 0) {\n return {\n x: xArr[0],\n y: yArr[0],\n };\n }\n if (t === 1) {\n var count = xArr.length;\n return {\n x: xArr[count - 1],\n y: yArr[count - 1],\n };\n }\n d = Infinity;\n for (var i = 0; i < 32; i++) {\n if (interval < EPSILON) {\n break;\n }\n var prev = t - interval;\n var next = t + interval;\n var v1 = [tCallback.apply(null, xArr.concat([prev])), tCallback.apply(null, yArr.concat([prev]))];\n var d1 = distance(v0[0], v0[1], v1[0], v1[1]);\n if (prev >= 0 && d1 < d) {\n t = prev;\n d = d1;\n }\n else {\n var v2 = [tCallback.apply(null, xArr.concat([next])), tCallback.apply(null, yArr.concat([next]))];\n var d2 = distance(v0[0], v0[1], v2[0], v2[1]);\n if (next <= 1 && d2 < d) {\n t = next;\n d = d2;\n }\n else {\n interval *= 0.5;\n }\n }\n }\n return {\n x: tCallback.apply(null, xArr.concat([t])),\n y: tCallback.apply(null, yArr.concat([t])),\n };\n}\n// 近似求解 https://community.khronos.org/t/3d-cubic-bezier-segment-length/62363/2\nfunction snapLength(xArr, yArr) {\n var totalLength = 0;\n var count = xArr.length;\n for (var i = 0; i < count; i++) {\n var x = xArr[i];\n var y = yArr[i];\n var nextX = xArr[(i + 1) % count];\n var nextY = yArr[(i + 1) % count];\n totalLength += distance(x, y, nextX, nextY);\n }\n return totalLength / 2;\n}\n//# sourceMappingURL=bezier.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/quadratic.js\n\n\n\n// 差值公式\nfunction quadraticAt(p0, p1, p2, t) {\n var onet = 1 - t;\n return onet * onet * p0 + 2 * t * onet * p1 + t * t * p2;\n}\n// 求极值\nfunction extrema(p0, p1, p2) {\n var a = p0 + p2 - 2 * p1;\n if (isNumberEqual(a, 0)) {\n return [0.5];\n }\n var rst = (p0 - p1) / a;\n if (rst <= 1 && rst >= 0) {\n return [rst];\n }\n return [];\n}\nfunction derivativeAt(p0, p1, p2, t) {\n return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1);\n}\n// 分割贝塞尔曲线\nfunction divideQuadratic(x1, y1, x2, y2, x3, y3, t) {\n // 划分点\n var xt = quadraticAt(x1, x2, x3, t);\n var yt = quadraticAt(y1, y2, y3, t);\n // 分割的第一条曲线的控制点\n var controlPoint1 = line.pointAt(x1, y1, x2, y2, t);\n // 分割的第二条曲线的控制点\n var controlPoint2 = line.pointAt(x2, y2, x3, y3, t);\n return [\n [x1, y1, controlPoint1.x, controlPoint1.y, xt, yt],\n [xt, yt, controlPoint2.x, controlPoint2.y, x3, y3],\n ];\n}\n// 使用迭代法取贝塞尔曲线的长度\nfunction quadraticLength(x1, y1, x2, y2, x3, y3, iterationCount) {\n if (iterationCount === 0) {\n return (distance(x1, y1, x2, y2) + distance(x2, y2, x3, y3) + distance(x1, y1, x3, y3)) / 2;\n }\n var quadratics = divideQuadratic(x1, y1, x2, y2, x3, y3, 0.5);\n var left = quadratics[0];\n var right = quadratics[1];\n left.push(iterationCount - 1);\n right.push(iterationCount - 1);\n return quadraticLength.apply(null, left) + quadraticLength.apply(null, right);\n}\n/* harmony default export */ var quadratic = ({\n box: function (x1, y1, x2, y2, x3, y3) {\n var xExtrema = extrema(x1, x2, x3)[0];\n var yExtrema = extrema(y1, y2, y3)[0];\n // 控制点不加入 box 的计算\n var xArr = [x1, x3];\n var yArr = [y1, y3];\n if (xExtrema !== undefined) {\n xArr.push(quadraticAt(x1, x2, x3, xExtrema));\n }\n if (yExtrema !== undefined) {\n yArr.push(quadraticAt(y1, y2, y3, yExtrema));\n }\n return getBBoxByArray(xArr, yArr);\n },\n length: function (x1, y1, x2, y2, x3, y3) {\n return quadraticLength(x1, y1, x2, y2, x3, y3, 3);\n },\n nearestPoint: function (x1, y1, x2, y2, x3, y3, x0, y0) {\n return bezier_nearestPoint([x1, x2, x3], [y1, y2, y3], x0, y0, quadraticAt);\n },\n pointDistance: function (x1, y1, x2, y2, x3, y3, x0, y0) {\n var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x0, y0);\n return distance(point.x, point.y, x0, y0);\n },\n interpolationAt: quadraticAt,\n pointAt: function (x1, y1, x2, y2, x3, y3, t) {\n return {\n x: quadraticAt(x1, x2, x3, t),\n y: quadraticAt(y1, y2, y3, t),\n };\n },\n divide: function (x1, y1, x2, y2, x3, y3, t) {\n return divideQuadratic(x1, y1, x2, y2, x3, y3, t);\n },\n tangentAngle: function (x1, y1, x2, y2, x3, y3, t) {\n var dx = derivativeAt(x1, x2, x3, t);\n var dy = derivativeAt(y1, y2, y3, t);\n var angle = Math.atan2(dy, dx);\n return piMod(angle);\n },\n});\n//# sourceMappingURL=quadratic.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/cubic.js\n\n\n\nfunction cubicAt(p0, p1, p2, p3, t) {\n var onet = 1 - t; // t * t * t 的性能大概是 Math.pow(t, 3) 的三倍\n return onet * onet * onet * p0 + 3 * p1 * t * onet * onet + 3 * p2 * t * t * onet + p3 * t * t * t;\n}\nfunction cubic_derivativeAt(p0, p1, p2, p3, t) {\n var onet = 1 - t;\n return 3 * (onet * onet * (p1 - p0) + 2 * onet * t * (p2 - p1) + t * t * (p3 - p2));\n}\nfunction cubic_extrema(p0, p1, p2, p3) {\n var a = -3 * p0 + 9 * p1 - 9 * p2 + 3 * p3;\n var b = 6 * p0 - 12 * p1 + 6 * p2;\n var c = 3 * p1 - 3 * p0;\n var extremas = [];\n var t1;\n var t2;\n var discSqrt;\n if (isNumberEqual(a, 0)) {\n if (!isNumberEqual(b, 0)) {\n t1 = -c / b;\n if (t1 >= 0 && t1 <= 1) {\n extremas.push(t1);\n }\n }\n }\n else {\n var disc = b * b - 4 * a * c;\n if (isNumberEqual(disc, 0)) {\n extremas.push(-b / (2 * a));\n }\n else if (disc > 0) {\n discSqrt = Math.sqrt(disc);\n t1 = (-b + discSqrt) / (2 * a);\n t2 = (-b - discSqrt) / (2 * a);\n if (t1 >= 0 && t1 <= 1) {\n extremas.push(t1);\n }\n if (t2 >= 0 && t2 <= 1) {\n extremas.push(t2);\n }\n }\n }\n return extremas;\n}\n// 分割贝塞尔曲线\nfunction divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, t) {\n // 划分点\n var xt = cubicAt(x1, x2, x3, x4, t);\n var yt = cubicAt(y1, y2, y3, y4, t);\n // 计算两点之间的差值点\n var c1 = line.pointAt(x1, y1, x2, y2, t);\n var c2 = line.pointAt(x2, y2, x3, y3, t);\n var c3 = line.pointAt(x3, y3, x4, y4, t);\n var c12 = line.pointAt(c1.x, c1.y, c2.x, c2.y, t);\n var c23 = line.pointAt(c2.x, c2.y, c3.x, c3.y, t);\n return [\n [x1, y1, c1.x, c1.y, c12.x, c12.y, xt, yt],\n [xt, yt, c23.x, c23.y, c3.x, c3.y, x4, y4],\n ];\n}\n// 使用迭代法取贝塞尔曲线的长度,二阶和三阶分开写,更清晰和便于调试\nfunction cubicLength(x1, y1, x2, y2, x3, y3, x4, y4, iterationCount) {\n if (iterationCount === 0) {\n return snapLength([x1, x2, x3, x4], [y1, y2, y3, y4]);\n }\n var cubics = divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0.5);\n var left = cubics[0];\n var right = cubics[1];\n left.push(iterationCount - 1);\n right.push(iterationCount - 1);\n return cubicLength.apply(null, left) + cubicLength.apply(null, right);\n}\n/* harmony default export */ var cubic = ({\n extrema: cubic_extrema,\n box: function (x1, y1, x2, y2, x3, y3, x4, y4) {\n var xArr = [x1, x4];\n var yArr = [y1, y4];\n var xExtrema = cubic_extrema(x1, x2, x3, x4);\n var yExtrema = cubic_extrema(y1, y2, y3, y4);\n for (var i = 0; i < xExtrema.length; i++) {\n xArr.push(cubicAt(x1, x2, x3, x4, xExtrema[i]));\n }\n for (var i = 0; i < yExtrema.length; i++) {\n yArr.push(cubicAt(y1, y2, y3, y4, yExtrema[i]));\n }\n return getBBoxByArray(xArr, yArr);\n },\n length: function (x1, y1, x2, y2, x3, y3, x4, y4) {\n // 迭代三次,划分成 8 段求长度\n return cubicLength(x1, y1, x2, y2, x3, y3, x4, y4, 3);\n },\n nearestPoint: function (x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) {\n return bezier_nearestPoint([x1, x2, x3, x4], [y1, y2, y3, y4], x0, y0, cubicAt, length);\n },\n pointDistance: function (x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) {\n var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length);\n return distance(point.x, point.y, x0, y0);\n },\n interpolationAt: cubicAt,\n pointAt: function (x1, y1, x2, y2, x3, y3, x4, y4, t) {\n return {\n x: cubicAt(x1, x2, x3, x4, t),\n y: cubicAt(y1, y2, y3, y4, t),\n };\n },\n divide: function (x1, y1, x2, y2, x3, y3, x4, y4, t) {\n return divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, t);\n },\n tangentAngle: function (x1, y1, x2, y2, x3, y3, x4, y4, t) {\n var dx = cubic_derivativeAt(x1, x2, x3, x4, t);\n var dy = cubic_derivativeAt(y1, y2, y3, y4, t);\n return piMod(Math.atan2(dy, dx));\n },\n});\n//# sourceMappingURL=cubic.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/ellipse.js\n/**\n * @fileoverview 椭圆的一些计算,\n * - 周长计算参考:https://www.mathsisfun.com/geometry/ellipse-perimeter.html\n * - 距离计算参考:https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/\n * @author dxq613@gmail.com\n */\n\nfunction copysign(v1, v2) {\n var absv = Math.abs(v1);\n return v2 > 0 ? absv : absv * -1;\n}\n/* harmony default export */ var ellipse = ({\n /**\n * 包围盒计算\n * @param {number} x 椭圆中心 x\n * @param {number} y 椭圆中心 y\n * @param {number} rx 椭圆 x 方向半径\n * @param {number} ry 椭圆 y 方向半径\n * @return {object} 包围盒\n */\n box: function (x, y, rx, ry) {\n return {\n x: x - rx,\n y: y - ry,\n width: rx * 2,\n height: ry * 2,\n };\n },\n /**\n * 计算周长,使用近似法\n * @param {number} x 椭圆中心 x\n * @param {number} y 椭圆中心 y\n * @param {number} rx 椭圆 x 方向半径\n * @param {number} ry 椭圆 y 方向半径\n * @return {number} 椭圆周长\n */\n length: function (x, y, rx, ry) {\n return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));\n },\n /**\n * 距离椭圆最近的点\n * @param {number} x 椭圆中心 x\n * @param {number} y 椭圆中心 y\n * @param {number} rx 椭圆 x 方向半径\n * @param {number} ry 椭圆 y 方向半径\n * @param {number} x0 指定的点 x\n * @param {number} y0 指定的点 y\n * @return {object} 椭圆上距离指定点最近的点\n */\n nearestPoint: function (x, y, rx, ry, x0, y0) {\n var a = rx;\n var b = ry;\n // 假如椭圆半径为0则返回圆心\n if (a === 0 || b === 0) {\n return {\n x: x,\n y: y,\n };\n }\n // 转换成 0, 0 为中心的椭圆计算\n var relativeX = x0 - x;\n var relativeY = y0 - y;\n var px = Math.abs(relativeX);\n var py = Math.abs(relativeY);\n var squareA = a * a;\n var squareB = b * b;\n // const angle0 = Math.atan2(relativeY, relativeX);\n var t = Math.PI / 4;\n var nearestX; // 椭圆上的任一点\n var nearestY;\n // 迭代 4 次\n for (var i = 0; i < 4; i++) {\n nearestX = a * Math.cos(t);\n nearestY = b * Math.sin(t);\n var ex = ((squareA - squareB) * Math.pow(Math.cos(t), 3)) / a;\n var ey = ((squareB - squareA) * Math.pow(Math.sin(t), 3)) / b;\n var rx1 = nearestX - ex;\n var ry1 = nearestY - ey;\n var qx = px - ex;\n var qy = py - ey;\n var r = Math.hypot(ry1, rx1);\n var q = Math.hypot(qy, qx);\n var delta_c = r * Math.asin((rx1 * qy - ry1 * qx) / (r * q));\n var delta_t = delta_c / Math.sqrt(squareA + squareB - nearestX * nearestX - nearestY * nearestY);\n t += delta_t;\n t = Math.min(Math.PI / 2, Math.max(0, t));\n }\n return {\n x: x + copysign(nearestX, relativeX),\n y: y + copysign(nearestY, relativeY),\n };\n },\n /**\n * 点到椭圆最近的距离\n * @param {number} x 椭圆中心 x\n * @param {number} y 椭圆中心 y\n * @param {number} rx 椭圆 x 方向半径\n * @param {number} ry 椭圆 y 方向半径\n * @param {number} x0 指定的点 x\n * @param {number} y0 指定的点 y\n * @return {number} 点到椭圆的距离\n */\n pointDistance: function (x, y, rx, ry, x0, y0) {\n var nearestPoint = this.nearestPoint(x, y, rx, ry, x0, y0);\n return distance(nearestPoint.x, nearestPoint.y, x0, y0);\n },\n /**\n * 根据比例获取点\n * @param {number} x 椭圆中心 x\n * @param {number} y 椭圆中心 y\n * @param {number} rx 椭圆 x 方向半径\n * @param {number} ry 椭圆 y 方向半径\n * @param {number} t 指定比例,x轴方向为 0\n * @return {object} 点\n */\n pointAt: function (x, y, rx, ry, t) {\n var angle = 2 * Math.PI * t; // 按照角度进行计算,而不按照周长计算\n return {\n x: x + rx * Math.cos(angle),\n y: y + ry * Math.sin(angle),\n };\n },\n /**\n * 根据比例计算切线角度\n * @param {number} x 椭圆中心 x\n * @param {number} y 椭圆中心 y\n * @param {number} rx 椭圆 x 方向半径\n * @param {number} ry 椭圆 y 方向半径\n * @param {number} t 指定比例 0 - 1 之间,x轴方向为 0。在 0-1 范围之外是循环还是返回 null,还需要调整\n * @return {number} 角度,在 0 - 2PI 之间\n */\n tangentAngle: function (x, y, rx, ry, t) {\n var angle = 2 * Math.PI * t; // 按照角度进行计算,而不按照周长计算\n // 直接使用 x,y 的导数计算, x\' = -rx * sin(t); y\' = ry * cos(t);\n var tangentAngle = Math.atan2(ry * Math.cos(angle), -rx * Math.sin(angle));\n // 也可以使用指定点的切线方程计算,成本有些高\n // const point = this.pointAt(0, 0, rx, ry, t); // 椭圆的切线同椭圆的中心不相关\n // let tangentAngle = -1 * Math.atan((ry * ry * point.x) / (rx * rx * point.y));\n // if (angle >= 0 && angle <= Math.PI) {\n // tangentAngle += Math.PI;\n // }\n return piMod(tangentAngle);\n },\n});\n//# sourceMappingURL=ellipse.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/arc.js\n\n\n// 偏导数 x\nfunction derivativeXAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle) {\n return -1 * rx * Math.cos(xRotation) * Math.sin(angle) - ry * Math.sin(xRotation) * Math.cos(angle);\n}\n// 偏导数 y\nfunction derivativeYAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle) {\n return -1 * rx * Math.sin(xRotation) * Math.sin(angle) + ry * Math.cos(xRotation) * Math.cos(angle);\n}\n// x 的极值\nfunction arc_xExtrema(rx, ry, xRotation) {\n return Math.atan((-ry / rx) * Math.tan(xRotation));\n}\n// y 的极值\nfunction arc_yExtrema(rx, ry, xRotation) {\n return Math.atan(ry / (rx * Math.tan(xRotation)));\n}\n// 根据角度求 x 坐标\nfunction xAt(cx, cy, rx, ry, xRotation, angle) {\n return rx * Math.cos(xRotation) * Math.cos(angle) - ry * Math.sin(xRotation) * Math.sin(angle) + cx;\n}\n// 根据角度求 y 坐标\nfunction yAt(cx, cy, rx, ry, xRotation, angle) {\n return rx * Math.sin(xRotation) * Math.cos(angle) + ry * Math.cos(xRotation) * Math.sin(angle) + cy;\n}\n// 获取点在椭圆上的角度\nfunction getAngle(rx, ry, x0, y0) {\n var angle = Math.atan2(y0 * rx, x0 * ry);\n // 转换到 0 - 2PI 内\n return (angle + Math.PI * 2) % (Math.PI * 2);\n}\n// 根据角度获取,x,y\nfunction getPoint(rx, ry, angle) {\n return {\n x: rx * Math.cos(angle),\n y: ry * Math.sin(angle),\n };\n}\n// 旋转\nfunction rotate(x, y, angle) {\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n return [x * cos - y * sin, x * sin + y * cos];\n}\n/* harmony default export */ var arc = ({\n /**\n * 计算包围盒\n * @param {number} cx 圆心 x\n * @param {number} cy 圆心 y\n * @param {number} rx x 轴方向的半径\n * @param {number} ry y 轴方向的半径\n * @param {number} xRotation 旋转角度\n * @param {number} startAngle 起始角度\n * @param {number} endAngle 结束角度\n * @return {object} 包围盒对象\n */\n box: function (cx, cy, rx, ry, xRotation, startAngle, endAngle) {\n var xDim = arc_xExtrema(rx, ry, xRotation);\n var minX = Infinity;\n var maxX = -Infinity;\n var xs = [startAngle, endAngle];\n for (var i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) {\n var xAngle = xDim + i;\n if (startAngle < endAngle) {\n if (startAngle < xAngle && xAngle < endAngle) {\n xs.push(xAngle);\n }\n }\n else {\n if (endAngle < xAngle && xAngle < startAngle) {\n xs.push(xAngle);\n }\n }\n }\n for (var i = 0; i < xs.length; i++) {\n var x = xAt(cx, cy, rx, ry, xRotation, xs[i]);\n if (x < minX) {\n minX = x;\n }\n if (x > maxX) {\n maxX = x;\n }\n }\n var yDim = arc_yExtrema(rx, ry, xRotation);\n var minY = Infinity;\n var maxY = -Infinity;\n var ys = [startAngle, endAngle];\n for (var i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) {\n var yAngle = yDim + i;\n if (startAngle < endAngle) {\n if (startAngle < yAngle && yAngle < endAngle) {\n ys.push(yAngle);\n }\n }\n else {\n if (endAngle < yAngle && yAngle < startAngle) {\n ys.push(yAngle);\n }\n }\n }\n for (var i = 0; i < ys.length; i++) {\n var y = yAt(cx, cy, rx, ry, xRotation, ys[i]);\n if (y < minY) {\n minY = y;\n }\n if (y > maxY) {\n maxY = y;\n }\n }\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n },\n /**\n * 获取圆弧的长度,计算圆弧长度时不考虑旋转角度,\n * 仅跟 rx, ry, startAngle, endAngle 相关\n * @param {number} cx 圆心 x\n * @param {number} cy 圆心 y\n * @param {number} rx x 轴方向的半径\n * @param {number} ry y 轴方向的半径\n * @param {number} xRotation 旋转角度\n * @param {number} startAngle 起始角度\n * @param {number} endAngle 结束角度\n */\n length: function (cx, cy, rx, ry, xRotation, startAngle, endAngle) { },\n /**\n * 获取指定点到圆弧的最近距离的点\n * @param {number} cx 圆心 x\n * @param {number} cy 圆心 y\n * @param {number} rx x 轴方向的半径\n * @param {number} ry y 轴方向的半径\n * @param {number} xRotation 旋转角度\n * @param {number} startAngle 起始角度\n * @param {number} endAngle 结束角度\n * @param {number} x0 指定点的 x\n * @param {number} y0 指定点的 y\n * @return {object} 到指定点最近距离的点\n */\n nearestPoint: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, x0, y0) {\n // 将最近距离问题转换成到椭圆中心 0,0 没有旋转的椭圆问题\n var relativeVector = rotate(x0 - cx, y0 - cy, -xRotation);\n var x1 = relativeVector[0], y1 = relativeVector[1];\n // 计算点到椭圆的最近的点\n var relativePoint = ellipse.nearestPoint(0, 0, rx, ry, x1, y1);\n // 获取点在椭圆上的角度\n var angle = getAngle(rx, ry, relativePoint.x, relativePoint.y);\n // 点没有在圆弧上\n if (angle < startAngle) {\n // 小于起始圆弧\n relativePoint = getPoint(rx, ry, startAngle);\n }\n else if (angle > endAngle) {\n // 大于结束圆弧\n relativePoint = getPoint(rx, ry, endAngle);\n }\n // 旋转到 xRotation 的角度\n var vector = rotate(relativePoint.x, relativePoint.y, xRotation);\n return {\n x: vector[0] + cx,\n y: vector[1] + cy,\n };\n },\n pointDistance: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, x0, y0) {\n var nearestPoint = this.nearestPoint(cx, cy, rx, ry, x0, y0);\n return distance(nearestPoint.x, nearestPoint.y, x0, y0);\n },\n pointAt: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, t) {\n var angle = (endAngle - startAngle) * t + startAngle;\n return {\n x: xAt(cx, cy, rx, ry, xRotation, angle),\n y: yAt(cx, cy, rx, ry, xRotation, angle),\n };\n },\n tangentAngle: function (cx, cy, rx, ry, xRotation, startAngle, endAngle, t) {\n var angle = (endAngle - startAngle) * t + startAngle;\n var dx = derivativeXAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle);\n var dy = derivativeYAt(cx, cy, rx, ry, xRotation, startAngle, endAngle, angle);\n return piMod(Math.atan2(dy, dx));\n },\n});\n//# sourceMappingURL=arc.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/segments.js\n\n\nfunction analyzePoints(points) {\n // 计算每段的长度和总的长度\n var totalLength = 0;\n var segments = [];\n for (var i = 0; i < points.length - 1; i++) {\n var from = points[i];\n var to = points[i + 1];\n var length_1 = distance(from[0], from[1], to[0], to[1]);\n var seg = {\n from: from,\n to: to,\n length: length_1,\n };\n segments.push(seg);\n totalLength += length_1;\n }\n return { segments: segments, totalLength: totalLength };\n}\nfunction lengthOfSegment(points) {\n if (points.length < 2) {\n return 0;\n }\n var totalLength = 0;\n for (var i = 0; i < points.length - 1; i++) {\n var from = points[i];\n var to = points[i + 1];\n totalLength += distance(from[0], from[1], to[0], to[1]);\n }\n return totalLength;\n}\n/**\n * 按照比例在数据片段中获取点\n * @param {array} points 点的集合\n * @param {number} t 百分比 0-1\n * @return {object} 点的坐标\n */\nfunction pointAtSegments(points, t) {\n // 边界判断\n if (t > 1 || t < 0 || points.length < 2) {\n return null;\n }\n var _a = analyzePoints(points), segments = _a.segments, totalLength = _a.totalLength;\n // 多个点有可能重合\n if (totalLength === 0) {\n return {\n x: points[0][0],\n y: points[0][1],\n };\n }\n // 计算比例\n var startRatio = 0;\n var point = null;\n for (var i = 0; i < segments.length; i++) {\n var seg = segments[i];\n var from = seg.from, to = seg.to;\n var currentRatio = seg.length / totalLength;\n if (t >= startRatio && t <= startRatio + currentRatio) {\n var localRatio = (t - startRatio) / currentRatio;\n point = line.pointAt(from[0], from[1], to[0], to[1], localRatio);\n break;\n }\n startRatio += currentRatio;\n }\n return point;\n}\n/**\n * 按照比例在数据片段中获取切线的角度\n * @param {array} points 点的集合\n * @param {number} t 百分比 0-1\n */\nfunction angleAtSegments(points, t) {\n // 边界判断\n if (t > 1 || t < 0 || points.length < 2) {\n return 0;\n }\n var _a = analyzePoints(points), segments = _a.segments, totalLength = _a.totalLength;\n // 计算比例\n var startRatio = 0;\n var angle = 0;\n for (var i = 0; i < segments.length; i++) {\n var seg = segments[i];\n var from = seg.from, to = seg.to;\n var currentRatio = seg.length / totalLength;\n if (t >= startRatio && t <= startRatio + currentRatio) {\n angle = Math.atan2(to[1] - from[1], to[0] - from[0]);\n break;\n }\n startRatio += currentRatio;\n }\n return angle;\n}\nfunction distanceAtSegment(points, x, y) {\n var minDistance = Infinity;\n for (var i = 0; i < points.length - 1; i++) {\n var point = points[i];\n var nextPoint = points[i + 1];\n var distance_1 = line.pointDistance(point[0], point[1], nextPoint[0], nextPoint[1], x, y);\n if (distance_1 < minDistance) {\n minDistance = distance_1;\n }\n }\n return minDistance;\n}\n//# sourceMappingURL=segments.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/polyline.js\n\n\n/* harmony default export */ var polyline = ({\n /**\n * 计算多折线的包围盒\n * @param {array} points 点的集合 [x,y] 的形式\n * @return {object} 包围盒\n */\n box: function (points) {\n var xArr = [];\n var yArr = [];\n for (var i = 0; i < points.length; i++) {\n var point = points[i];\n xArr.push(point[0]);\n yArr.push(point[1]);\n }\n return getBBoxByArray(xArr, yArr);\n },\n /**\n * 计算多折线的长度\n * @param {array} points 点的集合 [x,y] 的形式\n * @return {object} 多条边的长度\n */\n length: function (points) {\n return lengthOfSegment(points);\n },\n /**\n * 根据比例获取多折线的点\n * @param {array} points 点的集合 [x,y] 的形式\n * @param {number} t 在多折线的长度上的比例\n * @return {object} 根据比例值计算出来的点\n */\n pointAt: function (points, t) {\n return pointAtSegments(points, t);\n },\n /**\n * 指定点到多折线的距离\n * @param {array} points 点的集合 [x,y] 的形式\n * @param {number} x 指定点的 x\n * @param {number} y 指定点的 y\n * @return {number} 点到多折线的距离\n */\n pointDistance: function (points, x, y) {\n return distanceAtSegment(points, x, y);\n },\n /**\n * 根据比例获取多折线的切线角度\n * @param {array} points 点的集合 [x,y] 的形式\n * @param {number} t 在多折线的长度上的比例\n * @return {object} 根据比例值计算出来的角度\n */\n tangentAngle: function (points, t) {\n return angleAtSegments(points, t);\n },\n});\n//# sourceMappingURL=polyline.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/polygon.js\n\n\nfunction getAllPoints(points) {\n var tmp = points.slice(0);\n if (points.length) {\n tmp.push(points[0]);\n }\n return tmp;\n}\n/* harmony default export */ var polygon = ({\n /**\n * 计算多边形的包围盒\n * @param {array} points 点的集合 [x,y] 的形式\n * @return {object} 包围盒\n */\n box: function (points) {\n return polyline.box(points);\n },\n /**\n * 计算多边形的长度\n * @param {array} points 点的集合 [x,y] 的形式\n * @return {object} 多边形边的长度\n */\n length: function (points) {\n return lengthOfSegment(getAllPoints(points));\n },\n /**\n * 根据比例获取多边形的点\n * @param {array} points 点的集合 [x,y] 的形式\n * @param {number} t 在多边形的长度上的比例\n * @return {object} 根据比例值计算出来的点\n */\n pointAt: function (points, t) {\n return pointAtSegments(getAllPoints(points), t);\n },\n /**\n * 指定点到多边形的距离\n * @param {array} points 点的集合 [x,y] 的形式\n * @param {number} x 指定点的 x\n * @param {number} y 指定点的 y\n * @return {number} 点到多边形的距离\n */\n pointDistance: function (points, x, y) {\n return distanceAtSegment(getAllPoints(points), x, y);\n },\n /**\n * 根据比例获取多边形的切线角度\n * @param {array} points 点的集合 [x,y] 的形式\n * @param {number} t 在多边形的长度上的比例\n * @return {object} 根据比例值计算出来的角度\n */\n tangentAngle: function (points, t) {\n return angleAtSegments(getAllPoints(points), t);\n },\n});\n//# sourceMappingURL=polygon.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g-math/esm/index.js\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1tYXRoL2VzbS91dGlsLmpzPzRmNTMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L2ctbWF0aC9lc20vbGluZS5qcz9mNzViIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvZXNtL2Jlemllci5qcz9lYjQxIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvZXNtL3F1YWRyYXRpYy5qcz82MWZlIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvZXNtL2N1YmljLmpzPzY1ZDEiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L2ctbWF0aC9lc20vZWxsaXBzZS5qcz9mMzc1Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvZXNtL2FyYy5qcz9iZDAxIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9nLW1hdGgvZXNtL3NlZ21lbnRzLmpzPzIwZmUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L2ctbWF0aC9lc20vcG9seWxpbmUuanM/NDMyMCIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1tYXRoL2VzbS9wb2x5Z29uLmpzPzE5NTgiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L2ctbWF0aC9lc20vaW5kZXguanM/MTE4MyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFlBQVksT0FBTztBQUNuQjtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDTztB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RUFBQztBQUNGLG9DOztBQ3ZEa0c7QUFDaEU7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZTtBQUNmO0FBQ0E7QUFDQSxlQUFlLE1BQU07QUFDckIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixLQUFLO0FBQ0w7QUFDQTtBQUNBLGVBQWUsTUFBTTtBQUNyQixnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0EsZUFBZSxlQUFlO0FBQzlCLEtBQUs7QUFDTDtBQUNBO0FBQ0EsZUFBZSxNQUFNO0FBQ3JCLGVBQWUsT0FBTztBQUN0QixnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0EsZUFBZSxlQUFlO0FBQzlCLEtBQUs7QUFDTDtBQUNBO0FBQ0EsZUFBZSxNQUFNO0FBQ3JCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDLEtBQUs7QUFDTDtBQUNBO0FBQ0EsZUFBZSxNQUFNO0FBQ3JCLGVBQWUsT0FBTztBQUN0QixnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0EsZUFBZSxlQUFlO0FBQzlCLEtBQUs7QUFDTCxDQUFDLEVBQUM7QUFDRixtQzs7QUN2RCtCO0FBQ0g7QUFDSjtBQUNFO0FBQ007QUFDRTtBQUNIO0FBQzRCO0FBQzNEIiwiZmlsZSI6IjIwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gbWluTnVtKGFycmF5KSB7XG4gICAgcmV0dXJuIE1hdGgubWluLmFwcGx5KG51bGwsIGFycmF5KTtcbn1cbmZ1bmN0aW9uIG1heE51bShhcnJheSkge1xuICAgIHJldHVybiBNYXRoLm1heC5hcHBseShudWxsLCBhcnJheSk7XG59XG4vKipcbiAqIOS4pOeCueS5i+mXtOeahOi3neemu1xuICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gKiBAcmV0dXJuIHtudW1iZXJ9IOi3neemu1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpIHtcbiAgICB2YXIgZHggPSB4MSAtIHgyO1xuICAgIHZhciBkeSA9IHkxIC0geTI7XG4gICAgcmV0dXJuIE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG59XG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXJFcXVhbCh2MSwgdjIpIHtcbiAgICByZXR1cm4gTWF0aC5hYnModjEgLSB2MikgPCAwLjAwMTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRCQm94QnlBcnJheSh4QXJyLCB5QXJyKSB7XG4gICAgdmFyIG1pblggPSBtaW5OdW0oeEFycik7XG4gICAgdmFyIG1pblkgPSBtaW5OdW0oeUFycik7XG4gICAgdmFyIG1heFggPSBtYXhOdW0oeEFycik7XG4gICAgdmFyIG1heFkgPSBtYXhOdW0oeUFycik7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogbWluWCxcbiAgICAgICAgeTogbWluWSxcbiAgICAgICAgd2lkdGg6IG1heFggLSBtaW5YLFxuICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgIH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0QkJveFJhbmdlKHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluWDogbWluTnVtKFt4MSwgeDJdKSxcbiAgICAgICAgbWF4WDogbWF4TnVtKFt4MSwgeDJdKSxcbiAgICAgICAgbWluWTogbWluTnVtKFt5MSwgeTJdKSxcbiAgICAgICAgbWF4WTogbWF4TnVtKFt5MSwgeTJdKSxcbiAgICB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIHBpTW9kKGFuZ2xlKSB7XG4gICAgcmV0dXJuIChhbmdsZSArIE1hdGguUEkgKiAyKSAlIChNYXRoLlBJICogMik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD11dGlsLmpzLm1hcCIsImltcG9ydCB7IGRpc3RhbmNlLCBnZXRCQm94QnlBcnJheSB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgKiBhcyB2ZWMyIGZyb20gJ2dsLW1hdHJpeC92ZWMyJztcbmV4cG9ydCBkZWZhdWx0IHtcbiAgICAvKipcbiAgICAgKiDorqHnrpfnur/mrrXnmoTljIXlm7Tnm5JcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDIg57uT5p2f54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTIg57uT5p2f54K5IHlcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOWMheWbtOebkuWvueixoVxuICAgICAqL1xuICAgIGJveDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgICAgIHJldHVybiBnZXRCQm94QnlBcnJheShbeDEsIHgyXSwgW3kxLCB5Ml0pO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog57q/5q6155qE6ZW/5bqmXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkxIOi1t+Wni+eCuSB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgyIOe7k+adn+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gICAgICogQHJldHVybiB7bnVtYmVyfSDot53nprtcbiAgICAgKi9cbiAgICBsZW5ndGg6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgICByZXR1cm4gZGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5q+U5L6L6I635Y+W54K5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkxIOi1t+Wni+eCuSB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgyIOe7k+adn+eCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkyIOe7k+adn+eCuSB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5oyH5a6a5q+U5L6LXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDljIXlkKsgeCwgeSDnmoTngrlcbiAgICAgKi9cbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6ICgxIC0gdCkgKiB4MSArIHQgKiB4MixcbiAgICAgICAgICAgIHk6ICgxIC0gdCkgKiB5MSArIHQgKiB5MixcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOeCueWIsOe6v+auteeahOi3neemu1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MSDotbflp4vngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MSDotbflp4vngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnu5PmnZ/ngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5MiDnu5PmnZ/ngrkgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmtYvor5XngrkgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmtYvor5XngrkgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g6Led56a7XG4gICAgICovXG4gICAgcG9pbnREaXN0YW5jZTogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4LCB5KSB7XG4gICAgICAgIC8vIOaKleW9sei3neemuyB4MSwgeTEg55qE5ZCR6YeP77yM5YGH6K6+IHAsIHAxLCBwMiDkuInkuKrngrnvvIzmipXlvbHngrnkuLogYVxuICAgICAgICAvLyBwMWEgPSBwMXAucDFwMi98cDFwMnwgKiAocDFwIOeahOWNleS9jeWQkemHjylcbiAgICAgICAgdmFyIGNyb3NzID0gKHgyIC0geDEpICogKHggLSB4MSkgKyAoeTIgLSB5MSkgKiAoeSAtIHkxKTtcbiAgICAgICAgaWYgKGNyb3NzIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGRpc3RhbmNlKHgxLCB5MSwgeCwgeSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGxlbmd0aFNxdWFyZSA9ICh4MiAtIHgxKSAqICh4MiAtIHgxKSArICh5MiAtIHkxKSAqICh5MiAtIHkxKTtcbiAgICAgICAgaWYgKGNyb3NzID4gbGVuZ3RoU3F1YXJlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGlzdGFuY2UoeDIsIHkyLCB4LCB5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5wb2ludFRvTGluZSh4MSwgeTEsIHgyLCB5MiwgeCwgeSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDngrnliLDnm7Tnur/nmoTot53nprvvvIzogIzkuI3mmK/ngrnliLDnur/mrrXnmoTot53nprtcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDIg57uT5p2f54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTIg57uT5p2f54K5IHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geCAg5rWL6K+V54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geSAg5rWL6K+V54K5IHlcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IOi3neemu1xuICAgICAqL1xuICAgIHBvaW50VG9MaW5lOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgsIHkpIHtcbiAgICAgICAgdmFyIGQgPSBbeDIgLSB4MSwgeTIgLSB5MV07XG4gICAgICAgIC8vIOWmguaenOerr+eCueebuOetie+8jOWImeWIpOWumueCueWIsOeCueeahOi3neemu1xuICAgICAgICBpZiAodmVjMi5leGFjdEVxdWFscyhkLCBbMCwgMF0pKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5zcXJ0KCh4IC0geDEpICogKHggLSB4MSkgKyAoeSAtIHkxKSAqICh5IC0geTEpKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdSA9IFstZFsxXSwgZFswXV07XG4gICAgICAgIHZlYzIubm9ybWFsaXplKHUsIHUpO1xuICAgICAgICB2YXIgYSA9IFt4IC0geDEsIHkgLSB5MV07XG4gICAgICAgIHJldHVybiBNYXRoLmFicyh2ZWMyLmRvdChhLCB1KSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDnur/mrrXnmoTop5LluqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDEg6LW35aeL54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDIg57uT5p2f54K5IHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTIg57uT5p2f54K5IHlcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IOWvvOaVsFxuICAgICAqL1xuICAgIHRhbmdlbnRBbmdsZTogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmF0YW4yKHkyIC0geTEsIHgyIC0geDEpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bGluZS5qcy5tYXAiLCJpbXBvcnQgeyBkaXN0YW5jZSB9IGZyb20gJy4vdXRpbCc7XG52YXIgRVBTSUxPTiA9IDAuMDAwMTtcbi8qKlxuICog5L2/55So54mb6aG/5YiH5Ymy5rOV5rGC5pyA6L+R55qE54K5XG4gKiBAcGFyYW0ge251bWJlcltdfSB4QXJyICAgICAg54K555qEIHgg5pWw57uEXG4gKiBAcGFyYW0ge251bWJlcltdfSB5QXJyICAgICAg54K555qEIHkg5pWw57uEXG4gKiBAcGFyYW0ge251bWJlcn0gICB4ICAgICAgICAg5oyH5a6a55qE54K5IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSAgIHkgICAgICAgICDmjIflrprnmoTngrkgeVxuICogQHBhcmFtIHtGdW5jdGlvbn0gdENhbGxiYWNrIOW3ruWAvOWHveaVsFxuICovXG5leHBvcnQgZnVuY3Rpb24gbmVhcmVzdFBvaW50KHhBcnIsIHlBcnIsIHgsIHksIHRDYWxsYmFjaywgbGVuZ3RoKSB7XG4gICAgdmFyIHQ7XG4gICAgdmFyIGQgPSBJbmZpbml0eTtcbiAgICB2YXIgdjAgPSBbeCwgeV07XG4gICAgdmFyIHNlZ051bSA9IDIwO1xuICAgIGlmIChsZW5ndGggJiYgbGVuZ3RoID4gMjAwKSB7XG4gICAgICAgIHNlZ051bSA9IGxlbmd0aCAvIDEwO1xuICAgIH1cbiAgICB2YXIgaW5jcmVhc2VSYXRlID0gMSAvIHNlZ051bTtcbiAgICB2YXIgaW50ZXJ2YWwgPSBpbmNyZWFzZVJhdGUgLyAxMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBzZWdOdW07IGkrKykge1xuICAgICAgICB2YXIgX3QgPSBpICogaW5jcmVhc2VSYXRlO1xuICAgICAgICB2YXIgdjEgPSBbdENhbGxiYWNrLmFwcGx5KG51bGwsIHhBcnIuY29uY2F0KFtfdF0pKSwgdENhbGxiYWNrLmFwcGx5KG51bGwsIHlBcnIuY29uY2F0KFtfdF0pKV07XG4gICAgICAgIHZhciBkMSA9IGRpc3RhbmNlKHYwWzBdLCB2MFsxXSwgdjFbMF0sIHYxWzFdKTtcbiAgICAgICAgaWYgKGQxIDwgZCkge1xuICAgICAgICAgICAgdCA9IF90O1xuICAgICAgICAgICAgZCA9IGQxO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIOaPkOWJjee7iOatolxuICAgIGlmICh0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4QXJyWzBdLFxuICAgICAgICAgICAgeTogeUFyclswXSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHQgPT09IDEpIHtcbiAgICAgICAgdmFyIGNvdW50ID0geEFyci5sZW5ndGg7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4QXJyW2NvdW50IC0gMV0sXG4gICAgICAgICAgICB5OiB5QXJyW2NvdW50IC0gMV0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIGQgPSBJbmZpbml0eTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHtcbiAgICAgICAgaWYgKGludGVydmFsIDwgRVBTSUxPTikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHByZXYgPSB0IC0gaW50ZXJ2YWw7XG4gICAgICAgIHZhciBuZXh0ID0gdCArIGludGVydmFsO1xuICAgICAgICB2YXIgdjEgPSBbdENhbGxiYWNrLmFwcGx5KG51bGwsIHhBcnIuY29uY2F0KFtwcmV2XSkpLCB0Q2FsbGJhY2suYXBwbHkobnVsbCwgeUFyci5jb25jYXQoW3ByZXZdKSldO1xuICAgICAgICB2YXIgZDEgPSBkaXN0YW5jZSh2MFswXSwgdjBbMV0sIHYxWzBdLCB2MVsxXSk7XG4gICAgICAgIGlmIChwcmV2ID49IDAgJiYgZDEgPCBkKSB7XG4gICAgICAgICAgICB0ID0gcHJldjtcbiAgICAgICAgICAgIGQgPSBkMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciB2MiA9IFt0Q2FsbGJhY2suYXBwbHkobnVsbCwgeEFyci5jb25jYXQoW25leHRdKSksIHRDYWxsYmFjay5hcHBseShudWxsLCB5QXJyLmNvbmNhdChbbmV4dF0pKV07XG4gICAgICAgICAgICB2YXIgZDIgPSBkaXN0YW5jZSh2MFswXSwgdjBbMV0sIHYyWzBdLCB2MlsxXSk7XG4gICAgICAgICAgICBpZiAobmV4dCA8PSAxICYmIGQyIDwgZCkge1xuICAgICAgICAgICAgICAgIHQgPSBuZXh0O1xuICAgICAgICAgICAgICAgIGQgPSBkMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGludGVydmFsICo9IDAuNTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB0Q2FsbGJhY2suYXBwbHkobnVsbCwgeEFyci5jb25jYXQoW3RdKSksXG4gICAgICAgIHk6IHRDYWxsYmFjay5hcHBseShudWxsLCB5QXJyLmNvbmNhdChbdF0pKSxcbiAgICB9O1xufVxuLy8g6L+R5Ly85rGC6KejIGh0dHBzOi8vY29tbXVuaXR5Lmtocm9ub3Mub3JnL3QvM2QtY3ViaWMtYmV6aWVyLXNlZ21lbnQtbGVuZ3RoLzYyMzYzLzJcbmV4cG9ydCBmdW5jdGlvbiBzbmFwTGVuZ3RoKHhBcnIsIHlBcnIpIHtcbiAgICB2YXIgdG90YWxMZW5ndGggPSAwO1xuICAgIHZhciBjb3VudCA9IHhBcnIubGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICB2YXIgeCA9IHhBcnJbaV07XG4gICAgICAgIHZhciB5ID0geUFycltpXTtcbiAgICAgICAgdmFyIG5leHRYID0geEFyclsoaSArIDEpICUgY291bnRdO1xuICAgICAgICB2YXIgbmV4dFkgPSB5QXJyWyhpICsgMSkgJSBjb3VudF07XG4gICAgICAgIHRvdGFsTGVuZ3RoICs9IGRpc3RhbmNlKHgsIHksIG5leHRYLCBuZXh0WSk7XG4gICAgfVxuICAgIHJldHVybiB0b3RhbExlbmd0aCAvIDI7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iZXppZXIuanMubWFwIiwiaW1wb3J0IGxpbmUgZnJvbSAnLi9saW5lJztcbmltcG9ydCB7IGRpc3RhbmNlLCBpc051bWJlckVxdWFsLCBnZXRCQm94QnlBcnJheSwgcGlNb2QgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHsgbmVhcmVzdFBvaW50IH0gZnJvbSAnLi9iZXppZXInO1xuLy8g5beu5YC85YWs5byPXG5mdW5jdGlvbiBxdWFkcmF0aWNBdChwMCwgcDEsIHAyLCB0KSB7XG4gICAgdmFyIG9uZXQgPSAxIC0gdDtcbiAgICByZXR1cm4gb25ldCAqIG9uZXQgKiBwMCArIDIgKiB0ICogb25ldCAqIHAxICsgdCAqIHQgKiBwMjtcbn1cbi8vIOaxguaegeWAvFxuZnVuY3Rpb24gZXh0cmVtYShwMCwgcDEsIHAyKSB7XG4gICAgdmFyIGEgPSBwMCArIHAyIC0gMiAqIHAxO1xuICAgIGlmIChpc051bWJlckVxdWFsKGEsIDApKSB7XG4gICAgICAgIHJldHVybiBbMC41XTtcbiAgICB9XG4gICAgdmFyIHJzdCA9IChwMCAtIHAxKSAvIGE7XG4gICAgaWYgKHJzdCA8PSAxICYmIHJzdCA+PSAwKSB7XG4gICAgICAgIHJldHVybiBbcnN0XTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xufVxuZnVuY3Rpb24gZGVyaXZhdGl2ZUF0KHAwLCBwMSwgcDIsIHQpIHtcbiAgICByZXR1cm4gMiAqICgxIC0gdCkgKiAocDEgLSBwMCkgKyAyICogdCAqIChwMiAtIHAxKTtcbn1cbi8vIOWIhuWJsui0neWhnuWwlOabsue6v1xuZnVuY3Rpb24gZGl2aWRlUXVhZHJhdGljKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHQpIHtcbiAgICAvLyDliJLliIbngrlcbiAgICB2YXIgeHQgPSBxdWFkcmF0aWNBdCh4MSwgeDIsIHgzLCB0KTtcbiAgICB2YXIgeXQgPSBxdWFkcmF0aWNBdCh5MSwgeTIsIHkzLCB0KTtcbiAgICAvLyDliIblibLnmoTnrKzkuIDmnaHmm7Lnur/nmoTmjqfliLbngrlcbiAgICB2YXIgY29udHJvbFBvaW50MSA9IGxpbmUucG9pbnRBdCh4MSwgeTEsIHgyLCB5MiwgdCk7XG4gICAgLy8g5YiG5Ymy55qE56ys5LqM5p2h5puy57q/55qE5o6n5Yi254K5XG4gICAgdmFyIGNvbnRyb2xQb2ludDIgPSBsaW5lLnBvaW50QXQoeDIsIHkyLCB4MywgeTMsIHQpO1xuICAgIHJldHVybiBbXG4gICAgICAgIFt4MSwgeTEsIGNvbnRyb2xQb2ludDEueCwgY29udHJvbFBvaW50MS55LCB4dCwgeXRdLFxuICAgICAgICBbeHQsIHl0LCBjb250cm9sUG9pbnQyLngsIGNvbnRyb2xQb2ludDIueSwgeDMsIHkzXSxcbiAgICBdO1xufVxuLy8g5L2/55So6L+t5Luj5rOV5Y+W6LSd5aGe5bCU5puy57q/55qE6ZW/5bqmXG5mdW5jdGlvbiBxdWFkcmF0aWNMZW5ndGgoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgaXRlcmF0aW9uQ291bnQpIHtcbiAgICBpZiAoaXRlcmF0aW9uQ291bnQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIChkaXN0YW5jZSh4MSwgeTEsIHgyLCB5MikgKyBkaXN0YW5jZSh4MiwgeTIsIHgzLCB5MykgKyBkaXN0YW5jZSh4MSwgeTEsIHgzLCB5MykpIC8gMjtcbiAgICB9XG4gICAgdmFyIHF1YWRyYXRpY3MgPSBkaXZpZGVRdWFkcmF0aWMoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgMC41KTtcbiAgICB2YXIgbGVmdCA9IHF1YWRyYXRpY3NbMF07XG4gICAgdmFyIHJpZ2h0ID0gcXVhZHJhdGljc1sxXTtcbiAgICBsZWZ0LnB1c2goaXRlcmF0aW9uQ291bnQgLSAxKTtcbiAgICByaWdodC5wdXNoKGl0ZXJhdGlvbkNvdW50IC0gMSk7XG4gICAgcmV0dXJuIHF1YWRyYXRpY0xlbmd0aC5hcHBseShudWxsLCBsZWZ0KSArIHF1YWRyYXRpY0xlbmd0aC5hcHBseShudWxsLCByaWdodCk7XG59XG5leHBvcnQgZGVmYXVsdCB7XG4gICAgYm94OiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5Mykge1xuICAgICAgICB2YXIgeEV4dHJlbWEgPSBleHRyZW1hKHgxLCB4MiwgeDMpWzBdO1xuICAgICAgICB2YXIgeUV4dHJlbWEgPSBleHRyZW1hKHkxLCB5MiwgeTMpWzBdO1xuICAgICAgICAvLyDmjqfliLbngrnkuI3liqDlhaUgYm94IOeahOiuoeeul1xuICAgICAgICB2YXIgeEFyciA9IFt4MSwgeDNdO1xuICAgICAgICB2YXIgeUFyciA9IFt5MSwgeTNdO1xuICAgICAgICBpZiAoeEV4dHJlbWEgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgeEFyci5wdXNoKHF1YWRyYXRpY0F0KHgxLCB4MiwgeDMsIHhFeHRyZW1hKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHlFeHRyZW1hICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHlBcnIucHVzaChxdWFkcmF0aWNBdCh5MSwgeTIsIHkzLCB5RXh0cmVtYSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXRCQm94QnlBcnJheSh4QXJyLCB5QXJyKTtcbiAgICB9LFxuICAgIGxlbmd0aDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgICAgICAgcmV0dXJuIHF1YWRyYXRpY0xlbmd0aCh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCAzKTtcbiAgICB9LFxuICAgIG5lYXJlc3RQb2ludDogZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHgwLCB5MCkge1xuICAgICAgICByZXR1cm4gbmVhcmVzdFBvaW50KFt4MSwgeDIsIHgzXSwgW3kxLCB5MiwgeTNdLCB4MCwgeTAsIHF1YWRyYXRpY0F0KTtcbiAgICB9LFxuICAgIHBvaW50RGlzdGFuY2U6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4MCwgeTApIHtcbiAgICAgICAgdmFyIHBvaW50ID0gdGhpcy5uZWFyZXN0UG9pbnQoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDAsIHkwKTtcbiAgICAgICAgcmV0dXJuIGRpc3RhbmNlKHBvaW50LngsIHBvaW50LnksIHgwLCB5MCk7XG4gICAgfSxcbiAgICBpbnRlcnBvbGF0aW9uQXQ6IHF1YWRyYXRpY0F0LFxuICAgIHBvaW50QXQ6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB0KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBxdWFkcmF0aWNBdCh4MSwgeDIsIHgzLCB0KSxcbiAgICAgICAgICAgIHk6IHF1YWRyYXRpY0F0KHkxLCB5MiwgeTMsIHQpLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgZGl2aWRlOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgdCkge1xuICAgICAgICByZXR1cm4gZGl2aWRlUXVhZHJhdGljKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHQpO1xuICAgIH0sXG4gICAgdGFuZ2VudEFuZ2xlOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgdCkge1xuICAgICAgICB2YXIgZHggPSBkZXJpdmF0aXZlQXQoeDEsIHgyLCB4MywgdCk7XG4gICAgICAgIHZhciBkeSA9IGRlcml2YXRpdmVBdCh5MSwgeTIsIHkzLCB0KTtcbiAgICAgICAgdmFyIGFuZ2xlID0gTWF0aC5hdGFuMihkeSwgZHgpO1xuICAgICAgICByZXR1cm4gcGlNb2QoYW5nbGUpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cXVhZHJhdGljLmpzLm1hcCIsImltcG9ydCB7IGRpc3RhbmNlLCBpc051bWJlckVxdWFsLCBnZXRCQm94QnlBcnJheSwgcGlNb2QgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IGxpbmUgZnJvbSAnLi9saW5lJztcbmltcG9ydCB7IHNuYXBMZW5ndGgsIG5lYXJlc3RQb2ludCB9IGZyb20gJy4vYmV6aWVyJztcbmZ1bmN0aW9uIGN1YmljQXQocDAsIHAxLCBwMiwgcDMsIHQpIHtcbiAgICB2YXIgb25ldCA9IDEgLSB0OyAvLyB0ICogdCAqIHQg55qE5oCn6IO95aSn5qaC5pivIE1hdGgucG93KHQsIDMpIOeahOS4ieWAjVxuICAgIHJldHVybiBvbmV0ICogb25ldCAqIG9uZXQgKiBwMCArIDMgKiBwMSAqIHQgKiBvbmV0ICogb25ldCArIDMgKiBwMiAqIHQgKiB0ICogb25ldCArIHAzICogdCAqIHQgKiB0O1xufVxuZnVuY3Rpb24gZGVyaXZhdGl2ZUF0KHAwLCBwMSwgcDIsIHAzLCB0KSB7XG4gICAgdmFyIG9uZXQgPSAxIC0gdDtcbiAgICByZXR1cm4gMyAqIChvbmV0ICogb25ldCAqIChwMSAtIHAwKSArIDIgKiBvbmV0ICogdCAqIChwMiAtIHAxKSArIHQgKiB0ICogKHAzIC0gcDIpKTtcbn1cbmZ1bmN0aW9uIGV4dHJlbWEocDAsIHAxLCBwMiwgcDMpIHtcbiAgICB2YXIgYSA9IC0zICogcDAgKyA5ICogcDEgLSA5ICogcDIgKyAzICogcDM7XG4gICAgdmFyIGIgPSA2ICogcDAgLSAxMiAqIHAxICsgNiAqIHAyO1xuICAgIHZhciBjID0gMyAqIHAxIC0gMyAqIHAwO1xuICAgIHZhciBleHRyZW1hcyA9IFtdO1xuICAgIHZhciB0MTtcbiAgICB2YXIgdDI7XG4gICAgdmFyIGRpc2NTcXJ0O1xuICAgIGlmIChpc051bWJlckVxdWFsKGEsIDApKSB7XG4gICAgICAgIGlmICghaXNOdW1iZXJFcXVhbChiLCAwKSkge1xuICAgICAgICAgICAgdDEgPSAtYyAvIGI7XG4gICAgICAgICAgICBpZiAodDEgPj0gMCAmJiB0MSA8PSAxKSB7XG4gICAgICAgICAgICAgICAgZXh0cmVtYXMucHVzaCh0MSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZhciBkaXNjID0gYiAqIGIgLSA0ICogYSAqIGM7XG4gICAgICAgIGlmIChpc051bWJlckVxdWFsKGRpc2MsIDApKSB7XG4gICAgICAgICAgICBleHRyZW1hcy5wdXNoKC1iIC8gKDIgKiBhKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGlzYyA+IDApIHtcbiAgICAgICAgICAgIGRpc2NTcXJ0ID0gTWF0aC5zcXJ0KGRpc2MpO1xuICAgICAgICAgICAgdDEgPSAoLWIgKyBkaXNjU3FydCkgLyAoMiAqIGEpO1xuICAgICAgICAgICAgdDIgPSAoLWIgLSBkaXNjU3FydCkgLyAoMiAqIGEpO1xuICAgICAgICAgICAgaWYgKHQxID49IDAgJiYgdDEgPD0gMSkge1xuICAgICAgICAgICAgICAgIGV4dHJlbWFzLnB1c2godDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHQyID49IDAgJiYgdDIgPD0gMSkge1xuICAgICAgICAgICAgICAgIGV4dHJlbWFzLnB1c2godDIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBleHRyZW1hcztcbn1cbi8vIOWIhuWJsui0neWhnuWwlOabsue6v1xuZnVuY3Rpb24gZGl2aWRlQ3ViaWMoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0KSB7XG4gICAgLy8g5YiS5YiG54K5XG4gICAgdmFyIHh0ID0gY3ViaWNBdCh4MSwgeDIsIHgzLCB4NCwgdCk7XG4gICAgdmFyIHl0ID0gY3ViaWNBdCh5MSwgeTIsIHkzLCB5NCwgdCk7XG4gICAgLy8g6K6h566X5Lik54K55LmL6Ze055qE5beu5YC854K5XG4gICAgdmFyIGMxID0gbGluZS5wb2ludEF0KHgxLCB5MSwgeDIsIHkyLCB0KTtcbiAgICB2YXIgYzIgPSBsaW5lLnBvaW50QXQoeDIsIHkyLCB4MywgeTMsIHQpO1xuICAgIHZhciBjMyA9IGxpbmUucG9pbnRBdCh4MywgeTMsIHg0LCB5NCwgdCk7XG4gICAgdmFyIGMxMiA9IGxpbmUucG9pbnRBdChjMS54LCBjMS55LCBjMi54LCBjMi55LCB0KTtcbiAgICB2YXIgYzIzID0gbGluZS5wb2ludEF0KGMyLngsIGMyLnksIGMzLngsIGMzLnksIHQpO1xuICAgIHJldHVybiBbXG4gICAgICAgIFt4MSwgeTEsIGMxLngsIGMxLnksIGMxMi54LCBjMTIueSwgeHQsIHl0XSxcbiAgICAgICAgW3h0LCB5dCwgYzIzLngsIGMyMy55LCBjMy54LCBjMy55LCB4NCwgeTRdLFxuICAgIF07XG59XG4vLyDkvb/nlKjov63ku6Pms5Xlj5botJ3loZ7lsJTmm7Lnur/nmoTplb/luqbvvIzkuozpmLblkozkuInpmLbliIblvIDlhpnvvIzmm7TmuIXmmbDlkozkvr/kuo7osIPor5VcbmZ1bmN0aW9uIGN1YmljTGVuZ3RoKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgaXRlcmF0aW9uQ291bnQpIHtcbiAgICBpZiAoaXRlcmF0aW9uQ291bnQgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHNuYXBMZW5ndGgoW3gxLCB4MiwgeDMsIHg0XSwgW3kxLCB5MiwgeTMsIHk0XSk7XG4gICAgfVxuICAgIHZhciBjdWJpY3MgPSBkaXZpZGVDdWJpYyh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIDAuNSk7XG4gICAgdmFyIGxlZnQgPSBjdWJpY3NbMF07XG4gICAgdmFyIHJpZ2h0ID0gY3ViaWNzWzFdO1xuICAgIGxlZnQucHVzaChpdGVyYXRpb25Db3VudCAtIDEpO1xuICAgIHJpZ2h0LnB1c2goaXRlcmF0aW9uQ291bnQgLSAxKTtcbiAgICByZXR1cm4gY3ViaWNMZW5ndGguYXBwbHkobnVsbCwgbGVmdCkgKyBjdWJpY0xlbmd0aC5hcHBseShudWxsLCByaWdodCk7XG59XG5leHBvcnQgZGVmYXVsdCB7XG4gICAgZXh0cmVtYTogZXh0cmVtYSxcbiAgICBib3g6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIHtcbiAgICAgICAgdmFyIHhBcnIgPSBbeDEsIHg0XTtcbiAgICAgICAgdmFyIHlBcnIgPSBbeTEsIHk0XTtcbiAgICAgICAgdmFyIHhFeHRyZW1hID0gZXh0cmVtYSh4MSwgeDIsIHgzLCB4NCk7XG4gICAgICAgIHZhciB5RXh0cmVtYSA9IGV4dHJlbWEoeTEsIHkyLCB5MywgeTQpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhFeHRyZW1hLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB4QXJyLnB1c2goY3ViaWNBdCh4MSwgeDIsIHgzLCB4NCwgeEV4dHJlbWFbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHlFeHRyZW1hLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB5QXJyLnB1c2goY3ViaWNBdCh5MSwgeTIsIHkzLCB5NCwgeUV4dHJlbWFbaV0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2V0QkJveEJ5QXJyYXkoeEFyciwgeUFycik7XG4gICAgfSxcbiAgICBsZW5ndGg6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIHtcbiAgICAgICAgLy8g6L+t5Luj5LiJ5qyh77yM5YiS5YiG5oiQIDgg5q615rGC6ZW/5bqmXG4gICAgICAgIHJldHVybiBjdWJpY0xlbmd0aCh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIDMpO1xuICAgIH0sXG4gICAgbmVhcmVzdFBvaW50OiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB4MCwgeTAsIGxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbmVhcmVzdFBvaW50KFt4MSwgeDIsIHgzLCB4NF0sIFt5MSwgeTIsIHkzLCB5NF0sIHgwLCB5MCwgY3ViaWNBdCwgbGVuZ3RoKTtcbiAgICB9LFxuICAgIHBvaW50RGlzdGFuY2U6IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHgwLCB5MCwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHRoaXMubmVhcmVzdFBvaW50KHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeDAsIHkwLCBsZW5ndGgpO1xuICAgICAgICByZXR1cm4gZGlzdGFuY2UocG9pbnQueCwgcG9pbnQueSwgeDAsIHkwKTtcbiAgICB9LFxuICAgIGludGVycG9sYXRpb25BdDogY3ViaWNBdCxcbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiBjdWJpY0F0KHgxLCB4MiwgeDMsIHg0LCB0KSxcbiAgICAgICAgICAgIHk6IGN1YmljQXQoeTEsIHkyLCB5MywgeTQsIHQpLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgZGl2aWRlOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0KSB7XG4gICAgICAgIHJldHVybiBkaXZpZGVDdWJpYyh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQsIHQpO1xuICAgIH0sXG4gICAgdGFuZ2VudEFuZ2xlOiBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0KSB7XG4gICAgICAgIHZhciBkeCA9IGRlcml2YXRpdmVBdCh4MSwgeDIsIHgzLCB4NCwgdCk7XG4gICAgICAgIHZhciBkeSA9IGRlcml2YXRpdmVBdCh5MSwgeTIsIHkzLCB5NCwgdCk7XG4gICAgICAgIHJldHVybiBwaU1vZChNYXRoLmF0YW4yKGR5LCBkeCkpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3ViaWMuanMubWFwIiwiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOakreWchueahOS4gOS6m+iuoeeul++8jFxuICogIC0g5ZGo6ZW/6K6h566X5Y+C6ICD77yaaHR0cHM6Ly93d3cubWF0aHNpc2Z1bi5jb20vZ2VvbWV0cnkvZWxsaXBzZS1wZXJpbWV0ZXIuaHRtbFxuICogIC0g6Led56a76K6h566X5Y+C6ICD77yaaHR0cHM6Ly93ZXQtcm9ib3RzLmdob3N0LmlvL3NpbXBsZS1tZXRob2QtZm9yLWRpc3RhbmNlLXRvLWVsbGlwc2UvXG4gKiBAYXV0aG9yIGR4cTYxM0BnbWFpbC5jb21cbiAqL1xuaW1wb3J0IHsgZGlzdGFuY2UsIHBpTW9kIH0gZnJvbSAnLi91dGlsJztcbmZ1bmN0aW9uIGNvcHlzaWduKHYxLCB2Mikge1xuICAgIHZhciBhYnN2ID0gTWF0aC5hYnModjEpO1xuICAgIHJldHVybiB2MiA+IDAgPyBhYnN2IDogYWJzdiAqIC0xO1xufVxuZXhwb3J0IGRlZmF1bHQge1xuICAgIC8qKlxuICAgICAqIOWMheWbtOebkuiuoeeul1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmpK3lnIbkuK3lv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmpK3lnIbkuK3lv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCDmpK3lnIYgeCDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkg5qSt5ZyGIHkg5pa55ZCR5Y2K5b6EXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDljIXlm7Tnm5JcbiAgICAgKi9cbiAgICBib3g6IGZ1bmN0aW9uICh4LCB5LCByeCwgcnkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHggLSByeCxcbiAgICAgICAgICAgIHk6IHkgLSByeSxcbiAgICAgICAgICAgIHdpZHRoOiByeCAqIDIsXG4gICAgICAgICAgICBoZWlnaHQ6IHJ5ICogMixcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOiuoeeul+WRqOmVv++8jOS9v+eUqOi/keS8vOazlVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4ICDmpK3lnIbkuK3lv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ICDmpK3lnIbkuK3lv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCDmpK3lnIYgeCDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkg5qSt5ZyGIHkg5pa55ZCR5Y2K5b6EXG4gICAgICogQHJldHVybiB7bnVtYmVyfSDmpK3lnIblkajplb9cbiAgICAgKi9cbiAgICBsZW5ndGg6IGZ1bmN0aW9uICh4LCB5LCByeCwgcnkpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguUEkgKiAoMyAqIChyeCArIHJ5KSAtIE1hdGguc3FydCgoMyAqIHJ4ICsgcnkpICogKHJ4ICsgMyAqIHJ5KSkpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog6Led56a75qSt5ZyG5pyA6L+R55qE54K5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHggIOakreWchuS4reW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkgIOakreWchuS4reW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4IOakreWchiB4IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSDmpK3lnIYgeSDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDAgIOaMh+WumueahOeCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkwICDmjIflrprnmoTngrkgeVxuICAgICAqIEByZXR1cm4ge29iamVjdH0g5qSt5ZyG5LiK6Led56a75oyH5a6a54K55pyA6L+R55qE54K5XG4gICAgICovXG4gICAgbmVhcmVzdFBvaW50OiBmdW5jdGlvbiAoeCwgeSwgcngsIHJ5LCB4MCwgeTApIHtcbiAgICAgICAgdmFyIGEgPSByeDtcbiAgICAgICAgdmFyIGIgPSByeTtcbiAgICAgICAgLy8g5YGH5aaC5qSt5ZyG5Y2K5b6E5Li6MOWImei/lOWbnuWchuW/g1xuICAgICAgICBpZiAoYSA9PT0gMCB8fCBiID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICAgICAgeTogeSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgLy8g6L2s5o2i5oiQIDDvvIwgMCDkuLrkuK3lv4PnmoTmpK3lnIborqHnrpdcbiAgICAgICAgdmFyIHJlbGF0aXZlWCA9IHgwIC0geDtcbiAgICAgICAgdmFyIHJlbGF0aXZlWSA9IHkwIC0geTtcbiAgICAgICAgdmFyIHB4ID0gTWF0aC5hYnMocmVsYXRpdmVYKTtcbiAgICAgICAgdmFyIHB5ID0gTWF0aC5hYnMocmVsYXRpdmVZKTtcbiAgICAgICAgdmFyIHNxdWFyZUEgPSBhICogYTtcbiAgICAgICAgdmFyIHNxdWFyZUIgPSBiICogYjtcbiAgICAgICAgLy8gY29uc3QgYW5nbGUwID0gTWF0aC5hdGFuMihyZWxhdGl2ZVksIHJlbGF0aXZlWCk7XG4gICAgICAgIHZhciB0ID0gTWF0aC5QSSAvIDQ7XG4gICAgICAgIHZhciBuZWFyZXN0WDsgLy8g5qSt5ZyG5LiK55qE5Lu75LiA54K5XG4gICAgICAgIHZhciBuZWFyZXN0WTtcbiAgICAgICAgLy8g6L+t5LujIDQg5qyhXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgICAgICBuZWFyZXN0WCA9IGEgKiBNYXRoLmNvcyh0KTtcbiAgICAgICAgICAgIG5lYXJlc3RZID0gYiAqIE1hdGguc2luKHQpO1xuICAgICAgICAgICAgdmFyIGV4ID0gKChzcXVhcmVBIC0gc3F1YXJlQikgKiBNYXRoLnBvdyhNYXRoLmNvcyh0KSwgMykpIC8gYTtcbiAgICAgICAgICAgIHZhciBleSA9ICgoc3F1YXJlQiAtIHNxdWFyZUEpICogTWF0aC5wb3coTWF0aC5zaW4odCksIDMpKSAvIGI7XG4gICAgICAgICAgICB2YXIgcngxID0gbmVhcmVzdFggLSBleDtcbiAgICAgICAgICAgIHZhciByeTEgPSBuZWFyZXN0WSAtIGV5O1xuICAgICAgICAgICAgdmFyIHF4ID0gcHggLSBleDtcbiAgICAgICAgICAgIHZhciBxeSA9IHB5IC0gZXk7XG4gICAgICAgICAgICB2YXIgciA9IE1hdGguaHlwb3QocnkxLCByeDEpO1xuICAgICAgICAgICAgdmFyIHEgPSBNYXRoLmh5cG90KHF5LCBxeCk7XG4gICAgICAgICAgICB2YXIgZGVsdGFfYyA9IHIgKiBNYXRoLmFzaW4oKHJ4MSAqIHF5IC0gcnkxICogcXgpIC8gKHIgKiBxKSk7XG4gICAgICAgICAgICB2YXIgZGVsdGFfdCA9IGRlbHRhX2MgLyBNYXRoLnNxcnQoc3F1YXJlQSArIHNxdWFyZUIgLSBuZWFyZXN0WCAqIG5lYXJlc3RYIC0gbmVhcmVzdFkgKiBuZWFyZXN0WSk7XG4gICAgICAgICAgICB0ICs9IGRlbHRhX3Q7XG4gICAgICAgICAgICB0ID0gTWF0aC5taW4oTWF0aC5QSSAvIDIsIE1hdGgubWF4KDAsIHQpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCArIGNvcHlzaWduKG5lYXJlc3RYLCByZWxhdGl2ZVgpLFxuICAgICAgICAgICAgeTogeSArIGNvcHlzaWduKG5lYXJlc3RZLCByZWxhdGl2ZVkpLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog54K55Yiw5qSt5ZyG5pyA6L+R55qE6Led56a7XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHggIOakreWchuS4reW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkgIOakreWchuS4reW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4IOakreWchiB4IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSDmpK3lnIYgeSDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geDAgIOaMh+WumueahOeCuSB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkwICDmjIflrprnmoTngrkgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g54K55Yiw5qSt5ZyG55qE6Led56a7XG4gICAgICovXG4gICAgcG9pbnREaXN0YW5jZTogZnVuY3Rpb24gKHgsIHksIHJ4LCByeSwgeDAsIHkwKSB7XG4gICAgICAgIHZhciBuZWFyZXN0UG9pbnQgPSB0aGlzLm5lYXJlc3RQb2ludCh4LCB5LCByeCwgcnksIHgwLCB5MCk7XG4gICAgICAgIHJldHVybiBkaXN0YW5jZShuZWFyZXN0UG9pbnQueCwgbmVhcmVzdFBvaW50LnksIHgwLCB5MCk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDmoLnmja7mr5Tkvovojrflj5bngrlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geCDmpK3lnIbkuK3lv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5IOakreWchuS4reW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4IOakreWchiB4IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSDmpK3lnIYgeSDmlrnlkJHljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdCDmjIflrprmr5TkvovvvIx46L205pa55ZCR5Li6IDBcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOeCuVxuICAgICAqL1xuICAgIHBvaW50QXQ6IGZ1bmN0aW9uICh4LCB5LCByeCwgcnksIHQpIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gMiAqIE1hdGguUEkgKiB0OyAvLyDmjInnhafop5Lluqbov5vooYzorqHnrpfvvIzogIzkuI3mjInnhaflkajplb/orqHnrpdcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHggKyByeCAqIE1hdGguY29zKGFuZ2xlKSxcbiAgICAgICAgICAgIHk6IHkgKyByeSAqIE1hdGguc2luKGFuZ2xlKSxcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOagueaNruavlOS+i+iuoeeul+WIh+e6v+inkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4IOakreWchuS4reW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkg5qSt5ZyG5Lit5b+DIHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcngg5qSt5ZyGIHgg5pa55ZCR5Y2K5b6EXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ5IOakreWchiB5IOaWueWQkeWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0IOaMh+WumuavlOS+iyAwIC0gMSDkuYvpl7TvvIx46L205pa55ZCR5Li6IDDjgILlnKggMC0xIOiMg+WbtOS5i+WkluaYr+W+queOr+i/mOaYr+i/lOWbniBudWxs77yM6L+Y6ZyA6KaB6LCD5pW0XG4gICAgICogQHJldHVybiB7bnVtYmVyfSDop5LluqbvvIzlnKggMCAtIDJQSSDkuYvpl7RcbiAgICAgKi9cbiAgICB0YW5nZW50QW5nbGU6IGZ1bmN0aW9uICh4LCB5LCByeCwgcnksIHQpIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gMiAqIE1hdGguUEkgKiB0OyAvLyDmjInnhafop5Lluqbov5vooYzorqHnrpfvvIzogIzkuI3mjInnhaflkajplb/orqHnrpdcbiAgICAgICAgLy8g55u05o6l5L2/55SoIHgseSDnmoTlr7zmlbDorqHnrpfvvIwgeCcgPSAtcnggKiBzaW4odCk7IHknID0gcnkgKiBjb3ModCk7XG4gICAgICAgIHZhciB0YW5nZW50QW5nbGUgPSBNYXRoLmF0YW4yKHJ5ICogTWF0aC5jb3MoYW5nbGUpLCAtcnggKiBNYXRoLnNpbihhbmdsZSkpO1xuICAgICAgICAvLyDkuZ/lj6/ku6Xkvb/nlKjmjIflrprngrnnmoTliIfnur/mlrnnqIvorqHnrpfvvIzmiJDmnKzmnInkupvpq5hcbiAgICAgICAgLy8gY29uc3QgcG9pbnQgPSB0aGlzLnBvaW50QXQoMCwgMCwgcngsIHJ5LCB0KTsgLy8g5qSt5ZyG55qE5YiH57q/5ZCM5qSt5ZyG55qE5Lit5b+D5LiN55u45YWzXG4gICAgICAgIC8vIGxldCB0YW5nZW50QW5nbGUgPSAtMSAqIE1hdGguYXRhbigocnkgKiByeSAqIHBvaW50LngpIC8gKHJ4ICogcnggKiBwb2ludC55KSk7XG4gICAgICAgIC8vIGlmIChhbmdsZSA+PSAwICYmIGFuZ2xlIDw9IE1hdGguUEkpIHtcbiAgICAgICAgLy8gICB0YW5nZW50QW5nbGUgKz0gTWF0aC5QSTtcbiAgICAgICAgLy8gfVxuICAgICAgICByZXR1cm4gcGlNb2QodGFuZ2VudEFuZ2xlKTtcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVsbGlwc2UuanMubWFwIiwiaW1wb3J0IHsgZGlzdGFuY2UsIHBpTW9kIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCBlbGxpcHNlIGZyb20gJy4vZWxsaXBzZSc7XG4vLyDlgY/lr7zmlbAgeFxuZnVuY3Rpb24gZGVyaXZhdGl2ZVhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW5nbGUpIHtcbiAgICByZXR1cm4gLTEgKiByeCAqIE1hdGguY29zKHhSb3RhdGlvbikgKiBNYXRoLnNpbihhbmdsZSkgLSByeSAqIE1hdGguc2luKHhSb3RhdGlvbikgKiBNYXRoLmNvcyhhbmdsZSk7XG59XG4vLyDlgY/lr7zmlbAgeVxuZnVuY3Rpb24gZGVyaXZhdGl2ZVlBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW5nbGUpIHtcbiAgICByZXR1cm4gLTEgKiByeCAqIE1hdGguc2luKHhSb3RhdGlvbikgKiBNYXRoLnNpbihhbmdsZSkgKyByeSAqIE1hdGguY29zKHhSb3RhdGlvbikgKiBNYXRoLmNvcyhhbmdsZSk7XG59XG4vLyB4IOeahOaegeWAvFxuZnVuY3Rpb24geEV4dHJlbWEocngsIHJ5LCB4Um90YXRpb24pIHtcbiAgICByZXR1cm4gTWF0aC5hdGFuKCgtcnkgLyByeCkgKiBNYXRoLnRhbih4Um90YXRpb24pKTtcbn1cbi8vIHkg55qE5p6B5YC8XG5mdW5jdGlvbiB5RXh0cmVtYShyeCwgcnksIHhSb3RhdGlvbikge1xuICAgIHJldHVybiBNYXRoLmF0YW4ocnkgLyAocnggKiBNYXRoLnRhbih4Um90YXRpb24pKSk7XG59XG4vLyDmoLnmja7op5LluqbmsYIgeCDlnZDmoIdcbmZ1bmN0aW9uIHhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBhbmdsZSkge1xuICAgIHJldHVybiByeCAqIE1hdGguY29zKHhSb3RhdGlvbikgKiBNYXRoLmNvcyhhbmdsZSkgLSByeSAqIE1hdGguc2luKHhSb3RhdGlvbikgKiBNYXRoLnNpbihhbmdsZSkgKyBjeDtcbn1cbi8vIOagueaNruinkuW6puaxgiB5IOWdkOagh1xuZnVuY3Rpb24geUF0KGN4LCBjeSwgcngsIHJ5LCB4Um90YXRpb24sIGFuZ2xlKSB7XG4gICAgcmV0dXJuIHJ4ICogTWF0aC5zaW4oeFJvdGF0aW9uKSAqIE1hdGguY29zKGFuZ2xlKSArIHJ5ICogTWF0aC5jb3MoeFJvdGF0aW9uKSAqIE1hdGguc2luKGFuZ2xlKSArIGN5O1xufVxuLy8g6I635Y+W54K55Zyo5qSt5ZyG5LiK55qE6KeS5bqmXG5mdW5jdGlvbiBnZXRBbmdsZShyeCwgcnksIHgwLCB5MCkge1xuICAgIHZhciBhbmdsZSA9IE1hdGguYXRhbjIoeTAgKiByeCwgeDAgKiByeSk7XG4gICAgLy8g6L2s5o2i5YiwIDAgLSAyUEkg5YaFXG4gICAgcmV0dXJuIChhbmdsZSArIE1hdGguUEkgKiAyKSAlIChNYXRoLlBJICogMik7XG59XG4vLyDmoLnmja7op5Lluqbojrflj5bvvIx4LHlcbmZ1bmN0aW9uIGdldFBvaW50KHJ4LCByeSwgYW5nbGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiByeCAqIE1hdGguY29zKGFuZ2xlKSxcbiAgICAgICAgeTogcnkgKiBNYXRoLnNpbihhbmdsZSksXG4gICAgfTtcbn1cbi8vIOaXi+i9rFxuZnVuY3Rpb24gcm90YXRlKHgsIHksIGFuZ2xlKSB7XG4gICAgdmFyIGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICB2YXIgc2luID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgIHJldHVybiBbeCAqIGNvcyAtIHkgKiBzaW4sIHggKiBzaW4gKyB5ICogY29zXTtcbn1cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICAvKipcbiAgICAgKiDorqHnrpfljIXlm7Tnm5JcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY3ggICAgICAgICDlnIblv4MgeFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjeSAgICAgICAgIOWchuW/gyB5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ4ICAgICAgICAgeCDovbTmlrnlkJHnmoTljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnkgICAgICAgICB5IOi9tOaWueWQkeeahOWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4Um90YXRpb24gIOaXi+i9rOinkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydEFuZ2xlIOi1t+Wni+inkuW6plxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRBbmdsZSAgIOe7k+adn+inkuW6plxuICAgICAqIEByZXR1cm4ge29iamVjdH0g5YyF5Zu055uS5a+56LGhXG4gICAgICovXG4gICAgYm94OiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUpIHtcbiAgICAgICAgdmFyIHhEaW0gPSB4RXh0cmVtYShyeCwgcnksIHhSb3RhdGlvbik7XG4gICAgICAgIHZhciBtaW5YID0gSW5maW5pdHk7XG4gICAgICAgIHZhciBtYXhYID0gLUluZmluaXR5O1xuICAgICAgICB2YXIgeHMgPSBbc3RhcnRBbmdsZSwgZW5kQW5nbGVdO1xuICAgICAgICBmb3IgKHZhciBpID0gLU1hdGguUEkgKiAyOyBpIDw9IE1hdGguUEkgKiAyOyBpICs9IE1hdGguUEkpIHtcbiAgICAgICAgICAgIHZhciB4QW5nbGUgPSB4RGltICsgaTtcbiAgICAgICAgICAgIGlmIChzdGFydEFuZ2xlIDwgZW5kQW5nbGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnRBbmdsZSA8IHhBbmdsZSAmJiB4QW5nbGUgPCBlbmRBbmdsZSkge1xuICAgICAgICAgICAgICAgICAgICB4cy5wdXNoKHhBbmdsZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGVuZEFuZ2xlIDwgeEFuZ2xlICYmIHhBbmdsZSA8IHN0YXJ0QW5nbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgeHMucHVzaCh4QW5nbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgeCA9IHhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCB4c1tpXSk7XG4gICAgICAgICAgICBpZiAoeCA8IG1pblgpIHtcbiAgICAgICAgICAgICAgICBtaW5YID0geDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh4ID4gbWF4WCkge1xuICAgICAgICAgICAgICAgIG1heFggPSB4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciB5RGltID0geUV4dHJlbWEocngsIHJ5LCB4Um90YXRpb24pO1xuICAgICAgICB2YXIgbWluWSA9IEluZmluaXR5O1xuICAgICAgICB2YXIgbWF4WSA9IC1JbmZpbml0eTtcbiAgICAgICAgdmFyIHlzID0gW3N0YXJ0QW5nbGUsIGVuZEFuZ2xlXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IC1NYXRoLlBJICogMjsgaSA8PSBNYXRoLlBJICogMjsgaSArPSBNYXRoLlBJKSB7XG4gICAgICAgICAgICB2YXIgeUFuZ2xlID0geURpbSArIGk7XG4gICAgICAgICAgICBpZiAoc3RhcnRBbmdsZSA8IGVuZEFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0QW5nbGUgPCB5QW5nbGUgJiYgeUFuZ2xlIDwgZW5kQW5nbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgeXMucHVzaCh5QW5nbGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChlbmRBbmdsZSA8IHlBbmdsZSAmJiB5QW5nbGUgPCBzdGFydEFuZ2xlKSB7XG4gICAgICAgICAgICAgICAgICAgIHlzLnB1c2goeUFuZ2xlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHkgPSB5QXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgeXNbaV0pO1xuICAgICAgICAgICAgaWYgKHkgPCBtaW5ZKSB7XG4gICAgICAgICAgICAgICAgbWluWSA9IHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeSA+IG1heFkpIHtcbiAgICAgICAgICAgICAgICBtYXhZID0geTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogbWluWCxcbiAgICAgICAgICAgIHk6IG1pblksXG4gICAgICAgICAgICB3aWR0aDogbWF4WCAtIG1pblgsXG4gICAgICAgICAgICBoZWlnaHQ6IG1heFkgLSBtaW5ZLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog6I635Y+W5ZyG5byn55qE6ZW/5bqm77yM6K6h566X5ZyG5byn6ZW/5bqm5pe25LiN6ICD6JmR5peL6L2s6KeS5bqm77yMXG4gICAgICog5LuF6LefIHJ4LCByeSwgc3RhcnRBbmdsZSwgZW5kQW5nbGUg55u45YWzXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGN4ICAgICAgICAg5ZyG5b+DIHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY3kgICAgICAgICDlnIblv4MgeVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeCAgICAgICAgIHgg6L205pa55ZCR55qE5Y2K5b6EXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJ5ICAgICAgICAgeSDovbTmlrnlkJHnmoTljYrlvoRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geFJvdGF0aW9uICDml4vovazop5LluqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRBbmdsZSDotbflp4vop5LluqZcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kQW5nbGUgICDnu5PmnZ/op5LluqZcbiAgICAgKi9cbiAgICBsZW5ndGg6IGZ1bmN0aW9uIChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSkgeyB9LFxuICAgIC8qKlxuICAgICAqIOiOt+WPluaMh+WumueCueWIsOWchuW8p+eahOacgOi/kei3neemu+eahOeCuVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjeCAgICAgICAgIOWchuW/gyB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGN5ICAgICAgICAg5ZyG5b+DIHlcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcnggICAgICAgICB4IOi9tOaWueWQkeeahOWNiuW+hFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByeSAgICAgICAgIHkg6L205pa55ZCR55qE5Y2K5b6EXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHhSb3RhdGlvbiAg5peL6L2s6KeS5bqmXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0QW5nbGUg6LW35aeL6KeS5bqmXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZEFuZ2xlICAg57uT5p2f6KeS5bqmXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgwICAgICAgICAg5oyH5a6a54K555qEIHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geTAgICAgICAgICDmjIflrprngrnnmoQgeVxuICAgICAqIEByZXR1cm4ge29iamVjdH0g5Yiw5oyH5a6a54K55pyA6L+R6Led56a755qE54K5XG4gICAgICovXG4gICAgbmVhcmVzdFBvaW50OiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHgwLCB5MCkge1xuICAgICAgICAvLyDlsIbmnIDov5Hot53nprvpl67popjovazmjaLmiJDliLDmpK3lnIbkuK3lv4MgMCwwIOayoeacieaXi+i9rOeahOakreWchumXrumimFxuICAgICAgICB2YXIgcmVsYXRpdmVWZWN0b3IgPSByb3RhdGUoeDAgLSBjeCwgeTAgLSBjeSwgLXhSb3RhdGlvbik7XG4gICAgICAgIHZhciB4MSA9IHJlbGF0aXZlVmVjdG9yWzBdLCB5MSA9IHJlbGF0aXZlVmVjdG9yWzFdO1xuICAgICAgICAvLyDorqHnrpfngrnliLDmpK3lnIbnmoTmnIDov5HnmoTngrlcbiAgICAgICAgdmFyIHJlbGF0aXZlUG9pbnQgPSBlbGxpcHNlLm5lYXJlc3RQb2ludCgwLCAwLCByeCwgcnksIHgxLCB5MSk7XG4gICAgICAgIC8vIOiOt+WPlueCueWcqOakreWchuS4iueahOinkuW6plxuICAgICAgICB2YXIgYW5nbGUgPSBnZXRBbmdsZShyeCwgcnksIHJlbGF0aXZlUG9pbnQueCwgcmVsYXRpdmVQb2ludC55KTtcbiAgICAgICAgLy8g54K55rKh5pyJ5Zyo5ZyG5byn5LiKXG4gICAgICAgIGlmIChhbmdsZSA8IHN0YXJ0QW5nbGUpIHtcbiAgICAgICAgICAgIC8vIOWwj+S6jui1t+Wni+WchuW8p1xuICAgICAgICAgICAgcmVsYXRpdmVQb2ludCA9IGdldFBvaW50KHJ4LCByeSwgc3RhcnRBbmdsZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYW5nbGUgPiBlbmRBbmdsZSkge1xuICAgICAgICAgICAgLy8g5aSn5LqO57uT5p2f5ZyG5bynXG4gICAgICAgICAgICByZWxhdGl2ZVBvaW50ID0gZ2V0UG9pbnQocngsIHJ5LCBlbmRBbmdsZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5peL6L2s5YiwIHhSb3RhdGlvbiDnmoTop5LluqZcbiAgICAgICAgdmFyIHZlY3RvciA9IHJvdGF0ZShyZWxhdGl2ZVBvaW50LngsIHJlbGF0aXZlUG9pbnQueSwgeFJvdGF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHZlY3RvclswXSArIGN4LFxuICAgICAgICAgICAgeTogdmVjdG9yWzFdICsgY3ksXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBwb2ludERpc3RhbmNlOiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHgwLCB5MCkge1xuICAgICAgICB2YXIgbmVhcmVzdFBvaW50ID0gdGhpcy5uZWFyZXN0UG9pbnQoY3gsIGN5LCByeCwgcnksIHgwLCB5MCk7XG4gICAgICAgIHJldHVybiBkaXN0YW5jZShuZWFyZXN0UG9pbnQueCwgbmVhcmVzdFBvaW50LnksIHgwLCB5MCk7XG4gICAgfSxcbiAgICBwb2ludEF0OiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHQpIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSkgKiB0ICsgc3RhcnRBbmdsZTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBhbmdsZSksXG4gICAgICAgICAgICB5OiB5QXQoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgYW5nbGUpLFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgdGFuZ2VudEFuZ2xlOiBmdW5jdGlvbiAoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIHQpIHtcbiAgICAgICAgdmFyIGFuZ2xlID0gKGVuZEFuZ2xlIC0gc3RhcnRBbmdsZSkgKiB0ICsgc3RhcnRBbmdsZTtcbiAgICAgICAgdmFyIGR4ID0gZGVyaXZhdGl2ZVhBdChjeCwgY3ksIHJ4LCByeSwgeFJvdGF0aW9uLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYW5nbGUpO1xuICAgICAgICB2YXIgZHkgPSBkZXJpdmF0aXZlWUF0KGN4LCBjeSwgcngsIHJ5LCB4Um90YXRpb24sIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBhbmdsZSk7XG4gICAgICAgIHJldHVybiBwaU1vZChNYXRoLmF0YW4yKGR5LCBkeCkpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXJjLmpzLm1hcCIsImltcG9ydCBsaW5lIGZyb20gJy4vbGluZSc7XG5pbXBvcnQgeyBkaXN0YW5jZSB9IGZyb20gJy4vdXRpbCc7XG5mdW5jdGlvbiBhbmFseXplUG9pbnRzKHBvaW50cykge1xuICAgIC8vIOiuoeeul+avj+auteeahOmVv+W6puWSjOaAu+eahOmVv+W6plxuICAgIHZhciB0b3RhbExlbmd0aCA9IDA7XG4gICAgdmFyIHNlZ21lbnRzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIHZhciBmcm9tID0gcG9pbnRzW2ldO1xuICAgICAgICB2YXIgdG8gPSBwb2ludHNbaSArIDFdO1xuICAgICAgICB2YXIgbGVuZ3RoXzEgPSBkaXN0YW5jZShmcm9tWzBdLCBmcm9tWzFdLCB0b1swXSwgdG9bMV0pO1xuICAgICAgICB2YXIgc2VnID0ge1xuICAgICAgICAgICAgZnJvbTogZnJvbSxcbiAgICAgICAgICAgIHRvOiB0byxcbiAgICAgICAgICAgIGxlbmd0aDogbGVuZ3RoXzEsXG4gICAgICAgIH07XG4gICAgICAgIHNlZ21lbnRzLnB1c2goc2VnKTtcbiAgICAgICAgdG90YWxMZW5ndGggKz0gbGVuZ3RoXzE7XG4gICAgfVxuICAgIHJldHVybiB7IHNlZ21lbnRzOiBzZWdtZW50cywgdG90YWxMZW5ndGg6IHRvdGFsTGVuZ3RoIH07XG59XG5leHBvcnQgZnVuY3Rpb24gbGVuZ3RoT2ZTZWdtZW50KHBvaW50cykge1xuICAgIGlmIChwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgdmFyIHRvdGFsTGVuZ3RoID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgdmFyIGZyb20gPSBwb2ludHNbaV07XG4gICAgICAgIHZhciB0byA9IHBvaW50c1tpICsgMV07XG4gICAgICAgIHRvdGFsTGVuZ3RoICs9IGRpc3RhbmNlKGZyb21bMF0sIGZyb21bMV0sIHRvWzBdLCB0b1sxXSk7XG4gICAgfVxuICAgIHJldHVybiB0b3RhbExlbmd0aDtcbn1cbi8qKlxuICog5oyJ54Wn5q+U5L6L5Zyo5pWw5o2u54mH5q615Lit6I635Y+W54K5XG4gKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIXG4gKiBAcGFyYW0ge251bWJlcn0gdCDnmb7liIbmr5QgMC0xXG4gKiBAcmV0dXJuIHtvYmplY3R9IOeCueeahOWdkOagh1xuICovXG5leHBvcnQgZnVuY3Rpb24gcG9pbnRBdFNlZ21lbnRzKHBvaW50cywgdCkge1xuICAgIC8vIOi+ueeVjOWIpOaWrVxuICAgIGlmICh0ID4gMSB8fCB0IDwgMCB8fCBwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIF9hID0gYW5hbHl6ZVBvaW50cyhwb2ludHMpLCBzZWdtZW50cyA9IF9hLnNlZ21lbnRzLCB0b3RhbExlbmd0aCA9IF9hLnRvdGFsTGVuZ3RoO1xuICAgIC8vIOWkmuS4queCueacieWPr+iDvemHjeWQiFxuICAgIGlmICh0b3RhbExlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogcG9pbnRzWzBdWzBdLFxuICAgICAgICAgICAgeTogcG9pbnRzWzBdWzFdLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyDorqHnrpfmr5TkvotcbiAgICB2YXIgc3RhcnRSYXRpbyA9IDA7XG4gICAgdmFyIHBvaW50ID0gbnVsbDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzZWcgPSBzZWdtZW50c1tpXTtcbiAgICAgICAgdmFyIGZyb20gPSBzZWcuZnJvbSwgdG8gPSBzZWcudG87XG4gICAgICAgIHZhciBjdXJyZW50UmF0aW8gPSBzZWcubGVuZ3RoIC8gdG90YWxMZW5ndGg7XG4gICAgICAgIGlmICh0ID49IHN0YXJ0UmF0aW8gJiYgdCA8PSBzdGFydFJhdGlvICsgY3VycmVudFJhdGlvKSB7XG4gICAgICAgICAgICB2YXIgbG9jYWxSYXRpbyA9ICh0IC0gc3RhcnRSYXRpbykgLyBjdXJyZW50UmF0aW87XG4gICAgICAgICAgICBwb2ludCA9IGxpbmUucG9pbnRBdChmcm9tWzBdLCBmcm9tWzFdLCB0b1swXSwgdG9bMV0sIGxvY2FsUmF0aW8pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSYXRpbyArPSBjdXJyZW50UmF0aW87XG4gICAgfVxuICAgIHJldHVybiBwb2ludDtcbn1cbi8qKlxuICog5oyJ54Wn5q+U5L6L5Zyo5pWw5o2u54mH5q615Lit6I635Y+W5YiH57q/55qE6KeS5bqmXG4gKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIXG4gKiBAcGFyYW0ge251bWJlcn0gdCDnmb7liIbmr5QgMC0xXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmdsZUF0U2VnbWVudHMocG9pbnRzLCB0KSB7XG4gICAgLy8g6L6555WM5Yik5patXG4gICAgaWYgKHQgPiAxIHx8IHQgPCAwIHx8IHBvaW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICB2YXIgX2EgPSBhbmFseXplUG9pbnRzKHBvaW50cyksIHNlZ21lbnRzID0gX2Euc2VnbWVudHMsIHRvdGFsTGVuZ3RoID0gX2EudG90YWxMZW5ndGg7XG4gICAgLy8g6K6h566X5q+U5L6LXG4gICAgdmFyIHN0YXJ0UmF0aW8gPSAwO1xuICAgIHZhciBhbmdsZSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VnID0gc2VnbWVudHNbaV07XG4gICAgICAgIHZhciBmcm9tID0gc2VnLmZyb20sIHRvID0gc2VnLnRvO1xuICAgICAgICB2YXIgY3VycmVudFJhdGlvID0gc2VnLmxlbmd0aCAvIHRvdGFsTGVuZ3RoO1xuICAgICAgICBpZiAodCA+PSBzdGFydFJhdGlvICYmIHQgPD0gc3RhcnRSYXRpbyArIGN1cnJlbnRSYXRpbykge1xuICAgICAgICAgICAgYW5nbGUgPSBNYXRoLmF0YW4yKHRvWzFdIC0gZnJvbVsxXSwgdG9bMF0gLSBmcm9tWzBdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UmF0aW8gKz0gY3VycmVudFJhdGlvO1xuICAgIH1cbiAgICByZXR1cm4gYW5nbGU7XG59XG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2VBdFNlZ21lbnQocG9pbnRzLCB4LCB5KSB7XG4gICAgdmFyIG1pbkRpc3RhbmNlID0gSW5maW5pdHk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgdmFyIG5leHRQb2ludCA9IHBvaW50c1tpICsgMV07XG4gICAgICAgIHZhciBkaXN0YW5jZV8xID0gbGluZS5wb2ludERpc3RhbmNlKHBvaW50WzBdLCBwb2ludFsxXSwgbmV4dFBvaW50WzBdLCBuZXh0UG9pbnRbMV0sIHgsIHkpO1xuICAgICAgICBpZiAoZGlzdGFuY2VfMSA8IG1pbkRpc3RhbmNlKSB7XG4gICAgICAgICAgICBtaW5EaXN0YW5jZSA9IGRpc3RhbmNlXzE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1pbkRpc3RhbmNlO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VnbWVudHMuanMubWFwIiwiaW1wb3J0IHsgcG9pbnRBdFNlZ21lbnRzLCBhbmdsZUF0U2VnbWVudHMsIGRpc3RhbmNlQXRTZWdtZW50LCBsZW5ndGhPZlNlZ21lbnQgfSBmcm9tICcuL3NlZ21lbnRzJztcbmltcG9ydCB7IGdldEJCb3hCeUFycmF5IH0gZnJvbSAnLi91dGlsJztcbmV4cG9ydCBkZWZhdWx0IHtcbiAgICAvKipcbiAgICAgKiDorqHnrpflpJrmipjnur/nmoTljIXlm7Tnm5JcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIIFt4LHldIOeahOW9ouW8j1xuICAgICAqIEByZXR1cm4ge29iamVjdH0g5YyF5Zu055uSXG4gICAgICovXG4gICAgYm94OiBmdW5jdGlvbiAocG9pbnRzKSB7XG4gICAgICAgIHZhciB4QXJyID0gW107XG4gICAgICAgIHZhciB5QXJyID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgICAgICB4QXJyLnB1c2gocG9pbnRbMF0pO1xuICAgICAgICAgICAgeUFyci5wdXNoKHBvaW50WzFdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2V0QkJveEJ5QXJyYXkoeEFyciwgeUFycik7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDorqHnrpflpJrmipjnur/nmoTplb/luqZcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIIFt4LHldIOeahOW9ouW8j1xuICAgICAqIEByZXR1cm4ge29iamVjdH0g5aSa5p2h6L6555qE6ZW/5bqmXG4gICAgICovXG4gICAgbGVuZ3RoOiBmdW5jdGlvbiAocG9pbnRzKSB7XG4gICAgICAgIHJldHVybiBsZW5ndGhPZlNlZ21lbnQocG9pbnRzKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOagueaNruavlOS+i+iOt+WPluWkmuaKmOe6v+eahOeCuVxuICAgICAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIggW3gseV0g55qE5b2i5byPXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5Zyo5aSa5oqY57q/55qE6ZW/5bqm5LiK55qE5q+U5L6LXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDmoLnmja7mr5TkvovlgLzorqHnrpflh7rmnaXnmoTngrlcbiAgICAgKi9cbiAgICBwb2ludEF0OiBmdW5jdGlvbiAocG9pbnRzLCB0KSB7XG4gICAgICAgIHJldHVybiBwb2ludEF0U2VnbWVudHMocG9pbnRzLCB0KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOaMh+WumueCueWIsOWkmuaKmOe6v+eahOi3neemu1xuICAgICAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIggW3gseV0g55qE5b2i5byPXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHgg5oyH5a6a54K555qEIHhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geSDmjIflrprngrnnmoQgeVxuICAgICAqIEByZXR1cm4ge251bWJlcn0g54K55Yiw5aSa5oqY57q/55qE6Led56a7XG4gICAgICovXG4gICAgcG9pbnREaXN0YW5jZTogZnVuY3Rpb24gKHBvaW50cywgeCwgeSkge1xuICAgICAgICByZXR1cm4gZGlzdGFuY2VBdFNlZ21lbnQocG9pbnRzLCB4LCB5KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOagueaNruavlOS+i+iOt+WPluWkmuaKmOe6v+eahOWIh+e6v+inkuW6plxuICAgICAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIggW3gseV0g55qE5b2i5byPXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5Zyo5aSa5oqY57q/55qE6ZW/5bqm5LiK55qE5q+U5L6LXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDmoLnmja7mr5TkvovlgLzorqHnrpflh7rmnaXnmoTop5LluqZcbiAgICAgKi9cbiAgICB0YW5nZW50QW5nbGU6IGZ1bmN0aW9uIChwb2ludHMsIHQpIHtcbiAgICAgICAgcmV0dXJuIGFuZ2xlQXRTZWdtZW50cyhwb2ludHMsIHQpO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cG9seWxpbmUuanMubWFwIiwiaW1wb3J0IHsgcG9pbnRBdFNlZ21lbnRzLCBhbmdsZUF0U2VnbWVudHMsIGRpc3RhbmNlQXRTZWdtZW50LCBsZW5ndGhPZlNlZ21lbnQgfSBmcm9tICcuL3NlZ21lbnRzJztcbmltcG9ydCBwb2x5bGluZSBmcm9tICcuL3BvbHlsaW5lJztcbmZ1bmN0aW9uIGdldEFsbFBvaW50cyhwb2ludHMpIHtcbiAgICB2YXIgdG1wID0gcG9pbnRzLnNsaWNlKDApO1xuICAgIGlmIChwb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIHRtcC5wdXNoKHBvaW50c1swXSk7XG4gICAgfVxuICAgIHJldHVybiB0bXA7XG59XG5leHBvcnQgZGVmYXVsdCB7XG4gICAgLyoqXG4gICAgICog6K6h566X5aSa6L655b2i55qE5YyF5Zu055uSXG4gICAgICogQHBhcmFtIHthcnJheX0gcG9pbnRzIOeCueeahOmbhuWQiCBbeCx5XSDnmoTlvaLlvI9cbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOWMheWbtOebklxuICAgICAqL1xuICAgIGJveDogZnVuY3Rpb24gKHBvaW50cykge1xuICAgICAgICByZXR1cm4gcG9seWxpbmUuYm94KHBvaW50cyk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDorqHnrpflpJrovrnlvaLnmoTplb/luqZcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIIFt4LHldIOeahOW9ouW8j1xuICAgICAqIEByZXR1cm4ge29iamVjdH0g5aSa6L655b2i6L6555qE6ZW/5bqmXG4gICAgICovXG4gICAgbGVuZ3RoOiBmdW5jdGlvbiAocG9pbnRzKSB7XG4gICAgICAgIHJldHVybiBsZW5ndGhPZlNlZ21lbnQoZ2V0QWxsUG9pbnRzKHBvaW50cykpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5q+U5L6L6I635Y+W5aSa6L655b2i55qE54K5XG4gICAgICogQHBhcmFtIHthcnJheX0gcG9pbnRzIOeCueeahOmbhuWQiCBbeCx5XSDnmoTlvaLlvI9cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdCDlnKjlpJrovrnlvaLnmoTplb/luqbkuIrnmoTmr5TkvotcbiAgICAgKiBAcmV0dXJuIHtvYmplY3R9IOagueaNruavlOS+i+WAvOiuoeeul+WHuuadpeeahOeCuVxuICAgICAqL1xuICAgIHBvaW50QXQ6IGZ1bmN0aW9uIChwb2ludHMsIHQpIHtcbiAgICAgICAgcmV0dXJuIHBvaW50QXRTZWdtZW50cyhnZXRBbGxQb2ludHMocG9pbnRzKSwgdCk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDmjIflrprngrnliLDlpJrovrnlvaLnmoTot53nprtcbiAgICAgKiBAcGFyYW0ge2FycmF5fSBwb2ludHMg54K555qE6ZuG5ZCIIFt4LHldIOeahOW9ouW8j1xuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4IOaMh+WumueCueeahCB4XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHkg5oyH5a6a54K555qEIHlcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IOeCueWIsOWkmui+ueW9oueahOi3neemu1xuICAgICAqL1xuICAgIHBvaW50RGlzdGFuY2U6IGZ1bmN0aW9uIChwb2ludHMsIHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIGRpc3RhbmNlQXRTZWdtZW50KGdldEFsbFBvaW50cyhwb2ludHMpLCB4LCB5KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOagueaNruavlOS+i+iOt+WPluWkmui+ueW9oueahOWIh+e6v+inkuW6plxuICAgICAqIEBwYXJhbSB7YXJyYXl9IHBvaW50cyDngrnnmoTpm4blkIggW3gseV0g55qE5b2i5byPXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHQg5Zyo5aSa6L655b2i55qE6ZW/5bqm5LiK55qE5q+U5L6LXG4gICAgICogQHJldHVybiB7b2JqZWN0fSDmoLnmja7mr5TkvovlgLzorqHnrpflh7rmnaXnmoTop5LluqZcbiAgICAgKi9cbiAgICB0YW5nZW50QW5nbGU6IGZ1bmN0aW9uIChwb2ludHMsIHQpIHtcbiAgICAgICAgcmV0dXJuIGFuZ2xlQXRTZWdtZW50cyhnZXRBbGxQb2ludHMocG9pbnRzKSwgdCk7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2x5Z29uLmpzLm1hcCIsImltcG9ydCBRdWFkIGZyb20gJy4vcXVhZHJhdGljJztcbmltcG9ydCBDdWJpYyBmcm9tICcuL2N1YmljJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IExpbmUgZnJvbSAnLi9saW5lJztcbmltcG9ydCBQb2x5Z29uIGZyb20gJy4vcG9seWdvbic7XG5pbXBvcnQgUG9seWxpbmUgZnJvbSAnLi9wb2x5bGluZSc7XG5pbXBvcnQgKiBhcyBVdGlsIGZyb20gJy4vdXRpbCc7XG5leHBvcnQgeyBRdWFkLCBDdWJpYywgQXJjLCBMaW5lLCBQb2x5Z29uLCBQb2x5bGluZSwgVXRpbCB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///20\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* unused harmony export version */\n/* harmony import */ var _util_path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52);\n/* harmony reexport (module object) */ __webpack_require__.d(__webpack_exports__, "PathUtil", function() { return _util_path__WEBPACK_IMPORTED_MODULE_0__; });\n/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(175);\n/* harmony import */ var _types__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_types__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _interfaces__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(176);\n/* harmony import */ var _interfaces__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_interfaces__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _event_graph_event__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(118);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Event", function() { return _event_graph_event__WEBPACK_IMPORTED_MODULE_3__["a"]; });\n\n/* harmony import */ var _abstract_base__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(119);\n/* harmony import */ var _abstract_canvas__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(275);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractCanvas", function() { return _abstract_canvas__WEBPACK_IMPORTED_MODULE_5__["a"]; });\n\n/* harmony import */ var _abstract_group__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(178);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractGroup", function() { return _abstract_group__WEBPACK_IMPORTED_MODULE_6__["a"]; });\n\n/* harmony import */ var _abstract_shape__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(179);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractShape", function() { return _abstract_shape__WEBPACK_IMPORTED_MODULE_7__["a"]; });\n\n/* harmony import */ var _bbox__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(276);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getBBoxMethod", function() { return _bbox__WEBPACK_IMPORTED_MODULE_8__["a"]; });\n\n/* harmony import */ var _util_text__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(69);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getTextHeight", function() { return _util_text__WEBPACK_IMPORTED_MODULE_9__["b"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "assembleFont", function() { return _util_text__WEBPACK_IMPORTED_MODULE_9__["a"]; });\n\n/* harmony import */ var _util_util__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(19);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isAllowCapture", function() { return _util_util__WEBPACK_IMPORTED_MODULE_10__["b"]; });\n\n/* harmony import */ var _util_matrix__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(38);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multiplyVec2", function() { return _util_matrix__WEBPACK_IMPORTED_MODULE_11__["c"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "invert", function() { return _util_matrix__WEBPACK_IMPORTED_MODULE_11__["a"]; });\n\n/* harmony import */ var _util_offscreen__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(120);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getOffScreenContext", function() { return _util_offscreen__WEBPACK_IMPORTED_MODULE_12__["a"]; });\n\n/**\n * @fileoverview G 的基础接口定义和所有的抽象类\n * @author dxq613@gmail.com\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar version = \'0.5.6\';\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2VzbS9pbmRleC5qcz82ODU1Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ3dDO0FBQ2hCO0FBQ0s7QUFDMEI7QUFDTDtBQUNZO0FBQ0Y7QUFDQTtBQUN4QztBQUNtQjtBQUNtQjtBQUNiO0FBQ1E7QUFDRTtBQUNoRDtBQUNQIiwiZmlsZSI6IjIxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IEcg55qE5Z+656GA5o6l5Y+j5a6a5LmJ5ZKM5omA5pyJ55qE5oq96LGh57G7XG4gKiBAYXV0aG9yIGR4cTYxM0BnbWFpbC5jb21cbiAqL1xuaW1wb3J0ICogYXMgUGF0aFV0aWwgZnJvbSAnLi91dGlsL3BhdGgnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL2ludGVyZmFjZXMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBFdmVudCB9IGZyb20gJy4vZXZlbnQvZ3JhcGgtZXZlbnQnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBCYXNlIH0gZnJvbSAnLi9hYnN0cmFjdC9iYXNlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgQWJzdHJhY3RDYW52YXMgfSBmcm9tICcuL2Fic3RyYWN0L2NhbnZhcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIEFic3RyYWN0R3JvdXAgfSBmcm9tICcuL2Fic3RyYWN0L2dyb3VwJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgQWJzdHJhY3RTaGFwZSB9IGZyb20gJy4vYWJzdHJhY3Qvc2hhcGUnO1xuZXhwb3J0IHsgUGF0aFV0aWwgfTtcbmV4cG9ydCB7IGdldEJCb3hNZXRob2QgfSBmcm9tICcuL2Jib3gnO1xuZXhwb3J0IHsgZ2V0VGV4dEhlaWdodCwgYXNzZW1ibGVGb250IH0gZnJvbSAnLi91dGlsL3RleHQnO1xuZXhwb3J0IHsgaXNBbGxvd0NhcHR1cmUgfSBmcm9tICcuL3V0aWwvdXRpbCc7XG5leHBvcnQgeyBtdWx0aXBseVZlYzIsIGludmVydCB9IGZyb20gJy4vdXRpbC9tYXRyaXgnO1xuZXhwb3J0IHsgZ2V0T2ZmU2NyZWVuQ29udGV4dCB9IGZyb20gJy4vdXRpbC9vZmZzY3JlZW4nO1xuZXhwb3J0IHZhciB2ZXJzaW9uID0gJzAuNS42Jztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///21\n')},function(module,exports){eval('function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called");\n }\n\n return self;\n}\n\nmodule.exports = _assertThisInitialized;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQuanM/M2M5NiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EiLCJmaWxlIjoiMjIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHtcbiAgaWYgKHNlbGYgPT09IHZvaWQgMCkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTtcbiAgfVxuXG4gIHJldHVybiBzZWxmO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQ7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///22\n')},function(module,exports,__webpack_require__){eval('var setPrototypeOf = __webpack_require__(528);\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== "function" && superClass !== null) {\n throw new TypeError("Super expression must either be null or a function");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}\n\nmodule.exports = _inherits;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0cy5qcz9lZDZkIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHFCQUFxQixtQkFBTyxDQUFDLEdBQXFCOztBQUVsRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBIiwiZmlsZSI6IjIzLmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZShcIi4vc2V0UHJvdG90eXBlT2YuanNcIik7XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykge1xuICBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpO1xuICB9XG5cbiAgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBzdWJDbGFzcyxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcbiAgaWYgKHN1cGVyQ2xhc3MpIHNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaW5oZXJpdHM7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///23\n')},function(module,exports,__webpack_require__){eval('var _typeof = __webpack_require__(41)["default"];\n\nvar assertThisInitialized = __webpack_require__(22);\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === "object" || typeof call === "function")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError("Derived constructors may only return object or undefined");\n }\n\n return assertThisInitialized(self);\n}\n\nmodule.exports = _possibleConstructorReturn;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuLmpzPzZiNTgiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxtQkFBTyxDQUFDLEVBQStCOztBQUVyRCw0QkFBNEIsbUJBQU8sQ0FBQyxFQUE0Qjs7QUFFaEU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBIiwiZmlsZSI6IjI0LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIF90eXBlb2YgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2ZcIilbXCJkZWZhdWx0XCJdO1xuXG52YXIgYXNzZXJ0VGhpc0luaXRpYWxpemVkID0gcmVxdWlyZShcIi4vYXNzZXJ0VGhpc0luaXRpYWxpemVkLmpzXCIpO1xuXG5mdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7XG4gIGlmIChjYWxsICYmIChfdHlwZW9mKGNhbGwpID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBjYWxsID09PSBcImZ1bmN0aW9uXCIpKSB7XG4gICAgcmV0dXJuIGNhbGw7XG4gIH0gZWxzZSBpZiAoY2FsbCAhPT0gdm9pZCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkRlcml2ZWQgY29uc3RydWN0b3JzIG1heSBvbmx5IHJldHVybiBvYmplY3Qgb3IgdW5kZWZpbmVkXCIpO1xuICB9XG5cbiAgcmV0dXJuIGFzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjtcbm1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///24\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Component; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return ComponentManager; });\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9);\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(15);\n/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);\n/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);\n/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _Entity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(121);\n\n\n\n\n\nvar Component = function Component(data) {//\n\n _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default()(this, Component);\n};\n/**\n * 管理某一类 Component,尽可能做到 AoS 而非 SoA\n * @see https://wickedengine.net/2019/09/29/entity-component-system/\n * @see https://github.com/turanszkij/WickedEngine/blob/master/WickedEngine/wiECS.h\n */\n// tslint:disable-next-line:max-classes-per-file\n\nvar ComponentManager = /*#__PURE__*/function () {\n /**\n * 不在 Entity 中维护拥有的 Component 列表,反之亦然\n */\n function ComponentManager(clazz) {\n _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_3___default()(this, ComponentManager);\n\n this.clazz = void 0;\n this.components = [];\n this.entities = [];\n this.lookup = {};\n this.clazz = clazz;\n }\n\n _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default()(ComponentManager, [{\n key: "clear",\n value: function clear() {\n this.components = [];\n this.entities = [];\n this.lookup = {};\n }\n }, {\n key: "contains",\n value: function contains(entity) {\n return this.lookup[entity] > -1;\n }\n }, {\n key: "create",\n value: function create(entity, data) {\n this.lookup[entity] = this.components.length;\n var component = new this.clazz(data || {});\n this.components.push(component);\n this.entities.push(entity);\n return component;\n }\n }, {\n key: "remove",\n value: function remove(entity) {\n var componentIndex = this.lookup[entity];\n\n if (componentIndex > -1) {\n if (componentIndex < this.components.length - 1) {\n // 将待删除元素和最后一个元素交换\n // C++ 中有 std::move 这样的操作,避免数据的拷贝\n // @see https://github.com/turanszkij/WickedEngine/blob/master/WickedEngine/wiECS.h#L169\n this.components[componentIndex] = this.components[this.components.length - 1];\n this.entities[componentIndex] = this.entities[this.entities.length - 1];\n this.lookup[this.entities[componentIndex]] = componentIndex;\n }\n } // 待删除元素已经移动到了最后一个\n\n\n this.components.pop();\n this.entities.pop();\n delete this.lookup[entity];\n }\n }, {\n key: "removeKeepSorted",\n value: function removeKeepSorted(entity) {\n var componentIndex = this.lookup[entity];\n\n if (componentIndex > -1) {\n var entity2 = this.entities[componentIndex];\n\n if (componentIndex < this.components.length - 1) {\n // Move every component left by one that is after this element:\n for (var _i = componentIndex + 1; _i < this.components.length; ++_i) {\n this.components[_i - 1] = this.components[_i];\n } // Move every entity left by one that is after this element and update lut:\n\n\n for (var _i2 = componentIndex + 1; _i2 < this.entities.length; ++_i2) {\n this.entities[_i2 - 1] = this.entities[_i2];\n this.lookup[this.entities[_i2 - 1]] = _i2 - 1;\n }\n }\n\n this.components.pop();\n this.entities.pop();\n delete this.lookup[entity2];\n }\n }\n }, {\n key: "moveItem",\n value: function moveItem(srcIndex, destIndex) {\n if (srcIndex === destIndex) {\n return;\n } // Save the moved component and entity:\n\n\n var srcComponent = this.components[srcIndex];\n var srcEntity = this.entities[srcIndex]; // Every other entity-component that\'s in the way gets moved by one and lut is kept updated:\n\n var direction = srcIndex < destIndex ? 1 : -1;\n\n for (var _i3 = srcIndex; _i3 !== destIndex; _i3 += direction) {\n var next = _i3 + direction;\n this.components[_i3] = this.components[next];\n this.entities[_i3] = this.entities[next];\n this.lookup[this.entities[_i3]] = _i3;\n } // Saved entity-component moved to the required position:\n\n\n this.components[destIndex] = srcComponent;\n this.entities[destIndex] = srcEntity;\n this.lookup[srcEntity] = destIndex;\n }\n }, {\n key: "getEntity",\n value: function getEntity(index) {\n return this.entities[index];\n }\n /**\n * 由于缺少类似 C++ 的重载操作符,没法通过 [下标] 直接访问。因此只能增加该方法用于遍历。\n */\n\n }, {\n key: "getComponent",\n value: function getComponent(index) {\n return this.components[index];\n }\n }, {\n key: "getComponentByEntity",\n value: function getComponentByEntity(entity) {\n var componentIndex = this.lookup[entity];\n\n if (componentIndex > -1) {\n return this.components[componentIndex];\n }\n\n return null;\n }\n }, {\n key: "getCount",\n value: function getCount() {\n return this.components.length;\n }\n }, {\n key: "getEntityByComponentIndex",\n value: function getEntityByComponentIndex(componentIdx) {\n for (var _i4 = 0, _Object$keys = Object.keys(this.lookup); _i4 < _Object$keys.length; _i4++) {\n var _entity = _Object$keys[_i4];\n var entityInNum = Number(_entity);\n\n if (this.lookup[entityInNum] === componentIdx) {\n return entityInNum;\n }\n }\n\n return _Entity__WEBPACK_IMPORTED_MODULE_4__[/* EMPTY */ "a"];\n }\n }, {\n key: "find",\n value: function find(callback) {\n for (var _i5 = 0; _i5 < this.getCount(); _i5++) {\n var _component = this.getComponent(_i5);\n\n if (callback(_component, _i5)) {\n return _component;\n }\n }\n\n return null;\n }\n }, {\n key: "findIndex",\n value: function findIndex(callback) {\n for (var _i6 = 0; _i6 < this.getCount(); _i6++) {\n var _component2 = this.getComponent(_i6);\n\n if (callback(_component2, _i6)) {\n return _i6;\n }\n }\n\n return -1;\n }\n }, {\n key: "forEach",\n value: function forEach(callback) {\n for (var _i7 = 0, _Object$keys2 = Object.keys(this.lookup); _i7 < _Object$keys2.length; _i7++) {\n var _entity2 = _Object$keys2[_i7];\n var entityInNum = Number(_entity2);\n var componentIndex = this.lookup[entityInNum];\n callback(entityInNum, this.getComponent(componentIndex));\n }\n }\n }, {\n key: "forEachAsync",\n value: function () {\n var _forEachAsync = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee(callback) {\n var _i8, _Object$keys3, _entity3, entityInNum, componentIndex;\n\n return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _i8 = 0, _Object$keys3 = Object.keys(this.lookup);\n\n case 1:\n if (!(_i8 < _Object$keys3.length)) {\n _context.next = 10;\n break;\n }\n\n _entity3 = _Object$keys3[_i8];\n entityInNum = Number(_entity3);\n componentIndex = this.lookup[entityInNum];\n _context.next = 7;\n return callback(entityInNum, this.getComponent(componentIndex));\n\n case 7:\n _i8++;\n _context.next = 1;\n break;\n\n case 10:\n case "end":\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function forEachAsync(_x) {\n return _forEachAsync.apply(this, arguments);\n }\n\n return forEachAsync;\n }()\n }, {\n key: "map",\n value: function map(callback) {\n var result = [];\n\n for (var _i9 = 0, _Object$keys4 = Object.keys(this.lookup); _i9 < _Object$keys4.length; _i9++) {\n var _entity4 = _Object$keys4[_i9];\n var entityInNum = Number(_entity4);\n var componentIndex = this.lookup[entityInNum];\n result.push(callback(entityInNum, this.getComponent(componentIndex)));\n }\n\n return result;\n }\n }]);\n\n return ComponentManager;\n}();\n//# sourceMappingURL=ComponentManager.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy13ZWJncHUtY29yZS9lcy9Db21wb25lbnRNYW5hZ2VyLmpzP2EwM2IiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUE2RDtBQUNXO0FBQ1Y7QUFDTTtBQUNuQztBQUMxQiwwQ0FBMEM7O0FBRWpELEVBQUUsNEVBQWU7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksNEVBQWU7O0FBRW5CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFFLHlFQUFZO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7O0FBR1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJDQUEyQyw2QkFBNkI7QUFDeEU7QUFDQSxXQUFXOzs7QUFHWCw0Q0FBNEMsNEJBQTRCO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOzs7QUFHUDtBQUNBLDhDQUE4Qzs7QUFFOUM7O0FBRUEsOEJBQThCLG1CQUFtQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87OztBQUdQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLGdFQUFnRSwyQkFBMkI7QUFDM0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxhQUFhLHFEQUFLO0FBQ2xCO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSx1QkFBdUIsdUJBQXVCO0FBQzlDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLHVCQUF1Qix1QkFBdUI7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsaUVBQWlFLDRCQUE0QjtBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLDBCQUEwQiw4RUFBaUIsZUFBZSxpRUFBbUI7QUFDN0U7O0FBRUEsZUFBZSxpRUFBbUI7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQSxpRUFBaUUsNEJBQTRCO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSxDQUFDO0FBQ0QiLCJmaWxlIjoiMjUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgX3JlZ2VuZXJhdG9yUnVudGltZSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIjtcbmltcG9ydCBfYXN5bmNUb0dlbmVyYXRvciBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgeyBFTVBUWSB9IGZyb20gJy4vRW50aXR5JztcbmV4cG9ydCB2YXIgQ29tcG9uZW50ID0gZnVuY3Rpb24gQ29tcG9uZW50KGRhdGEpIHsvL1xuXG4gIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb21wb25lbnQpO1xufTtcbi8qKlxuICog566h55CG5p+Q5LiA57G7IENvbXBvbmVudO+8jOWwveWPr+iDveWBmuWIsCBBb1Mg6ICM6Z2eIFNvQVxuICogQHNlZSBodHRwczovL3dpY2tlZGVuZ2luZS5uZXQvMjAxOS8wOS8yOS9lbnRpdHktY29tcG9uZW50LXN5c3RlbS9cbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3R1cmFuc3praWovV2lja2VkRW5naW5lL2Jsb2IvbWFzdGVyL1dpY2tlZEVuZ2luZS93aUVDUy5oXG4gKi9cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtY2xhc3Nlcy1wZXItZmlsZVxuXG5leHBvcnQgdmFyIENvbXBvbmVudE1hbmFnZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICog5LiN5ZyoIEVudGl0eSDkuK3nu7TmiqTmi6XmnInnmoQgQ29tcG9uZW50IOWIl+ihqO+8jOWPjeS5i+S6pueEtlxuICAgKi9cbiAgZnVuY3Rpb24gQ29tcG9uZW50TWFuYWdlcihjbGF6eikge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb21wb25lbnRNYW5hZ2VyKTtcblxuICAgIHRoaXMuY2xhenogPSB2b2lkIDA7XG4gICAgdGhpcy5jb21wb25lbnRzID0gW107XG4gICAgdGhpcy5lbnRpdGllcyA9IFtdO1xuICAgIHRoaXMubG9va3VwID0ge307XG4gICAgdGhpcy5jbGF6eiA9IGNsYXp6O1xuICB9XG5cbiAgX2NyZWF0ZUNsYXNzKENvbXBvbmVudE1hbmFnZXIsIFt7XG4gICAga2V5OiBcImNsZWFyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgICAgdGhpcy5jb21wb25lbnRzID0gW107XG4gICAgICB0aGlzLmVudGl0aWVzID0gW107XG4gICAgICB0aGlzLmxvb2t1cCA9IHt9O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJjb250YWluc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjb250YWlucyhlbnRpdHkpIHtcbiAgICAgIHJldHVybiB0aGlzLmxvb2t1cFtlbnRpdHldID4gLTE7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImNyZWF0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjcmVhdGUoZW50aXR5LCBkYXRhKSB7XG4gICAgICB0aGlzLmxvb2t1cFtlbnRpdHldID0gdGhpcy5jb21wb25lbnRzLmxlbmd0aDtcbiAgICAgIHZhciBjb21wb25lbnQgPSBuZXcgdGhpcy5jbGF6eihkYXRhIHx8IHt9KTtcbiAgICAgIHRoaXMuY29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgICB0aGlzLmVudGl0aWVzLnB1c2goZW50aXR5KTtcbiAgICAgIHJldHVybiBjb21wb25lbnQ7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbW92ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW1vdmUoZW50aXR5KSB7XG4gICAgICB2YXIgY29tcG9uZW50SW5kZXggPSB0aGlzLmxvb2t1cFtlbnRpdHldO1xuXG4gICAgICBpZiAoY29tcG9uZW50SW5kZXggPiAtMSkge1xuICAgICAgICBpZiAoY29tcG9uZW50SW5kZXggPCB0aGlzLmNvbXBvbmVudHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIC8vIOWwhuW+heWIoOmZpOWFg+e0oOWSjOacgOWQjuS4gOS4quWFg+e0oOS6pOaNolxuICAgICAgICAgIC8vIEMrKyDkuK3mnIkgc3RkOjptb3ZlIOi/meagt+eahOaTjeS9nO+8jOmBv+WFjeaVsOaNrueahOaLt+i0nVxuICAgICAgICAgIC8vIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3R1cmFuc3praWovV2lja2VkRW5naW5lL2Jsb2IvbWFzdGVyL1dpY2tlZEVuZ2luZS93aUVDUy5oI0wxNjlcbiAgICAgICAgICB0aGlzLmNvbXBvbmVudHNbY29tcG9uZW50SW5kZXhdID0gdGhpcy5jb21wb25lbnRzW3RoaXMuY29tcG9uZW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgICB0aGlzLmVudGl0aWVzW2NvbXBvbmVudEluZGV4XSA9IHRoaXMuZW50aXRpZXNbdGhpcy5lbnRpdGllcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICB0aGlzLmxvb2t1cFt0aGlzLmVudGl0aWVzW2NvbXBvbmVudEluZGV4XV0gPSBjb21wb25lbnRJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSAvLyDlvoXliKDpmaTlhYPntKDlt7Lnu4/np7vliqjliLDkuobmnIDlkI7kuIDkuKpcblxuXG4gICAgICB0aGlzLmNvbXBvbmVudHMucG9wKCk7XG4gICAgICB0aGlzLmVudGl0aWVzLnBvcCgpO1xuICAgICAgZGVsZXRlIHRoaXMubG9va3VwW2VudGl0eV07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcInJlbW92ZUtlZXBTb3J0ZWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlS2VlcFNvcnRlZChlbnRpdHkpIHtcbiAgICAgIHZhciBjb21wb25lbnRJbmRleCA9IHRoaXMubG9va3VwW2VudGl0eV07XG5cbiAgICAgIGlmIChjb21wb25lbnRJbmRleCA+IC0xKSB7XG4gICAgICAgIHZhciBlbnRpdHkyID0gdGhpcy5lbnRpdGllc1tjb21wb25lbnRJbmRleF07XG5cbiAgICAgICAgaWYgKGNvbXBvbmVudEluZGV4IDwgdGhpcy5jb21wb25lbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAvLyBNb3ZlIGV2ZXJ5IGNvbXBvbmVudCBsZWZ0IGJ5IG9uZSB0aGF0IGlzIGFmdGVyIHRoaXMgZWxlbWVudDpcbiAgICAgICAgICBmb3IgKHZhciBfaSA9IGNvbXBvbmVudEluZGV4ICsgMTsgX2kgPCB0aGlzLmNvbXBvbmVudHMubGVuZ3RoOyArK19pKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudHNbX2kgLSAxXSA9IHRoaXMuY29tcG9uZW50c1tfaV07XG4gICAgICAgICAgfSAvLyBNb3ZlIGV2ZXJ5IGVudGl0eSBsZWZ0IGJ5IG9uZSB0aGF0IGlzIGFmdGVyIHRoaXMgZWxlbWVudCBhbmQgdXBkYXRlIGx1dDpcblxuXG4gICAgICAgICAgZm9yICh2YXIgX2kyID0gY29tcG9uZW50SW5kZXggKyAxOyBfaTIgPCB0aGlzLmVudGl0aWVzLmxlbmd0aDsgKytfaTIpIHtcbiAgICAgICAgICAgIHRoaXMuZW50aXRpZXNbX2kyIC0gMV0gPSB0aGlzLmVudGl0aWVzW19pMl07XG4gICAgICAgICAgICB0aGlzLmxvb2t1cFt0aGlzLmVudGl0aWVzW19pMiAtIDFdXSA9IF9pMiAtIDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb21wb25lbnRzLnBvcCgpO1xuICAgICAgICB0aGlzLmVudGl0aWVzLnBvcCgpO1xuICAgICAgICBkZWxldGUgdGhpcy5sb29rdXBbZW50aXR5Ml07XG4gICAgICB9XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcIm1vdmVJdGVtXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIG1vdmVJdGVtKHNyY0luZGV4LCBkZXN0SW5kZXgpIHtcbiAgICAgIGlmIChzcmNJbmRleCA9PT0gZGVzdEluZGV4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gLy8gU2F2ZSB0aGUgbW92ZWQgY29tcG9uZW50IGFuZCBlbnRpdHk6XG5cblxuICAgICAgdmFyIHNyY0NvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50c1tzcmNJbmRleF07XG4gICAgICB2YXIgc3JjRW50aXR5ID0gdGhpcy5lbnRpdGllc1tzcmNJbmRleF07IC8vIEV2ZXJ5IG90aGVyIGVudGl0eS1jb21wb25lbnQgdGhhdCdzIGluIHRoZSB3YXkgZ2V0cyBtb3ZlZCBieSBvbmUgYW5kIGx1dCBpcyBrZXB0IHVwZGF0ZWQ6XG5cbiAgICAgIHZhciBkaXJlY3Rpb24gPSBzcmNJbmRleCA8IGRlc3RJbmRleCA/IDEgOiAtMTtcblxuICAgICAgZm9yICh2YXIgX2kzID0gc3JjSW5kZXg7IF9pMyAhPT0gZGVzdEluZGV4OyBfaTMgKz0gZGlyZWN0aW9uKSB7XG4gICAgICAgIHZhciBuZXh0ID0gX2kzICsgZGlyZWN0aW9uO1xuICAgICAgICB0aGlzLmNvbXBvbmVudHNbX2kzXSA9IHRoaXMuY29tcG9uZW50c1tuZXh0XTtcbiAgICAgICAgdGhpcy5lbnRpdGllc1tfaTNdID0gdGhpcy5lbnRpdGllc1tuZXh0XTtcbiAgICAgICAgdGhpcy5sb29rdXBbdGhpcy5lbnRpdGllc1tfaTNdXSA9IF9pMztcbiAgICAgIH0gLy8gU2F2ZWQgZW50aXR5LWNvbXBvbmVudCBtb3ZlZCB0byB0aGUgcmVxdWlyZWQgcG9zaXRpb246XG5cblxuICAgICAgdGhpcy5jb21wb25lbnRzW2Rlc3RJbmRleF0gPSBzcmNDb21wb25lbnQ7XG4gICAgICB0aGlzLmVudGl0aWVzW2Rlc3RJbmRleF0gPSBzcmNFbnRpdHk7XG4gICAgICB0aGlzLmxvb2t1cFtzcmNFbnRpdHldID0gZGVzdEluZGV4O1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRFbnRpdHlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RW50aXR5KGluZGV4KSB7XG4gICAgICByZXR1cm4gdGhpcy5lbnRpdGllc1tpbmRleF07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOeUseS6jue8uuWwkeexu+S8vCBDKysg55qE6YeN6L295pON5L2c56ym77yM5rKh5rOV6YCa6L+HIFvkuIvmoIddIOebtOaOpeiuv+mXruOAguWboOatpOWPquiDveWinuWKoOivpeaWueazleeUqOS6jumBjeWOhuOAglxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0Q29tcG9uZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldENvbXBvbmVudChpbmRleCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50c1tpbmRleF07XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImdldENvbXBvbmVudEJ5RW50aXR5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldENvbXBvbmVudEJ5RW50aXR5KGVudGl0eSkge1xuICAgICAgdmFyIGNvbXBvbmVudEluZGV4ID0gdGhpcy5sb29rdXBbZW50aXR5XTtcblxuICAgICAgaWYgKGNvbXBvbmVudEluZGV4ID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50c1tjb21wb25lbnRJbmRleF07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRDb3VudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRDb3VudCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudHMubGVuZ3RoO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJnZXRFbnRpdHlCeUNvbXBvbmVudEluZGV4XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEVudGl0eUJ5Q29tcG9uZW50SW5kZXgoY29tcG9uZW50SWR4KSB7XG4gICAgICBmb3IgKHZhciBfaTQgPSAwLCBfT2JqZWN0JGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLmxvb2t1cCk7IF9pNCA8IF9PYmplY3Qka2V5cy5sZW5ndGg7IF9pNCsrKSB7XG4gICAgICAgIHZhciBfZW50aXR5ID0gX09iamVjdCRrZXlzW19pNF07XG4gICAgICAgIHZhciBlbnRpdHlJbk51bSA9IE51bWJlcihfZW50aXR5KTtcblxuICAgICAgICBpZiAodGhpcy5sb29rdXBbZW50aXR5SW5OdW1dID09PSBjb21wb25lbnRJZHgpIHtcbiAgICAgICAgICByZXR1cm4gZW50aXR5SW5OdW07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEVNUFRZO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJmaW5kXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGZpbmQoY2FsbGJhY2spIHtcbiAgICAgIGZvciAodmFyIF9pNSA9IDA7IF9pNSA8IHRoaXMuZ2V0Q291bnQoKTsgX2k1KyspIHtcbiAgICAgICAgdmFyIF9jb21wb25lbnQgPSB0aGlzLmdldENvbXBvbmVudChfaTUpO1xuXG4gICAgICAgIGlmIChjYWxsYmFjayhfY29tcG9uZW50LCBfaTUpKSB7XG4gICAgICAgICAgcmV0dXJuIF9jb21wb25lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9LCB7XG4gICAga2V5OiBcImZpbmRJbmRleFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBmaW5kSW5kZXgoY2FsbGJhY2spIHtcbiAgICAgIGZvciAodmFyIF9pNiA9IDA7IF9pNiA8IHRoaXMuZ2V0Q291bnQoKTsgX2k2KyspIHtcbiAgICAgICAgdmFyIF9jb21wb25lbnQyID0gdGhpcy5nZXRDb21wb25lbnQoX2k2KTtcblxuICAgICAgICBpZiAoY2FsbGJhY2soX2NvbXBvbmVudDIsIF9pNikpIHtcbiAgICAgICAgICByZXR1cm4gX2k2O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gIH0sIHtcbiAgICBrZXk6IFwiZm9yRWFjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICBmb3IgKHZhciBfaTcgPSAwLCBfT2JqZWN0JGtleXMyID0gT2JqZWN0LmtleXModGhpcy5sb29rdXApOyBfaTcgPCBfT2JqZWN0JGtleXMyLmxlbmd0aDsgX2k3KyspIHtcbiAgICAgICAgdmFyIF9lbnRpdHkyID0gX09iamVjdCRrZXlzMltfaTddO1xuICAgICAgICB2YXIgZW50aXR5SW5OdW0gPSBOdW1iZXIoX2VudGl0eTIpO1xuICAgICAgICB2YXIgY29tcG9uZW50SW5kZXggPSB0aGlzLmxvb2t1cFtlbnRpdHlJbk51bV07XG4gICAgICAgIGNhbGxiYWNrKGVudGl0eUluTnVtLCB0aGlzLmdldENvbXBvbmVudChjb21wb25lbnRJbmRleCkpO1xuICAgICAgfVxuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJmb3JFYWNoQXN5bmNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mb3JFYWNoQXN5bmMgPSBfYXN5bmNUb0dlbmVyYXRvciggLyojX19QVVJFX18qL19yZWdlbmVyYXRvclJ1bnRpbWUubWFyayhmdW5jdGlvbiBfY2FsbGVlKGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBfaTgsIF9PYmplY3Qka2V5czMsIF9lbnRpdHkzLCBlbnRpdHlJbk51bSwgY29tcG9uZW50SW5kZXg7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvclJ1bnRpbWUud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfaTggPSAwLCBfT2JqZWN0JGtleXMzID0gT2JqZWN0LmtleXModGhpcy5sb29rdXApO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICBpZiAoIShfaTggPCBfT2JqZWN0JGtleXMzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxMDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIF9lbnRpdHkzID0gX09iamVjdCRrZXlzM1tfaThdO1xuICAgICAgICAgICAgICAgIGVudGl0eUluTnVtID0gTnVtYmVyKF9lbnRpdHkzKTtcbiAgICAgICAgICAgICAgICBjb21wb25lbnRJbmRleCA9IHRoaXMubG9va3VwW2VudGl0eUluTnVtXTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNztcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZW50aXR5SW5OdW0sIHRoaXMuZ2V0Q29tcG9uZW50KGNvbXBvbmVudEluZGV4KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIF9pOCsrO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIGZ1bmN0aW9uIGZvckVhY2hBc3luYyhfeCkge1xuICAgICAgICByZXR1cm4gX2ZvckVhY2hBc3luYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZm9yRWFjaEFzeW5jO1xuICAgIH0oKVxuICB9LCB7XG4gICAga2V5OiBcIm1hcFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBtYXAoY2FsbGJhY2spIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgZm9yICh2YXIgX2k5ID0gMCwgX09iamVjdCRrZXlzNCA9IE9iamVjdC5rZXlzKHRoaXMubG9va3VwKTsgX2k5IDwgX09iamVjdCRrZXlzNC5sZW5ndGg7IF9pOSsrKSB7XG4gICAgICAgIHZhciBfZW50aXR5NCA9IF9PYmplY3Qka2V5czRbX2k5XTtcbiAgICAgICAgdmFyIGVudGl0eUluTnVtID0gTnVtYmVyKF9lbnRpdHk0KTtcbiAgICAgICAgdmFyIGNvbXBvbmVudEluZGV4ID0gdGhpcy5sb29rdXBbZW50aXR5SW5OdW1dO1xuICAgICAgICByZXN1bHQucHVzaChjYWxsYmFjayhlbnRpdHlJbk51bSwgdGhpcy5nZXRDb21wb25lbnQoY29tcG9uZW50SW5kZXgpKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICB9XSk7XG5cbiAgcmV0dXJuIENvbXBvbmVudE1hbmFnZXI7XG59KCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db21wb25lbnRNYW5hZ2VyLmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///25\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return createSVGElement; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return createDom; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return sortDom; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return moveTo; });\n/* harmony import */ var _antv_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n/* harmony import */ var _constant__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17);\n\n\n/**\n * 创建并返回图形的 svg 元素\n * @param type svg类型\n */\nfunction createSVGElement(type) {\n return document.createElementNS('http://www.w3.org/2000/svg', type);\n}\n/**\n * 创建并返回图形的 dom 元素\n * @param {IShape} shape 图形\n * @return {SVGElement}\n */\nfunction createDom(shape) {\n var type = _constant__WEBPACK_IMPORTED_MODULE_1__[/* SHAPE_TO_TAGS */ \"a\"][shape.type];\n var parent = shape.getParent();\n if (!type) {\n throw new Error(\"the type \" + shape.type + \" is not supported by svg\");\n }\n var element = createSVGElement(type);\n if (shape.get('id')) {\n element.id = shape.get('id');\n }\n shape.set('el', element);\n shape.set('attrs', {});\n // 对于 defs 下的 dom 节点,parent 为空,通过 context 统一挂载到 defs 节点下\n if (parent) {\n var parentNode = parent.get('el');\n if (parentNode) {\n parentNode.appendChild(element);\n }\n else {\n // parentNode maybe null for group\n parentNode = parent.createDom();\n parent.set('el', parentNode);\n parentNode.appendChild(element);\n }\n }\n return element;\n}\n/**\n * 对 dom 元素进行排序\n * @param {IElement} element 元素\n * @param {sorter} function 排序函数\n */\nfunction sortDom(element, sorter) {\n var el = element.get('el');\n var childList = Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"toArray\"])(el.children).sort(sorter);\n // create empty fragment\n var fragment = document.createDocumentFragment();\n childList.forEach(function (child) {\n fragment.appendChild(child);\n });\n el.appendChild(fragment);\n}\n/**\n * 将 dom 元素移动到父元素下的指定位置\n * @param {SVGElement} element dom 元素\n * @param {number} targetIndex 目标位置(从 0 开始)\n */\nfunction moveTo(element, targetIndex) {\n var parentNode = element.parentNode;\n var siblings = Array.from(parentNode.childNodes).filter(\n // 要求为元素节点,且不能为 defs 节点\n function (node) { return node.nodeType === 1 && node.nodeName.toLowerCase() !== 'defs'; });\n // 获取目标节点\n var target = siblings[targetIndex];\n var currentIndex = siblings.indexOf(element);\n // 如果目标节点存在\n if (target) {\n // 当前索引 > 目标索引,直接插入到目标节点之前即可\n if (currentIndex > targetIndex) {\n parentNode.insertBefore(element, target);\n }\n else if (currentIndex < targetIndex) {\n // 当前索引 < 目标索引\n // 获取目标节点的下一个节点\n var targetNext = siblings[targetIndex + 1];\n // 如果目标节点的下一个节点存在,插入到该节点之前\n if (targetNext) {\n parentNode.insertBefore(element, targetNext);\n }\n else {\n // 如果该节点不存在,则追加到末尾\n parentNode.appendChild(element);\n }\n }\n }\n else {\n parentNode.appendChild(element);\n }\n}\n//# sourceMappingURL=dom.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvZXNtL3V0aWwvZG9tLmpzPzczZWMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQXFDO0FBQ087QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFlBQVk7QUFDWjtBQUNPO0FBQ1AsZUFBZSwrREFBYTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQixXQUFXLE9BQU87QUFDbEI7QUFDTztBQUNQO0FBQ0Esb0JBQW9CLDBEQUFPO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxXQUFXO0FBQ3RCLFdBQVcsT0FBTztBQUNsQjtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHNFQUFzRSxFQUFFO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjI2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdG9BcnJheSB9IGZyb20gJ0BhbnR2L3V0aWwnO1xuaW1wb3J0IHsgU0hBUEVfVE9fVEFHUyB9IGZyb20gJy4uL2NvbnN0YW50Jztcbi8qKlxuICog5Yib5bu65bm26L+U5Zue5Zu+5b2i55qEIHN2ZyDlhYPntKBcbiAqIEBwYXJhbSB0eXBlIHN2Z+exu+Wei1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU1ZHRWxlbWVudCh0eXBlKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUygnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLCB0eXBlKTtcbn1cbi8qKlxuICog5Yib5bu65bm26L+U5Zue5Zu+5b2i55qEIGRvbSDlhYPntKBcbiAqIEBwYXJhbSAge0lTaGFwZX0gc2hhcGUg5Zu+5b2iXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRG9tKHNoYXBlKSB7XG4gICAgdmFyIHR5cGUgPSBTSEFQRV9UT19UQUdTW3NoYXBlLnR5cGVdO1xuICAgIHZhciBwYXJlbnQgPSBzaGFwZS5nZXRQYXJlbnQoKTtcbiAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGhlIHR5cGUgXCIgKyBzaGFwZS50eXBlICsgXCIgaXMgbm90IHN1cHBvcnRlZCBieSBzdmdcIik7XG4gICAgfVxuICAgIHZhciBlbGVtZW50ID0gY3JlYXRlU1ZHRWxlbWVudCh0eXBlKTtcbiAgICBpZiAoc2hhcGUuZ2V0KCdpZCcpKSB7XG4gICAgICAgIGVsZW1lbnQuaWQgPSBzaGFwZS5nZXQoJ2lkJyk7XG4gICAgfVxuICAgIHNoYXBlLnNldCgnZWwnLCBlbGVtZW50KTtcbiAgICBzaGFwZS5zZXQoJ2F0dHJzJywge30pO1xuICAgIC8vIOWvueS6jiBkZWZzIOS4i+eahCBkb20g6IqC54K577yMcGFyZW50IOS4uuepuu+8jOmAmui/hyBjb250ZXh0IOe7n+S4gOaMgui9veWIsCBkZWZzIOiKgueCueS4i1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnQuZ2V0KCdlbCcpO1xuICAgICAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHBhcmVudE5vZGUgbWF5YmUgbnVsbCBmb3IgZ3JvdXBcbiAgICAgICAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnQuY3JlYXRlRG9tKCk7XG4gICAgICAgICAgICBwYXJlbnQuc2V0KCdlbCcsIHBhcmVudE5vZGUpO1xuICAgICAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cbi8qKlxuICog5a+5IGRvbSDlhYPntKDov5vooYzmjpLluo9cbiAqIEBwYXJhbSB7SUVsZW1lbnR9IGVsZW1lbnQgIOWFg+e0oFxuICogQHBhcmFtIHtzb3J0ZXJ9ICAgZnVuY3Rpb24g5o6S5bqP5Ye95pWwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb3J0RG9tKGVsZW1lbnQsIHNvcnRlcikge1xuICAgIHZhciBlbCA9IGVsZW1lbnQuZ2V0KCdlbCcpO1xuICAgIHZhciBjaGlsZExpc3QgPSB0b0FycmF5KGVsLmNoaWxkcmVuKS5zb3J0KHNvcnRlcik7XG4gICAgLy8gY3JlYXRlIGVtcHR5IGZyYWdtZW50XG4gICAgdmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIGNoaWxkTGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgfSk7XG4gICAgZWwuYXBwZW5kQ2hpbGQoZnJhZ21lbnQpO1xufVxuLyoqXG4gKiDlsIYgZG9tIOWFg+e0oOenu+WKqOWIsOeItuWFg+e0oOS4i+eahOaMh+WumuS9jee9rlxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBlbGVtZW50ICAgICBkb20g5YWD57SgXG4gKiBAcGFyYW0ge251bWJlcn0gICAgIHRhcmdldEluZGV4IOebruagh+S9jee9rijku44gMCDlvIDlp4spXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlVG8oZWxlbWVudCwgdGFyZ2V0SW5kZXgpIHtcbiAgICB2YXIgcGFyZW50Tm9kZSA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgICB2YXIgc2libGluZ3MgPSBBcnJheS5mcm9tKHBhcmVudE5vZGUuY2hpbGROb2RlcykuZmlsdGVyKFxuICAgIC8vIOimgeaxguS4uuWFg+e0oOiKgueCue+8jOS4lOS4jeiDveS4uiBkZWZzIOiKgueCuVxuICAgIGZ1bmN0aW9uIChub2RlKSB7IHJldHVybiBub2RlLm5vZGVUeXBlID09PSAxICYmIG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gJ2RlZnMnOyB9KTtcbiAgICAvLyDojrflj5bnm67moIfoioLngrlcbiAgICB2YXIgdGFyZ2V0ID0gc2libGluZ3NbdGFyZ2V0SW5kZXhdO1xuICAgIHZhciBjdXJyZW50SW5kZXggPSBzaWJsaW5ncy5pbmRleE9mKGVsZW1lbnQpO1xuICAgIC8vIOWmguaenOebruagh+iKgueCueWtmOWcqFxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgLy8g5b2T5YmN57Si5byVID4g55uu5qCH57Si5byV77yM55u05o6l5o+S5YWl5Yiw55uu5qCH6IqC54K55LmL5YmN5Y2z5Y+vXG4gICAgICAgIGlmIChjdXJyZW50SW5kZXggPiB0YXJnZXRJbmRleCkge1xuICAgICAgICAgICAgcGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgdGFyZ2V0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjdXJyZW50SW5kZXggPCB0YXJnZXRJbmRleCkge1xuICAgICAgICAgICAgLy8g5b2T5YmN57Si5byVIDwg55uu5qCH57Si5byVXG4gICAgICAgICAgICAvLyDojrflj5bnm67moIfoioLngrnnmoTkuIvkuIDkuKroioLngrlcbiAgICAgICAgICAgIHZhciB0YXJnZXROZXh0ID0gc2libGluZ3NbdGFyZ2V0SW5kZXggKyAxXTtcbiAgICAgICAgICAgIC8vIOWmguaenOebruagh+iKgueCueeahOS4i+S4gOS4quiKgueCueWtmOWcqO+8jOaPkuWFpeWIsOivpeiKgueCueS5i+WJjVxuICAgICAgICAgICAgaWYgKHRhcmdldE5leHQpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50LCB0YXJnZXROZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOivpeiKgueCueS4jeWtmOWcqO+8jOWImei/veWKoOWIsOacq+WwvlxuICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZG9tLmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///26\n")},function(module,exports,__webpack_require__){eval('var arrayWithoutHoles = __webpack_require__(530);\n\nvar iterableToArray = __webpack_require__(531);\n\nvar unsupportedIterableToArray = __webpack_require__(240);\n\nvar nonIterableSpread = __webpack_require__(532);\n\nfunction _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}\n\nmodule.exports = _toConsumableArray;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy90b0NvbnN1bWFibGVBcnJheS5qcz80NDhhIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHdCQUF3QixtQkFBTyxDQUFDLEdBQXdCOztBQUV4RCxzQkFBc0IsbUJBQU8sQ0FBQyxHQUFzQjs7QUFFcEQsaUNBQWlDLG1CQUFPLENBQUMsR0FBaUM7O0FBRTFFLHdCQUF3QixtQkFBTyxDQUFDLEdBQXdCOztBQUV4RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiIyNy5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBhcnJheVdpdGhvdXRIb2xlcyA9IHJlcXVpcmUoXCIuL2FycmF5V2l0aG91dEhvbGVzLmpzXCIpO1xuXG52YXIgaXRlcmFibGVUb0FycmF5ID0gcmVxdWlyZShcIi4vaXRlcmFibGVUb0FycmF5LmpzXCIpO1xuXG52YXIgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkgPSByZXF1aXJlKFwiLi91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qc1wiKTtcblxudmFyIG5vbkl0ZXJhYmxlU3ByZWFkID0gcmVxdWlyZShcIi4vbm9uSXRlcmFibGVTcHJlYWQuanNcIik7XG5cbmZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHtcbiAgcmV0dXJuIGFycmF5V2l0aG91dEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5KGFycikgfHwgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBub25JdGVyYWJsZVNwcmVhZCgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF90b0NvbnN1bWFibGVBcnJheTtcbm1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///27\n')},function(module,exports,__webpack_require__){eval("// eslint-disable-next-line no-redeclare\n/* global window */\n\nvar lodash;\n\nif (true) {\n try {\n lodash = {\n cloneDeep: __webpack_require__(435),\n constant: __webpack_require__(163),\n defaults: __webpack_require__(436),\n each: __webpack_require__(204),\n filter: __webpack_require__(207),\n find: __webpack_require__(437),\n flatten: __webpack_require__(234),\n forEach: __webpack_require__(205),\n forIn: __webpack_require__(444),\n has: __webpack_require__(218),\n isUndefined: __webpack_require__(219),\n last: __webpack_require__(445),\n map: __webpack_require__(220),\n mapValues: __webpack_require__(446),\n max: __webpack_require__(447),\n merge: __webpack_require__(449),\n min: __webpack_require__(455),\n minBy: __webpack_require__(456),\n now: __webpack_require__(457),\n pick: __webpack_require__(458),\n range: __webpack_require__(463),\n reduce: __webpack_require__(222),\n sortBy: __webpack_require__(466),\n uniqueId: __webpack_require__(471),\n values: __webpack_require__(227),\n zipObject: __webpack_require__(472),\n };\n } catch (e) {\n // continue regardless of error\n }\n}\n\nif (!lodash) {\n lodash = window._;\n}\n\nmodule.exports = lodash;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZGFncmVqcy9saWIvbG9kYXNoLmpzPzYzYmUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7QUFFQTs7QUFFQSxJQUFJLElBQTZCO0FBQ2pDO0FBQ0E7QUFDQSxpQkFBaUIsbUJBQU8sQ0FBQyxHQUFrQjtBQUMzQyxnQkFBZ0IsbUJBQU8sQ0FBQyxHQUFpQjtBQUN6QyxnQkFBZ0IsbUJBQU8sQ0FBQyxHQUFpQjtBQUN6QyxZQUFZLG1CQUFPLENBQUMsR0FBYTtBQUNqQyxjQUFjLG1CQUFPLENBQUMsR0FBZTtBQUNyQyxZQUFZLG1CQUFPLENBQUMsR0FBYTtBQUNqQyxlQUFlLG1CQUFPLENBQUMsR0FBZ0I7QUFDdkMsZUFBZSxtQkFBTyxDQUFDLEdBQWdCO0FBQ3ZDLGFBQWEsbUJBQU8sQ0FBQyxHQUFjO0FBQ25DLFlBQVksbUJBQU8sQ0FBQyxHQUFZO0FBQ2hDLG1CQUFtQixtQkFBTyxDQUFDLEdBQW9CO0FBQy9DLFlBQVksbUJBQU8sQ0FBQyxHQUFhO0FBQ2pDLFdBQVcsbUJBQU8sQ0FBQyxHQUFZO0FBQy9CLGlCQUFpQixtQkFBTyxDQUFDLEdBQWtCO0FBQzNDLFdBQVcsbUJBQU8sQ0FBQyxHQUFZO0FBQy9CLGFBQWEsbUJBQU8sQ0FBQyxHQUFjO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxHQUFZO0FBQy9CLGFBQWEsbUJBQU8sQ0FBQyxHQUFjO0FBQ25DLFdBQVcsbUJBQU8sQ0FBQyxHQUFZO0FBQy9CLFlBQVksbUJBQU8sQ0FBQyxHQUFhO0FBQ2pDLGFBQWEsbUJBQU8sQ0FBQyxHQUFjO0FBQ25DLGNBQWMsbUJBQU8sQ0FBQyxHQUFlO0FBQ3JDLGNBQWMsbUJBQU8sQ0FBQyxHQUFlO0FBQ3JDLGdCQUFnQixtQkFBTyxDQUFDLEdBQWlCO0FBQ3pDLGNBQWMsbUJBQU8sQ0FBQyxHQUFlO0FBQ3JDLGlCQUFpQixtQkFBTyxDQUFDLEdBQWtCO0FBQzNDO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEiLCJmaWxlIjoiMjguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG4vKiBnbG9iYWwgd2luZG93ICovXG5cbnZhciBsb2Rhc2g7XG5cbmlmICh0eXBlb2YgcmVxdWlyZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gIHRyeSB7XG4gICAgbG9kYXNoID0ge1xuICAgICAgY2xvbmVEZWVwOiByZXF1aXJlKFwibG9kYXNoL2Nsb25lRGVlcFwiKSxcbiAgICAgIGNvbnN0YW50OiByZXF1aXJlKFwibG9kYXNoL2NvbnN0YW50XCIpLFxuICAgICAgZGVmYXVsdHM6IHJlcXVpcmUoXCJsb2Rhc2gvZGVmYXVsdHNcIiksXG4gICAgICBlYWNoOiByZXF1aXJlKFwibG9kYXNoL2VhY2hcIiksXG4gICAgICBmaWx0ZXI6IHJlcXVpcmUoXCJsb2Rhc2gvZmlsdGVyXCIpLFxuICAgICAgZmluZDogcmVxdWlyZShcImxvZGFzaC9maW5kXCIpLFxuICAgICAgZmxhdHRlbjogcmVxdWlyZShcImxvZGFzaC9mbGF0dGVuXCIpLFxuICAgICAgZm9yRWFjaDogcmVxdWlyZShcImxvZGFzaC9mb3JFYWNoXCIpLFxuICAgICAgZm9ySW46IHJlcXVpcmUoXCJsb2Rhc2gvZm9ySW5cIiksXG4gICAgICBoYXM6ICByZXF1aXJlKFwibG9kYXNoL2hhc1wiKSxcbiAgICAgIGlzVW5kZWZpbmVkOiByZXF1aXJlKFwibG9kYXNoL2lzVW5kZWZpbmVkXCIpLFxuICAgICAgbGFzdDogcmVxdWlyZShcImxvZGFzaC9sYXN0XCIpLFxuICAgICAgbWFwOiByZXF1aXJlKFwibG9kYXNoL21hcFwiKSxcbiAgICAgIG1hcFZhbHVlczogcmVxdWlyZShcImxvZGFzaC9tYXBWYWx1ZXNcIiksXG4gICAgICBtYXg6IHJlcXVpcmUoXCJsb2Rhc2gvbWF4XCIpLFxuICAgICAgbWVyZ2U6IHJlcXVpcmUoXCJsb2Rhc2gvbWVyZ2VcIiksXG4gICAgICBtaW46IHJlcXVpcmUoXCJsb2Rhc2gvbWluXCIpLFxuICAgICAgbWluQnk6IHJlcXVpcmUoXCJsb2Rhc2gvbWluQnlcIiksXG4gICAgICBub3c6IHJlcXVpcmUoXCJsb2Rhc2gvbm93XCIpLFxuICAgICAgcGljazogcmVxdWlyZShcImxvZGFzaC9waWNrXCIpLFxuICAgICAgcmFuZ2U6IHJlcXVpcmUoXCJsb2Rhc2gvcmFuZ2VcIiksXG4gICAgICByZWR1Y2U6IHJlcXVpcmUoXCJsb2Rhc2gvcmVkdWNlXCIpLFxuICAgICAgc29ydEJ5OiByZXF1aXJlKFwibG9kYXNoL3NvcnRCeVwiKSxcbiAgICAgIHVuaXF1ZUlkOiByZXF1aXJlKFwibG9kYXNoL3VuaXF1ZUlkXCIpLFxuICAgICAgdmFsdWVzOiByZXF1aXJlKFwibG9kYXNoL3ZhbHVlc1wiKSxcbiAgICAgIHppcE9iamVjdDogcmVxdWlyZShcImxvZGFzaC96aXBPYmplY3RcIiksXG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGNvbnRpbnVlIHJlZ2FyZGxlc3Mgb2YgZXJyb3JcbiAgfVxufVxuXG5pZiAoIWxvZGFzaCkge1xuICBsb2Rhc2ggPSB3aW5kb3cuXztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///28\n")},function(module,exports){eval("function _initializerWarningHelper(descriptor, context) {\n throw new Error('Decorating class property failed. Please ensure that ' + 'proposal-class-properties is enabled and runs after the decorators transform.');\n}\n\nmodule.exports = _initializerWarningHelper;\nmodule.exports[\"default\"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbml0aWFsaXplcldhcm5pbmdIZWxwZXIuanM/ZDQwMCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiIyOS5qcyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9pbml0aWFsaXplcldhcm5pbmdIZWxwZXIoZGVzY3JpcHRvciwgY29udGV4dCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ0RlY29yYXRpbmcgY2xhc3MgcHJvcGVydHkgZmFpbGVkLiBQbGVhc2UgZW5zdXJlIHRoYXQgJyArICdwcm9wb3NhbC1jbGFzcy1wcm9wZXJ0aWVzIGlzIGVuYWJsZWQgYW5kIHJ1bnMgYWZ0ZXIgdGhlIGRlY29yYXRvcnMgdHJhbnNmb3JtLicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pbml0aWFsaXplcldhcm5pbmdIZWxwZXI7XG5tb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cywgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///29\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return applyAttrsToContext; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return drawChildren; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return checkRefresh; });\n/* unused harmony export checkChildrenRefresh */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return clearChanged; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"e\", function() { return drawPath; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"h\", function() { return refreshElement; });\n/* unused harmony export getRefreshRegion */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"f\", function() { return getMergedRegion; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"g\", function() { return mergeView; });\n/* harmony import */ var _antv_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n/* harmony import */ var _parse__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(142);\n/* harmony import */ var _arc_params__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(93);\n/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);\n/* harmony import */ var _util_arrow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(33);\n\n\n\n\n\nvar SHAPE_ATTRS_MAP = {\n fill: 'fillStyle',\n stroke: 'strokeStyle',\n opacity: 'globalAlpha',\n};\nfunction applyAttrsToContext(context, element) {\n var attrs = element.attr();\n for (var k in attrs) {\n var v = attrs[k];\n // 转换一下不与 canvas 兼容的属性名\n var name_1 = SHAPE_ATTRS_MAP[k] ? SHAPE_ATTRS_MAP[k] : k;\n if (name_1 === 'matrix' && v) {\n // 设置矩阵\n context.transform(v[0], v[1], v[3], v[4], v[6], v[7]);\n }\n else if (name_1 === 'lineDash' && context.setLineDash) {\n // 设置虚线,只支持数组形式,非数组形式不做任何操作\n Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"isArray\"])(v) && context.setLineDash(v);\n }\n else {\n if (name_1 === 'strokeStyle' || name_1 === 'fillStyle') {\n // 如果存在渐变、pattern 这个开销有些大\n // 可以考虑缓存机制,通过 hasUpdate 来避免一些运算\n v = Object(_parse__WEBPACK_IMPORTED_MODULE_1__[/* parseStyle */ \"b\"])(context, element, v);\n }\n else if (name_1 === 'globalAlpha') {\n // opacity 效果可以叠加,子元素的 opacity 需要与父元素 opacity 相乘\n v = v * context.globalAlpha;\n }\n context[name_1] = v;\n }\n }\n}\nfunction drawChildren(context, children, region) {\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n if (child.cfg.visible) {\n child.draw(context, region);\n }\n else {\n child.skipDraw();\n }\n }\n}\n// 这个地方的逻辑比较复杂,简单画了一张图:https://www.yuque.com/antv/ou292n/pcgt5g#OW1QE\nfunction checkRefresh(canvas, children, region) {\n var refreshElements = canvas.get('refreshElements');\n // 先遍历需要刷新的元素,将这些元素的父元素也设置 refresh\n Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"each\"])(refreshElements, function (el) {\n if (el !== canvas) {\n var parent_1 = el.cfg.parent;\n while (parent_1 && parent_1 !== canvas && !parent_1.cfg.refresh) {\n parent_1.cfg.refresh = true;\n parent_1 = parent_1.cfg.parent;\n }\n }\n });\n if (refreshElements[0] === canvas) {\n setChildrenRefresh(children, region);\n }\n else {\n // 检查所有子元素是否可以刷新\n checkChildrenRefresh(children, region);\n }\n}\n// 检查所有的子元素是否应该更新\nfunction checkChildrenRefresh(children, region) {\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n if (child.cfg.visible) {\n // 先判断 hasChanged,因为它的优先级判断应该高于 refresh\n if (child.cfg.hasChanged) {\n // 如果节点发生了 change,则需要级联设置子元素的 refresh\n child.cfg.refresh = true;\n if (child.isGroup()) {\n setChildrenRefresh(child.cfg.children, region);\n }\n }\n else if (child.cfg.refresh) {\n // 如果当前图形/分组 refresh = true,说明其子节点存在 changed\n if (child.isGroup()) {\n checkChildrenRefresh(child.cfg.children, region);\n }\n }\n else {\n // 这个分支说明此次局部刷新,所有的节点和父元素没有发生变化,仅需要检查包围盒(缓存)是否相交即可\n var refresh = checkElementRefresh(child, region);\n child.cfg.refresh = refresh;\n if (refresh && child.isGroup()) {\n // 如果需要刷新,说明子元素也需要刷新,继续进行判定\n checkChildrenRefresh(child.cfg.children, region);\n }\n }\n }\n }\n}\n// 由于对改变的图形放入 refreshElements 时做了优化,判定父元素 changed 时不加入\n// 那么有可能会出现 elements 都为空,所以最终 group\nfunction clearChanged(elements) {\n for (var i = 0; i < elements.length; i++) {\n var el = elements[i];\n el.cfg.hasChanged = false;\n // 级联清理\n if (el.isGroup() && !el.destroyed) {\n clearChanged(el.cfg.children);\n }\n }\n}\n// 当某个父元素发生改变时,调用这个方法级联设置 refresh\nfunction setChildrenRefresh(children, region) {\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n // let refresh = true;\n // 获取缓存的 bbox,如果这个 bbox 还存在则说明父元素不是矩阵发生了改变\n // const bbox = child.cfg.canvasBBox;\n // if (bbox) {\n // // 如果这时候\n // refresh = intersectRect(bbox, region);\n // }\n child.cfg.refresh = true;\n // 如果需要刷新当前节点,所有的子元素设置 refresh\n if (child.isGroup()) {\n setChildrenRefresh(child.get('children'), region);\n }\n }\n}\nfunction checkElementRefresh(shape, region) {\n var bbox = shape.cfg.cacheCanvasBBox;\n var isAllow = shape.cfg.isInView && bbox && Object(_util__WEBPACK_IMPORTED_MODULE_3__[/* intersectRect */ \"f\"])(bbox, region);\n return isAllow;\n}\n// 绘制 path\nfunction drawPath(shape, context, attrs, arcParamsCache) {\n var path = attrs.path, startArrow = attrs.startArrow, endArrow = attrs.endArrow;\n if (!path) {\n return;\n }\n var currentPoint = [0, 0]; // 当前图形\n var startMovePoint = [0, 0]; // 开始 M 的点,可能会有多个\n var distance = {\n dx: 0,\n dy: 0,\n };\n context.beginPath();\n for (var i = 0; i < path.length; i++) {\n var params = path[i];\n var command = params[0];\n if (i === 0 && startArrow && startArrow.d) {\n var tangent = shape.getStartTangent();\n distance = _util_arrow__WEBPACK_IMPORTED_MODULE_4__[/* getShortenOffset */ \"c\"](tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1], startArrow.d);\n }\n else if (i === path.length - 2 && path[i + 1][0] === 'Z' && endArrow && endArrow.d) {\n // 为了防止结尾为 Z 的 segment 缩短不起效,需要取最后两个 segment 特殊处理\n var lastPath = path[i + 1];\n if (lastPath[0] === 'Z') {\n var tangent = shape.getEndTangent();\n distance = _util_arrow__WEBPACK_IMPORTED_MODULE_4__[/* getShortenOffset */ \"c\"](tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1], endArrow.d);\n }\n }\n else if (i === path.length - 1 && endArrow && endArrow.d) {\n if (path[0] !== 'Z') {\n var tangent = shape.getEndTangent();\n distance = _util_arrow__WEBPACK_IMPORTED_MODULE_4__[/* getShortenOffset */ \"c\"](tangent[0][0], tangent[0][1], tangent[1][0], tangent[1][1], endArrow.d);\n }\n }\n var dx = distance.dx, dy = distance.dy;\n // V,H,S,T 都在前面被转换成标准形式\n switch (command) {\n case 'M':\n context.moveTo(params[1] - dx, params[2] - dy);\n startMovePoint = [params[1], params[2]];\n break;\n case 'L':\n context.lineTo(params[1] - dx, params[2] - dy);\n break;\n case 'Q':\n context.quadraticCurveTo(params[1], params[2], params[3] - dx, params[4] - dy);\n break;\n case 'C':\n context.bezierCurveTo(params[1], params[2], params[3], params[4], params[5] - dx, params[6] - dy);\n break;\n case 'A': {\n var arcParams = void 0;\n // 为了加速绘制,可以提供参数的缓存,各个图形自己缓存\n if (arcParamsCache) {\n arcParams = arcParamsCache[i];\n if (!arcParams) {\n arcParams = Object(_arc_params__WEBPACK_IMPORTED_MODULE_2__[/* default */ \"a\"])(currentPoint, params);\n arcParamsCache[i] = arcParams;\n }\n }\n else {\n arcParams = Object(_arc_params__WEBPACK_IMPORTED_MODULE_2__[/* default */ \"a\"])(currentPoint, params);\n }\n var cx = arcParams.cx, cy = arcParams.cy, rx = arcParams.rx, ry = arcParams.ry, startAngle = arcParams.startAngle, endAngle = arcParams.endAngle, xRotation = arcParams.xRotation, sweepFlag = arcParams.sweepFlag;\n // 直接使用椭圆的 api\n if (context.ellipse) {\n context.ellipse(cx, cy, rx, ry, xRotation, startAngle, endAngle, 1 - sweepFlag);\n }\n else {\n var r = rx > ry ? rx : ry;\n var scaleX = rx > ry ? 1 : rx / ry;\n var scaleY = rx > ry ? ry / rx : 1;\n context.translate(cx, cy);\n context.rotate(xRotation);\n context.scale(scaleX, scaleY);\n context.arc(0, 0, r, startAngle, endAngle, 1 - sweepFlag);\n context.scale(1 / scaleX, 1 / scaleY);\n context.rotate(-xRotation);\n context.translate(-cx, -cy);\n }\n break;\n }\n case 'Z':\n context.closePath();\n break;\n default:\n break;\n }\n // 有了 Z 后,当前节点从开始 M 的点开始\n if (command === 'Z') {\n currentPoint = startMovePoint;\n }\n else {\n var len = params.length;\n currentPoint = [params[len - 2], params[len - 1]];\n }\n }\n}\n// 刷新图形元素(Shape 或者 Group)\nfunction refreshElement(element, changeType) {\n var canvas = element.get('canvas');\n // 只有存在于 canvas 上时生效\n if (canvas) {\n if (changeType === 'remove') {\n // 一旦 remove,则无法在 element 上拿到包围盒\n // destroy 后所有属性都拿不到,所以需要暂存一下\n // 这是一段 hack 的代码\n element._cacheCanvasBBox = element.get('cacheCanvasBBox');\n }\n // 防止反复刷新\n if (!element.get('hasChanged')) {\n // 但是始终要标记为 hasChanged,便于后面进行局部渲染\n element.set('hasChanged', true);\n // 本来只有局部渲染模式下,才需要记录更新的元素队列\n // if (canvas.get('localRefresh')) {\n // canvas.refreshElement(element, changeType, canvas);\n // }\n // 但对于 https://github.com/antvis/g/issues/422 的场景,全局渲染的模式下也需要记录更新的元素队列\n // 如果当前元素的父元素发生了改变,可以不放入队列,这句话大概能够提升 15% 的初次渲染性能\n if (!(element.cfg.parent && element.cfg.parent.get('hasChanged'))) {\n canvas.refreshElement(element, changeType, canvas);\n if (canvas.get('autoDraw')) {\n canvas.draw();\n }\n }\n }\n }\n}\nfunction getRefreshRegion(element) {\n var region;\n if (!element.destroyed) {\n var cacheBox = element.get('cacheCanvasBBox');\n var validCache = cacheBox && !!(cacheBox.width && cacheBox.height);\n var bbox = element.getCanvasBBox();\n var validBBox = bbox && !!(bbox.width && bbox.height);\n // 是否是有效 bbox 判定,一些 NaN 或者 宽高为 0 的情况过滤掉\n if (validCache && validBBox) {\n region = Object(_util__WEBPACK_IMPORTED_MODULE_3__[/* mergeRegion */ \"l\"])(cacheBox, bbox);\n }\n else if (validCache) {\n region = cacheBox;\n }\n else if (validBBox) {\n region = bbox;\n }\n }\n else {\n // 因为元素已经销毁所以无法获取到缓存的包围盒\n region = element['_cacheCanvasBBox'];\n }\n return region;\n}\nfunction getMergedRegion(elements) {\n if (!elements.length) {\n return null;\n }\n var minXArr = [];\n var minYArr = [];\n var maxXArr = [];\n var maxYArr = [];\n Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"each\"])(elements, function (el) {\n var region = getRefreshRegion(el);\n if (region) {\n minXArr.push(region.minX);\n minYArr.push(region.minY);\n maxXArr.push(region.maxX);\n maxYArr.push(region.maxY);\n }\n });\n return {\n minX: Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"min\"])(minXArr),\n minY: Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"min\"])(minYArr),\n maxX: Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"max\"])(maxXArr),\n maxY: Object(_antv_util__WEBPACK_IMPORTED_MODULE_0__[\"max\"])(maxYArr),\n };\n}\nfunction mergeView(region, viewRegion) {\n if (!region || !viewRegion) {\n return null;\n }\n // 不相交,则直接返回 null\n if (!Object(_util__WEBPACK_IMPORTED_MODULE_3__[/* intersectRect */ \"f\"])(region, viewRegion)) {\n return null;\n }\n return {\n minX: Math.max(region.minX, viewRegion.minX),\n minY: Math.max(region.minY, viewRegion.minY),\n maxX: Math.min(region.maxX, viewRegion.maxX),\n maxY: Math.min(region.maxY, viewRegion.maxY),\n };\n}\n//# sourceMappingURL=draw.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvZXNtL3V0aWwvZHJhdy5qcz9mNWU1Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFxRDtBQUNoQjtBQUNHO0FBQ1k7QUFDVDtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSwwREFBTztBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGlFQUFVO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsbUJBQW1CLHFCQUFxQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBLElBQUksdURBQUk7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQLG1CQUFtQixxQkFBcUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUCxtQkFBbUIscUJBQXFCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHFCQUFxQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELG1FQUFhO0FBQzdEO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUIsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLG9FQUEwQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsb0VBQTBCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsb0VBQTBCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxtRUFBWTtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxtRUFBWTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsaUVBQVc7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLHVEQUFJO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxjQUFjLHNEQUFHO0FBQ2pCLGNBQWMsc0RBQUc7QUFDakIsY0FBYyxzREFBRztBQUNqQixjQUFjLHNEQUFHO0FBQ2pCO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxtRUFBYTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIzMC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVhY2gsIGlzQXJyYXksIG1heCwgbWluIH0gZnJvbSAnQGFudHYvdXRpbCc7XG5pbXBvcnQgeyBwYXJzZVN0eWxlIH0gZnJvbSAnLi9wYXJzZSc7XG5pbXBvcnQgZ2V0QXJjUGFyYW1zIGZyb20gJy4vYXJjLXBhcmFtcyc7XG5pbXBvcnQgeyBtZXJnZVJlZ2lvbiwgaW50ZXJzZWN0UmVjdCB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgKiBhcyBBcnJvd1V0aWwgZnJvbSAnLi4vdXRpbC9hcnJvdyc7XG52YXIgU0hBUEVfQVRUUlNfTUFQID0ge1xuICAgIGZpbGw6ICdmaWxsU3R5bGUnLFxuICAgIHN0cm9rZTogJ3N0cm9rZVN0eWxlJyxcbiAgICBvcGFjaXR5OiAnZ2xvYmFsQWxwaGEnLFxufTtcbmV4cG9ydCBmdW5jdGlvbiBhcHBseUF0dHJzVG9Db250ZXh0KGNvbnRleHQsIGVsZW1lbnQpIHtcbiAgICB2YXIgYXR0cnMgPSBlbGVtZW50LmF0dHIoKTtcbiAgICBmb3IgKHZhciBrIGluIGF0dHJzKSB7XG4gICAgICAgIHZhciB2ID0gYXR0cnNba107XG4gICAgICAgIC8vIOi9rOaNouS4gOS4i+S4jeS4jiBjYW52YXMg5YW85a6555qE5bGe5oCn5ZCNXG4gICAgICAgIHZhciBuYW1lXzEgPSBTSEFQRV9BVFRSU19NQVBba10gPyBTSEFQRV9BVFRSU19NQVBba10gOiBrO1xuICAgICAgICBpZiAobmFtZV8xID09PSAnbWF0cml4JyAmJiB2KSB7XG4gICAgICAgICAgICAvLyDorr7nva7nn6npmLVcbiAgICAgICAgICAgIGNvbnRleHQudHJhbnNmb3JtKHZbMF0sIHZbMV0sIHZbM10sIHZbNF0sIHZbNl0sIHZbN10pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5hbWVfMSA9PT0gJ2xpbmVEYXNoJyAmJiBjb250ZXh0LnNldExpbmVEYXNoKSB7XG4gICAgICAgICAgICAvLyDorr7nva7omZrnur/vvIzlj6rmlK/mjIHmlbDnu4TlvaLlvI/vvIzpnZ7mlbDnu4TlvaLlvI/kuI3lgZrku7vkvZXmk43kvZxcbiAgICAgICAgICAgIGlzQXJyYXkodikgJiYgY29udGV4dC5zZXRMaW5lRGFzaCh2KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChuYW1lXzEgPT09ICdzdHJva2VTdHlsZScgfHwgbmFtZV8xID09PSAnZmlsbFN0eWxlJykge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOWtmOWcqOa4kOWPmOOAgXBhdHRlcm4g6L+Z5Liq5byA6ZSA5pyJ5Lqb5aSnXG4gICAgICAgICAgICAgICAgLy8g5Y+v5Lul6ICD6JmR57yT5a2Y5py65Yi277yM6YCa6L+HIGhhc1VwZGF0ZSDmnaXpgb/lhY3kuIDkupvov5DnrpdcbiAgICAgICAgICAgICAgICB2ID0gcGFyc2VTdHlsZShjb250ZXh0LCBlbGVtZW50LCB2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG5hbWVfMSA9PT0gJ2dsb2JhbEFscGhhJykge1xuICAgICAgICAgICAgICAgIC8vIG9wYWNpdHkg5pWI5p6c5Y+v5Lul5Y+g5Yqg77yM5a2Q5YWD57Sg55qEIG9wYWNpdHkg6ZyA6KaB5LiO54i25YWD57SgIG9wYWNpdHkg55u45LmYXG4gICAgICAgICAgICAgICAgdiA9IHYgKiBjb250ZXh0Lmdsb2JhbEFscGhhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGV4dFtuYW1lXzFdID0gdjtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiBkcmF3Q2hpbGRyZW4oY29udGV4dCwgY2hpbGRyZW4sIHJlZ2lvbikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY2hpbGRyZW5baV07XG4gICAgICAgIGlmIChjaGlsZC5jZmcudmlzaWJsZSkge1xuICAgICAgICAgICAgY2hpbGQuZHJhdyhjb250ZXh0LCByZWdpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2hpbGQuc2tpcERyYXcoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIOi/meS4quWcsOaWueeahOmAu+i+keavlOi+g+Wkjeadgu+8jOeugOWNleeUu+S6huS4gOW8oOWbvu+8mmh0dHBzOi8vd3d3Lnl1cXVlLmNvbS9hbnR2L291Mjkybi9wY2d0NWcjT1cxUUVcbmV4cG9ydCBmdW5jdGlvbiBjaGVja1JlZnJlc2goY2FudmFzLCBjaGlsZHJlbiwgcmVnaW9uKSB7XG4gICAgdmFyIHJlZnJlc2hFbGVtZW50cyA9IGNhbnZhcy5nZXQoJ3JlZnJlc2hFbGVtZW50cycpO1xuICAgIC8vIOWFiOmBjeWOhumcgOimgeWIt+aWsOeahOWFg+e0oO+8jOWwhui/meS6m+WFg+e0oOeahOeItuWFg+e0oOS5n+iuvue9riByZWZyZXNoXG4gICAgZWFjaChyZWZyZXNoRWxlbWVudHMsIGZ1bmN0aW9uIChlbCkge1xuICAgICAgICBpZiAoZWwgIT09IGNhbnZhcykge1xuICAgICAgICAgICAgdmFyIHBhcmVudF8xID0gZWwuY2ZnLnBhcmVudDtcbiAgICAgICAgICAgIHdoaWxlIChwYXJlbnRfMSAmJiBwYXJlbnRfMSAhPT0gY2FudmFzICYmICFwYXJlbnRfMS5jZmcucmVmcmVzaCkge1xuICAgICAgICAgICAgICAgIHBhcmVudF8xLmNmZy5yZWZyZXNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBwYXJlbnRfMSA9IHBhcmVudF8xLmNmZy5wYXJlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAocmVmcmVzaEVsZW1lbnRzWzBdID09PSBjYW52YXMpIHtcbiAgICAgICAgc2V0Q2hpbGRyZW5SZWZyZXNoKGNoaWxkcmVuLCByZWdpb24pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g5qOA5p+l5omA5pyJ5a2Q5YWD57Sg5piv5ZCm5Y+v5Lul5Yi35pawXG4gICAgICAgIGNoZWNrQ2hpbGRyZW5SZWZyZXNoKGNoaWxkcmVuLCByZWdpb24pO1xuICAgIH1cbn1cbi8vIOajgOafpeaJgOacieeahOWtkOWFg+e0oOaYr+WQpuW6lOivpeabtOaWsFxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrQ2hpbGRyZW5SZWZyZXNoKGNoaWxkcmVuLCByZWdpb24pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgICAgICBpZiAoY2hpbGQuY2ZnLnZpc2libGUpIHtcbiAgICAgICAgICAgIC8vIOWFiOWIpOaWrSBoYXNDaGFuZ2Vk77yM5Zug5Li65a6D55qE5LyY5YWI57qn5Yik5pat5bqU6K+l6auY5LqOIHJlZnJlc2hcbiAgICAgICAgICAgIGlmIChjaGlsZC5jZmcuaGFzQ2hhbmdlZCkge1xuICAgICAgICAgICAgICAgIC8vIOWmguaenOiKgueCueWPkeeUn+S6hiBjaGFuZ2XvvIzliJnpnIDopoHnuqfogZTorr7nva7lrZDlhYPntKDnmoQgcmVmcmVzaFxuICAgICAgICAgICAgICAgIGNoaWxkLmNmZy5yZWZyZXNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNHcm91cCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldENoaWxkcmVuUmVmcmVzaChjaGlsZC5jZmcuY2hpbGRyZW4sIHJlZ2lvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGQuY2ZnLnJlZnJlc2gpIHtcbiAgICAgICAgICAgICAgICAvLyDlpoLmnpzlvZPliY3lm77lvaIv5YiG57uEIHJlZnJlc2ggPSB0cnVl77yM6K+05piO5YW25a2Q6IqC54K55a2Y5ZyoIGNoYW5nZWRcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNHcm91cCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoZWNrQ2hpbGRyZW5SZWZyZXNoKGNoaWxkLmNmZy5jaGlsZHJlbiwgcmVnaW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyDov5nkuKrliIbmlK/or7TmmI7mraTmrKHlsYDpg6jliLfmlrDvvIzmiYDmnInnmoToioLngrnlkozniLblhYPntKDmsqHmnInlj5HnlJ/lj5jljJbvvIzku4XpnIDopoHmo4Dmn6XljIXlm7Tnm5LvvIjnvJPlrZjvvInmmK/lkKbnm7jkuqTljbPlj69cbiAgICAgICAgICAgICAgICB2YXIgcmVmcmVzaCA9IGNoZWNrRWxlbWVudFJlZnJlc2goY2hpbGQsIHJlZ2lvbik7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2ZnLnJlZnJlc2ggPSByZWZyZXNoO1xuICAgICAgICAgICAgICAgIGlmIChyZWZyZXNoICYmIGNoaWxkLmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyDlpoLmnpzpnIDopoHliLfmlrDvvIzor7TmmI7lrZDlhYPntKDkuZ/pnIDopoHliLfmlrDvvIznu6fnu63ov5vooYzliKTlrppcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tDaGlsZHJlblJlZnJlc2goY2hpbGQuY2ZnLmNoaWxkcmVuLCByZWdpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIOeUseS6juWvueaUueWPmOeahOWbvuW9ouaUvuWFpSByZWZyZXNoRWxlbWVudHMg5pe25YGa5LqG5LyY5YyW77yM5Yik5a6a54i25YWD57SgIGNoYW5nZWQg5pe25LiN5Yqg5YWlXG4vLyDpgqPkuYjmnInlj6/og73kvJrlh7rnjrAgZWxlbWVudHMg6YO95Li656m677yM5omA5Lul5pyA57uIIGdyb3VwXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDaGFuZ2VkKGVsZW1lbnRzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZWwgPSBlbGVtZW50c1tpXTtcbiAgICAgICAgZWwuY2ZnLmhhc0NoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgLy8g57qn6IGU5riF55CGXG4gICAgICAgIGlmIChlbC5pc0dyb3VwKCkgJiYgIWVsLmRlc3Ryb3llZCkge1xuICAgICAgICAgICAgY2xlYXJDaGFuZ2VkKGVsLmNmZy5jaGlsZHJlbik7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyDlvZPmn5DkuKrniLblhYPntKDlj5HnlJ/mlLnlj5jml7bvvIzosIPnlKjov5nkuKrmlrnms5XnuqfogZTorr7nva4gcmVmcmVzaFxuZnVuY3Rpb24gc2V0Q2hpbGRyZW5SZWZyZXNoKGNoaWxkcmVuLCByZWdpb24pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgICAgICAvLyBsZXQgcmVmcmVzaCA9IHRydWU7XG4gICAgICAgIC8vIOiOt+WPlue8k+WtmOeahCBiYm9477yM5aaC5p6c6L+Z5LiqIGJib3gg6L+Y5a2Y5Zyo5YiZ6K+05piO54i25YWD57Sg5LiN5piv55+p6Zi15Y+R55Sf5LqG5pS55Y+YXG4gICAgICAgIC8vIGNvbnN0IGJib3ggPSBjaGlsZC5jZmcuY2FudmFzQkJveDtcbiAgICAgICAgLy8gaWYgKGJib3gpIHtcbiAgICAgICAgLy8gICAvLyDlpoLmnpzov5nml7blgJlcbiAgICAgICAgLy8gICByZWZyZXNoID0gaW50ZXJzZWN0UmVjdChiYm94LCByZWdpb24pO1xuICAgICAgICAvLyB9XG4gICAgICAgIGNoaWxkLmNmZy5yZWZyZXNoID0gdHJ1ZTtcbiAgICAgICAgLy8g5aaC5p6c6ZyA6KaB5Yi35paw5b2T5YmN6IqC54K577yM5omA5pyJ55qE5a2Q5YWD57Sg6K6+572uIHJlZnJlc2hcbiAgICAgICAgaWYgKGNoaWxkLmlzR3JvdXAoKSkge1xuICAgICAgICAgICAgc2V0Q2hpbGRyZW5SZWZyZXNoKGNoaWxkLmdldCgnY2hpbGRyZW4nKSwgcmVnaW9uKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGNoZWNrRWxlbWVudFJlZnJlc2goc2hhcGUsIHJlZ2lvbikge1xuICAgIHZhciBiYm94ID0gc2hhcGUuY2ZnLmNhY2hlQ2FudmFzQkJveDtcbiAgICB2YXIgaXNBbGxvdyA9IHNoYXBlLmNmZy5pc0luVmlldyAmJiBiYm94ICYmIGludGVyc2VjdFJlY3QoYmJveCwgcmVnaW9uKTtcbiAgICByZXR1cm4gaXNBbGxvdztcbn1cbi8vIOe7mOWItiBwYXRoXG5leHBvcnQgZnVuY3Rpb24gZHJhd1BhdGgoc2hhcGUsIGNvbnRleHQsIGF0dHJzLCBhcmNQYXJhbXNDYWNoZSkge1xuICAgIHZhciBwYXRoID0gYXR0cnMucGF0aCwgc3RhcnRBcnJvdyA9IGF0dHJzLnN0YXJ0QXJyb3csIGVuZEFycm93ID0gYXR0cnMuZW5kQXJyb3c7XG4gICAgaWYgKCFwYXRoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGN1cnJlbnRQb2ludCA9IFswLCAwXTsgLy8g5b2T5YmN5Zu+5b2iXG4gICAgdmFyIHN0YXJ0TW92ZVBvaW50ID0gWzAsIDBdOyAvLyDlvIDlp4sgTSDnmoTngrnvvIzlj6/og73kvJrmnInlpJrkuKpcbiAgICB2YXIgZGlzdGFuY2UgPSB7XG4gICAgICAgIGR4OiAwLFxuICAgICAgICBkeTogMCxcbiAgICB9O1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwYXJhbXMgPSBwYXRoW2ldO1xuICAgICAgICB2YXIgY29tbWFuZCA9IHBhcmFtc1swXTtcbiAgICAgICAgaWYgKGkgPT09IDAgJiYgc3RhcnRBcnJvdyAmJiBzdGFydEFycm93LmQpIHtcbiAgICAgICAgICAgIHZhciB0YW5nZW50ID0gc2hhcGUuZ2V0U3RhcnRUYW5nZW50KCk7XG4gICAgICAgICAgICBkaXN0YW5jZSA9IEFycm93VXRpbC5nZXRTaG9ydGVuT2Zmc2V0KHRhbmdlbnRbMF1bMF0sIHRhbmdlbnRbMF1bMV0sIHRhbmdlbnRbMV1bMF0sIHRhbmdlbnRbMV1bMV0sIHN0YXJ0QXJyb3cuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaSA9PT0gcGF0aC5sZW5ndGggLSAyICYmIHBhdGhbaSArIDFdWzBdID09PSAnWicgJiYgZW5kQXJyb3cgJiYgZW5kQXJyb3cuZCkge1xuICAgICAgICAgICAgLy8g5Li65LqG6Ziy5q2i57uT5bC+5Li6IFog55qEIHNlZ21lbnQg57yp55+t5LiN6LW35pWI77yM6ZyA6KaB5Y+W5pyA5ZCO5Lik5LiqIHNlZ21lbnQg54m55q6K5aSE55CGXG4gICAgICAgICAgICB2YXIgbGFzdFBhdGggPSBwYXRoW2kgKyAxXTtcbiAgICAgICAgICAgIGlmIChsYXN0UGF0aFswXSA9PT0gJ1onKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhbmdlbnQgPSBzaGFwZS5nZXRFbmRUYW5nZW50KCk7XG4gICAgICAgICAgICAgICAgZGlzdGFuY2UgPSBBcnJvd1V0aWwuZ2V0U2hvcnRlbk9mZnNldCh0YW5nZW50WzBdWzBdLCB0YW5nZW50WzBdWzFdLCB0YW5nZW50WzFdWzBdLCB0YW5nZW50WzFdWzFdLCBlbmRBcnJvdy5kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpID09PSBwYXRoLmxlbmd0aCAtIDEgJiYgZW5kQXJyb3cgJiYgZW5kQXJyb3cuZCkge1xuICAgICAgICAgICAgaWYgKHBhdGhbMF0gIT09ICdaJykge1xuICAgICAgICAgICAgICAgIHZhciB0YW5nZW50ID0gc2hhcGUuZ2V0RW5kVGFuZ2VudCgpO1xuICAgICAgICAgICAgICAgIGRpc3RhbmNlID0gQXJyb3dVdGlsLmdldFNob3J0ZW5PZmZzZXQodGFuZ2VudFswXVswXSwgdGFuZ2VudFswXVsxXSwgdGFuZ2VudFsxXVswXSwgdGFuZ2VudFsxXVsxXSwgZW5kQXJyb3cuZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGR4ID0gZGlzdGFuY2UuZHgsIGR5ID0gZGlzdGFuY2UuZHk7XG4gICAgICAgIC8vIFYsSCxTLFQg6YO95Zyo5YmN6Z2i6KKr6L2s5o2i5oiQ5qCH5YeG5b2i5byPXG4gICAgICAgIHN3aXRjaCAoY29tbWFuZCkge1xuICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgY29udGV4dC5tb3ZlVG8ocGFyYW1zWzFdIC0gZHgsIHBhcmFtc1syXSAtIGR5KTtcbiAgICAgICAgICAgICAgICBzdGFydE1vdmVQb2ludCA9IFtwYXJhbXNbMV0sIHBhcmFtc1syXV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhwYXJhbXNbMV0gLSBkeCwgcGFyYW1zWzJdIC0gZHkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKHBhcmFtc1sxXSwgcGFyYW1zWzJdLCBwYXJhbXNbM10gLSBkeCwgcGFyYW1zWzRdIC0gZHkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQyc6XG4gICAgICAgICAgICAgICAgY29udGV4dC5iZXppZXJDdXJ2ZVRvKHBhcmFtc1sxXSwgcGFyYW1zWzJdLCBwYXJhbXNbM10sIHBhcmFtc1s0XSwgcGFyYW1zWzVdIC0gZHgsIHBhcmFtc1s2XSAtIGR5KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0EnOiB7XG4gICAgICAgICAgICAgICAgdmFyIGFyY1BhcmFtcyA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICAvLyDkuLrkuobliqDpgJ/nu5jliLbvvIzlj6/ku6Xmj5Dkvpvlj4LmlbDnmoTnvJPlrZjvvIzlkITkuKrlm77lvaLoh6rlt7HnvJPlrZhcbiAgICAgICAgICAgICAgICBpZiAoYXJjUGFyYW1zQ2FjaGUpIHtcbiAgICAgICAgICAgICAgICAgICAgYXJjUGFyYW1zID0gYXJjUGFyYW1zQ2FjaGVbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICghYXJjUGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmNQYXJhbXMgPSBnZXRBcmNQYXJhbXMoY3VycmVudFBvaW50LCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJjUGFyYW1zQ2FjaGVbaV0gPSBhcmNQYXJhbXM7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFyY1BhcmFtcyA9IGdldEFyY1BhcmFtcyhjdXJyZW50UG9pbnQsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBjeCA9IGFyY1BhcmFtcy5jeCwgY3kgPSBhcmNQYXJhbXMuY3ksIHJ4ID0gYXJjUGFyYW1zLnJ4LCByeSA9IGFyY1BhcmFtcy5yeSwgc3RhcnRBbmdsZSA9IGFyY1BhcmFtcy5zdGFydEFuZ2xlLCBlbmRBbmdsZSA9IGFyY1BhcmFtcy5lbmRBbmdsZSwgeFJvdGF0aW9uID0gYXJjUGFyYW1zLnhSb3RhdGlvbiwgc3dlZXBGbGFnID0gYXJjUGFyYW1zLnN3ZWVwRmxhZztcbiAgICAgICAgICAgICAgICAvLyDnm7TmjqXkvb/nlKjmpK3lnIbnmoQgYXBpXG4gICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuZWxsaXBzZSkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVsbGlwc2UoY3gsIGN5LCByeCwgcnksIHhSb3RhdGlvbiwgc3RhcnRBbmdsZSwgZW5kQW5nbGUsIDEgLSBzd2VlcEZsYWcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSByeCA+IHJ5ID8gcnggOiByeTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjYWxlWCA9IHJ4ID4gcnkgPyAxIDogcnggLyByeTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjYWxlWSA9IHJ4ID4gcnkgPyByeSAvIHJ4IDogMTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC50cmFuc2xhdGUoY3gsIGN5KTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5yb3RhdGUoeFJvdGF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5zY2FsZShzY2FsZVgsIHNjYWxlWSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQuYXJjKDAsIDAsIHIsIHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCAxIC0gc3dlZXBGbGFnKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5zY2FsZSgxIC8gc2NhbGVYLCAxIC8gc2NhbGVZKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5yb3RhdGUoLXhSb3RhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQudHJhbnNsYXRlKC1jeCwgLWN5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgICAgICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyDmnInkuoYgWiDlkI7vvIzlvZPliY3oioLngrnku47lvIDlp4sgTSDnmoTngrnlvIDlp4tcbiAgICAgICAgaWYgKGNvbW1hbmQgPT09ICdaJykge1xuICAgICAgICAgICAgY3VycmVudFBvaW50ID0gc3RhcnRNb3ZlUG9pbnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgbGVuID0gcGFyYW1zLmxlbmd0aDtcbiAgICAgICAgICAgIGN1cnJlbnRQb2ludCA9IFtwYXJhbXNbbGVuIC0gMl0sIHBhcmFtc1tsZW4gLSAxXV07XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyDliLfmlrDlm77lvaLlhYPntKAoU2hhcGUg5oiW6ICFIEdyb3VwKVxuZXhwb3J0IGZ1bmN0aW9uIHJlZnJlc2hFbGVtZW50KGVsZW1lbnQsIGNoYW5nZVR5cGUpIHtcbiAgICB2YXIgY2FudmFzID0gZWxlbWVudC5nZXQoJ2NhbnZhcycpO1xuICAgIC8vIOWPquacieWtmOWcqOS6jiBjYW52YXMg5LiK5pe255Sf5pWIXG4gICAgaWYgKGNhbnZhcykge1xuICAgICAgICBpZiAoY2hhbmdlVHlwZSA9PT0gJ3JlbW92ZScpIHtcbiAgICAgICAgICAgIC8vIOS4gOaXpiByZW1vdmXvvIzliJnml6Dms5XlnKggZWxlbWVudCDkuIrmi7/liLDljIXlm7Tnm5JcbiAgICAgICAgICAgIC8vIGRlc3Ryb3kg5ZCO5omA5pyJ5bGe5oCn6YO95ou/5LiN5Yiw77yM5omA5Lul6ZyA6KaB5pqC5a2Y5LiA5LiLXG4gICAgICAgICAgICAvLyDov5nmmK/kuIDmrrUgaGFjayDnmoTku6PnoIFcbiAgICAgICAgICAgIGVsZW1lbnQuX2NhY2hlQ2FudmFzQkJveCA9IGVsZW1lbnQuZ2V0KCdjYWNoZUNhbnZhc0JCb3gnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyDpmLLmraLlj43lpI3liLfmlrBcbiAgICAgICAgaWYgKCFlbGVtZW50LmdldCgnaGFzQ2hhbmdlZCcpKSB7XG4gICAgICAgICAgICAvLyDkvYbmmK/lp4vnu4jopoHmoIforrDkuLogaGFzQ2hhbmdlZO+8jOS+v+S6juWQjumdoui/m+ihjOWxgOmDqOa4suafk1xuICAgICAgICAgICAgZWxlbWVudC5zZXQoJ2hhc0NoYW5nZWQnLCB0cnVlKTtcbiAgICAgICAgICAgIC8vIOacrOadpeWPquacieWxgOmDqOa4suafk+aooeW8j+S4i++8jOaJjemcgOimgeiusOW9leabtOaWsOeahOWFg+e0oOmYn+WIl1xuICAgICAgICAgICAgLy8gaWYgKGNhbnZhcy5nZXQoJ2xvY2FsUmVmcmVzaCcpKSB7XG4gICAgICAgICAgICAvLyAgIGNhbnZhcy5yZWZyZXNoRWxlbWVudChlbGVtZW50LCBjaGFuZ2VUeXBlLCBjYW52YXMpO1xuICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgLy8g5L2G5a+55LqOIGh0dHBzOi8vZ2l0aHViLmNvbS9hbnR2aXMvZy9pc3N1ZXMvNDIyIOeahOWcuuaZr++8jOWFqOWxgOa4suafk+eahOaooeW8j+S4i+S5n+mcgOimgeiusOW9leabtOaWsOeahOWFg+e0oOmYn+WIl1xuICAgICAgICAgICAgLy8g5aaC5p6c5b2T5YmN5YWD57Sg55qE54i25YWD57Sg5Y+R55Sf5LqG5pS55Y+Y77yM5Y+v5Lul5LiN5pS+5YWl6Zif5YiX77yM6L+Z5Y+l6K+d5aSn5qaC6IO95aSf5o+Q5Y2HIDE1JSDnmoTliJ3mrKHmuLLmn5PmgKfog71cbiAgICAgICAgICAgIGlmICghKGVsZW1lbnQuY2ZnLnBhcmVudCAmJiBlbGVtZW50LmNmZy5wYXJlbnQuZ2V0KCdoYXNDaGFuZ2VkJykpKSB7XG4gICAgICAgICAgICAgICAgY2FudmFzLnJlZnJlc2hFbGVtZW50KGVsZW1lbnQsIGNoYW5nZVR5cGUsIGNhbnZhcyk7XG4gICAgICAgICAgICAgICAgaWYgKGNhbnZhcy5nZXQoJ2F1dG9EcmF3JykpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FudmFzLmRyYXcoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVmcmVzaFJlZ2lvbihlbGVtZW50KSB7XG4gICAgdmFyIHJlZ2lvbjtcbiAgICBpZiAoIWVsZW1lbnQuZGVzdHJveWVkKSB7XG4gICAgICAgIHZhciBjYWNoZUJveCA9IGVsZW1lbnQuZ2V0KCdjYWNoZUNhbnZhc0JCb3gnKTtcbiAgICAgICAgdmFyIHZhbGlkQ2FjaGUgPSBjYWNoZUJveCAmJiAhIShjYWNoZUJveC53aWR0aCAmJiBjYWNoZUJveC5oZWlnaHQpO1xuICAgICAgICB2YXIgYmJveCA9IGVsZW1lbnQuZ2V0Q2FudmFzQkJveCgpO1xuICAgICAgICB2YXIgdmFsaWRCQm94ID0gYmJveCAmJiAhIShiYm94LndpZHRoICYmIGJib3guaGVpZ2h0KTtcbiAgICAgICAgLy8g5piv5ZCm5piv5pyJ5pWIIGJib3gg5Yik5a6a77yM5LiA5LqbIE5hTiDmiJbogIUg5a696auY5Li6IDAg55qE5oOF5Ya16L+H5ruk5o6JXG4gICAgICAgIGlmICh2YWxpZENhY2hlICYmIHZhbGlkQkJveCkge1xuICAgICAgICAgICAgcmVnaW9uID0gbWVyZ2VSZWdpb24oY2FjaGVCb3gsIGJib3gpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZhbGlkQ2FjaGUpIHtcbiAgICAgICAgICAgIHJlZ2lvbiA9IGNhY2hlQm94O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZhbGlkQkJveCkge1xuICAgICAgICAgICAgcmVnaW9uID0gYmJveDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8g5Zug5Li65YWD57Sg5bey57uP6ZSA5q+B5omA5Lul5peg5rOV6I635Y+W5Yiw57yT5a2Y55qE5YyF5Zu055uSXG4gICAgICAgIHJlZ2lvbiA9IGVsZW1lbnRbJ19jYWNoZUNhbnZhc0JCb3gnXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlZ2lvbjtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRNZXJnZWRSZWdpb24oZWxlbWVudHMpIHtcbiAgICBpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIG1pblhBcnIgPSBbXTtcbiAgICB2YXIgbWluWUFyciA9IFtdO1xuICAgIHZhciBtYXhYQXJyID0gW107XG4gICAgdmFyIG1heFlBcnIgPSBbXTtcbiAgICBlYWNoKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgdmFyIHJlZ2lvbiA9IGdldFJlZnJlc2hSZWdpb24oZWwpO1xuICAgICAgICBpZiAocmVnaW9uKSB7XG4gICAgICAgICAgICBtaW5YQXJyLnB1c2gocmVnaW9uLm1pblgpO1xuICAgICAgICAgICAgbWluWUFyci5wdXNoKHJlZ2lvbi5taW5ZKTtcbiAgICAgICAgICAgIG1heFhBcnIucHVzaChyZWdpb24ubWF4WCk7XG4gICAgICAgICAgICBtYXhZQXJyLnB1c2gocmVnaW9uLm1heFkpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbWluWDogbWluKG1pblhBcnIpLFxuICAgICAgICBtaW5ZOiBtaW4obWluWUFyciksXG4gICAgICAgIG1heFg6IG1heChtYXhYQXJyKSxcbiAgICAgICAgbWF4WTogbWF4KG1heFlBcnIpLFxuICAgIH07XG59XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VWaWV3KHJlZ2lvbiwgdmlld1JlZ2lvbikge1xuICAgIGlmICghcmVnaW9uIHx8ICF2aWV3UmVnaW9uKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyDkuI3nm7jkuqTvvIzliJnnm7TmjqXov5Tlm54gbnVsbFxuICAgIGlmICghaW50ZXJzZWN0UmVjdChyZWdpb24sIHZpZXdSZWdpb24pKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBtaW5YOiBNYXRoLm1heChyZWdpb24ubWluWCwgdmlld1JlZ2lvbi5taW5YKSxcbiAgICAgICAgbWluWTogTWF0aC5tYXgocmVnaW9uLm1pblksIHZpZXdSZWdpb24ubWluWSksXG4gICAgICAgIG1heFg6IE1hdGgubWluKHJlZ2lvbi5tYXhYLCB2aWV3UmVnaW9uLm1heFgpLFxuICAgICAgICBtYXhZOiBNYXRoLm1pbihyZWdpb24ubWF4WSwgdmlld1JlZ2lvbi5tYXhZKSxcbiAgICB9O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHJhdy5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///30\n")},function(module,exports){eval("/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXkuanM/Njc0NyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsRUFBRTtBQUNiLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEiLCJmaWxlIjoiMzEuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///31\n")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nexports.NON_CUSTOM_TAG_KEYS = exports.POST_CONSTRUCT = exports.DESIGN_PARAM_TYPES = exports.PARAM_TYPES = exports.TAGGED_PROP = exports.TAGGED = exports.MULTI_INJECT_TAG = exports.INJECT_TAG = exports.OPTIONAL_TAG = exports.UNMANAGED_TAG = exports.NAME_TAG = exports.NAMED_TAG = void 0;\nexports.NAMED_TAG = "named";\nexports.NAME_TAG = "name";\nexports.UNMANAGED_TAG = "unmanaged";\nexports.OPTIONAL_TAG = "optional";\nexports.INJECT_TAG = "inject";\nexports.MULTI_INJECT_TAG = "multi_inject";\nexports.TAGGED = "inversify:tagged";\nexports.TAGGED_PROP = "inversify:tagged_props";\nexports.PARAM_TYPES = "inversify:paramtypes";\nexports.DESIGN_PARAM_TYPES = "design:paramtypes";\nexports.POST_CONSTRUCT = "post_construct";\nfunction getNonCustomTagKeys() {\n return [\n exports.INJECT_TAG,\n exports.MULTI_INJECT_TAG,\n exports.NAME_TAG,\n exports.UNMANAGED_TAG,\n exports.NAMED_TAG,\n exports.OPTIONAL_TAG,\n ];\n}\nexports.NON_CUSTOM_TAG_KEYS = getNonCustomTagKeys();\n//# sourceMappingURL=metadata_keys.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvbWV0YWRhdGFfa2V5cy5qcz9jNWY0Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjMyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLk5PTl9DVVNUT01fVEFHX0tFWVMgPSBleHBvcnRzLlBPU1RfQ09OU1RSVUNUID0gZXhwb3J0cy5ERVNJR05fUEFSQU1fVFlQRVMgPSBleHBvcnRzLlBBUkFNX1RZUEVTID0gZXhwb3J0cy5UQUdHRURfUFJPUCA9IGV4cG9ydHMuVEFHR0VEID0gZXhwb3J0cy5NVUxUSV9JTkpFQ1RfVEFHID0gZXhwb3J0cy5JTkpFQ1RfVEFHID0gZXhwb3J0cy5PUFRJT05BTF9UQUcgPSBleHBvcnRzLlVOTUFOQUdFRF9UQUcgPSBleHBvcnRzLk5BTUVfVEFHID0gZXhwb3J0cy5OQU1FRF9UQUcgPSB2b2lkIDA7XG5leHBvcnRzLk5BTUVEX1RBRyA9IFwibmFtZWRcIjtcbmV4cG9ydHMuTkFNRV9UQUcgPSBcIm5hbWVcIjtcbmV4cG9ydHMuVU5NQU5BR0VEX1RBRyA9IFwidW5tYW5hZ2VkXCI7XG5leHBvcnRzLk9QVElPTkFMX1RBRyA9IFwib3B0aW9uYWxcIjtcbmV4cG9ydHMuSU5KRUNUX1RBRyA9IFwiaW5qZWN0XCI7XG5leHBvcnRzLk1VTFRJX0lOSkVDVF9UQUcgPSBcIm11bHRpX2luamVjdFwiO1xuZXhwb3J0cy5UQUdHRUQgPSBcImludmVyc2lmeTp0YWdnZWRcIjtcbmV4cG9ydHMuVEFHR0VEX1BST1AgPSBcImludmVyc2lmeTp0YWdnZWRfcHJvcHNcIjtcbmV4cG9ydHMuUEFSQU1fVFlQRVMgPSBcImludmVyc2lmeTpwYXJhbXR5cGVzXCI7XG5leHBvcnRzLkRFU0lHTl9QQVJBTV9UWVBFUyA9IFwiZGVzaWduOnBhcmFtdHlwZXNcIjtcbmV4cG9ydHMuUE9TVF9DT05TVFJVQ1QgPSBcInBvc3RfY29uc3RydWN0XCI7XG5mdW5jdGlvbiBnZXROb25DdXN0b21UYWdLZXlzKCkge1xuICAgIHJldHVybiBbXG4gICAgICAgIGV4cG9ydHMuSU5KRUNUX1RBRyxcbiAgICAgICAgZXhwb3J0cy5NVUxUSV9JTkpFQ1RfVEFHLFxuICAgICAgICBleHBvcnRzLk5BTUVfVEFHLFxuICAgICAgICBleHBvcnRzLlVOTUFOQUdFRF9UQUcsXG4gICAgICAgIGV4cG9ydHMuTkFNRURfVEFHLFxuICAgICAgICBleHBvcnRzLk9QVElPTkFMX1RBRyxcbiAgICBdO1xufVxuZXhwb3J0cy5OT05fQ1VTVE9NX1RBR19LRVlTID0gZ2V0Tm9uQ3VzdG9tVGFnS2V5cygpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWV0YWRhdGFfa2V5cy5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///32\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return getShortenOffset; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return addStartArrow; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return addEndArrow; });\n/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);\n/* harmony import */ var _shape__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(57);\n\n\nvar sin = Math.sin, cos = Math.cos, atan2 = Math.atan2, PI = Math.PI;\nfunction _addDefaultArrow(shape, attrs, x1, y1, x2, y2, isStart) {\n var stroke = attrs.stroke, lineWidth = attrs.lineWidth;\n var x = x1 - x2;\n var y = y1 - y2;\n var rad = atan2(y, x);\n var arrowShape = new _shape__WEBPACK_IMPORTED_MODULE_1__["Path"]({\n type: \'path\',\n canvas: shape.get(\'canvas\'),\n isArrowShape: true,\n attrs: {\n // 默认箭头的边长为 10,夹角为 60 度\n path: "M" + 10 * cos(PI / 6) + "," + 10 * sin(PI / 6) + " L0,0 L" + 10 * cos(PI / 6) + ",-" + 10 * sin(PI / 6),\n // 使用 shape stroke 值\n stroke: stroke,\n lineWidth: lineWidth,\n },\n });\n arrowShape.translate(x2, y2);\n arrowShape.rotateAtPoint(x2, y2, rad);\n shape.set(isStart ? \'startArrowShape\' : \'endArrowShape\', arrowShape);\n}\n/**\n * 箭头 path 的设置要求\n * 1. 箭头顶点坐标需要为 (0, 0)\n * 2. 箭头夹角的中心分割线需要与 X 轴正方向对齐\n */\nfunction _addCustomizedArrow(shape, attrs, x1, y1, x2, y2, isStart) {\n var startArrow = attrs.startArrow, endArrow = attrs.endArrow, stroke = attrs.stroke, lineWidth = attrs.lineWidth;\n var arrowAttrs = isStart ? startArrow : endArrow;\n var d = arrowAttrs.d, arrowFill = arrowAttrs.fill, arrowStroke = arrowAttrs.stroke, arrowLineWidth = arrowAttrs.lineWidth, restAttrs = Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__rest"])(arrowAttrs, ["d", "fill", "stroke", "lineWidth"]);\n var x = x1 - x2;\n var y = y1 - y2;\n var rad = atan2(y, x);\n if (d) {\n x2 = x2 - cos(rad) * d;\n y2 = y2 - sin(rad) * d;\n }\n var arrowShape = new _shape__WEBPACK_IMPORTED_MODULE_1__["Path"]({\n type: \'path\',\n canvas: shape.get(\'canvas\'),\n isArrowShape: true,\n attrs: Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])(Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"])({}, restAttrs), { \n // 支持单独设置箭头的 stroke 和 lineWidth,若为空则使用 shape 的值\n stroke: arrowStroke || stroke, lineWidth: arrowLineWidth || lineWidth, \n // 箭头是否填充需要手动设置,不会继承自 shape 的值\n fill: arrowFill }),\n });\n arrowShape.translate(x2, y2);\n arrowShape.rotateAtPoint(x2, y2, rad);\n shape.set(isStart ? \'startArrowShape\' : \'endArrowShape\', arrowShape);\n}\n/**\n * 如果自定义箭头并且有 d 需要做偏移,如果直接画,线条会超出箭头尖端,因此需要根据箭头偏移 d, 返回线需要缩短的距离\n * |----------------\n * |<|--------------\n * |\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 箭头作用点 x\n * @param {number} y2 箭头作用点 y\n * @param {number} d 箭头沿线条方向的偏移距离\n * @return {{dx: number, dy: number}} 返回线条偏移距离\n */\nfunction getShortenOffset(x1, y1, x2, y2, d) {\n var rad = atan2(y2 - y1, x2 - x1);\n return {\n dx: cos(rad) * d,\n dy: sin(rad) * d,\n };\n}\n/**\n * 绘制起始箭头\n * @param {IShape} shape 图形\n * @param {ShapeAttrs} attrs shape 的绘图属性\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 箭头作用点 x\n * @param {number} y2 箭头作用点 y\n */\nfunction addStartArrow(shape, attrs, x1, y1, x2, y2) {\n if (typeof attrs.startArrow === \'object\') {\n _addCustomizedArrow(shape, attrs, x1, y1, x2, y2, true);\n }\n else if (attrs.startArrow) {\n _addDefaultArrow(shape, attrs, x1, y1, x2, y2, true);\n }\n else {\n shape.set(\'startArrowShape\', null);\n }\n}\n/**\n * 绘制结束箭头\n * @param {IShape} shape 图形\n * @param {ShapeAttrs} attrs shape 的绘图属性\n * @param {number} x1 起始点 x\n * @param {number} y1 起始点 y\n * @param {number} x2 箭头作用点 x\n * @param {number} y2 箭头作用点 y\n */\nfunction addEndArrow(shape, attrs, x1, y1, x2, y2) {\n if (typeof attrs.endArrow === \'object\') {\n _addCustomizedArrow(shape, attrs, x1, y1, x2, y2, false);\n }\n else if (attrs.endArrow) {\n _addDefaultArrow(shape, attrs, x1, y1, x2, y2, false);\n }\n else {\n shape.set(\'startArrowShape\', null);\n }\n}\n//# sourceMappingURL=arrow.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvZXNtL3V0aWwvYXJyb3cuanM/OWYyNyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQXlDO0FBQ1Q7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLDJDQUFJO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMklBQTJJLG9EQUFNO0FBQ2pKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLDJDQUFJO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLGVBQWUsc0RBQVEsQ0FBQyxzREFBUSxHQUFHLGU7QUFDbkM7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsd0JBQXdCO0FBQ3JDO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsV0FBVztBQUN0QixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEI7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLFdBQVc7QUFDdEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjMzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgX19hc3NpZ24sIF9fcmVzdCB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgUGF0aCB9IGZyb20gJy4uL3NoYXBlJztcbnZhciBzaW4gPSBNYXRoLnNpbiwgY29zID0gTWF0aC5jb3MsIGF0YW4yID0gTWF0aC5hdGFuMiwgUEkgPSBNYXRoLlBJO1xuZnVuY3Rpb24gX2FkZERlZmF1bHRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyLCBpc1N0YXJ0KSB7XG4gICAgdmFyIHN0cm9rZSA9IGF0dHJzLnN0cm9rZSwgbGluZVdpZHRoID0gYXR0cnMubGluZVdpZHRoO1xuICAgIHZhciB4ID0geDEgLSB4MjtcbiAgICB2YXIgeSA9IHkxIC0geTI7XG4gICAgdmFyIHJhZCA9IGF0YW4yKHksIHgpO1xuICAgIHZhciBhcnJvd1NoYXBlID0gbmV3IFBhdGgoe1xuICAgICAgICB0eXBlOiAncGF0aCcsXG4gICAgICAgIGNhbnZhczogc2hhcGUuZ2V0KCdjYW52YXMnKSxcbiAgICAgICAgaXNBcnJvd1NoYXBlOiB0cnVlLFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgICAgLy8g6buY6K6k566t5aS055qE6L656ZW/5Li6IDEw77yM5aS56KeS5Li6IDYwIOW6plxuICAgICAgICAgICAgcGF0aDogXCJNXCIgKyAxMCAqIGNvcyhQSSAvIDYpICsgXCIsXCIgKyAxMCAqIHNpbihQSSAvIDYpICsgXCIgTDAsMCBMXCIgKyAxMCAqIGNvcyhQSSAvIDYpICsgXCIsLVwiICsgMTAgKiBzaW4oUEkgLyA2KSxcbiAgICAgICAgICAgIC8vIOS9v+eUqCBzaGFwZSBzdHJva2Ug5YC8XG4gICAgICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgICAgIGxpbmVXaWR0aDogbGluZVdpZHRoLFxuICAgICAgICB9LFxuICAgIH0pO1xuICAgIGFycm93U2hhcGUudHJhbnNsYXRlKHgyLCB5Mik7XG4gICAgYXJyb3dTaGFwZS5yb3RhdGVBdFBvaW50KHgyLCB5MiwgcmFkKTtcbiAgICBzaGFwZS5zZXQoaXNTdGFydCA/ICdzdGFydEFycm93U2hhcGUnIDogJ2VuZEFycm93U2hhcGUnLCBhcnJvd1NoYXBlKTtcbn1cbi8qKlxuICog566t5aS0IHBhdGgg55qE6K6+572u6KaB5rGCXG4gKiAxLiDnrq3lpLTpobbngrnlnZDmoIfpnIDopoHkuLogKDAsIDApXG4gKiAyLiDnrq3lpLTlpLnop5LnmoTkuK3lv4PliIblibLnur/pnIDopoHkuI4gWCDovbTmraPmlrnlkJHlr7npvZBcbiAqL1xuZnVuY3Rpb24gX2FkZEN1c3RvbWl6ZWRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyLCBpc1N0YXJ0KSB7XG4gICAgdmFyIHN0YXJ0QXJyb3cgPSBhdHRycy5zdGFydEFycm93LCBlbmRBcnJvdyA9IGF0dHJzLmVuZEFycm93LCBzdHJva2UgPSBhdHRycy5zdHJva2UsIGxpbmVXaWR0aCA9IGF0dHJzLmxpbmVXaWR0aDtcbiAgICB2YXIgYXJyb3dBdHRycyA9IGlzU3RhcnQgPyBzdGFydEFycm93IDogZW5kQXJyb3c7XG4gICAgdmFyIGQgPSBhcnJvd0F0dHJzLmQsIGFycm93RmlsbCA9IGFycm93QXR0cnMuZmlsbCwgYXJyb3dTdHJva2UgPSBhcnJvd0F0dHJzLnN0cm9rZSwgYXJyb3dMaW5lV2lkdGggPSBhcnJvd0F0dHJzLmxpbmVXaWR0aCwgcmVzdEF0dHJzID0gX19yZXN0KGFycm93QXR0cnMsIFtcImRcIiwgXCJmaWxsXCIsIFwic3Ryb2tlXCIsIFwibGluZVdpZHRoXCJdKTtcbiAgICB2YXIgeCA9IHgxIC0geDI7XG4gICAgdmFyIHkgPSB5MSAtIHkyO1xuICAgIHZhciByYWQgPSBhdGFuMih5LCB4KTtcbiAgICBpZiAoZCkge1xuICAgICAgICB4MiA9IHgyIC0gY29zKHJhZCkgKiBkO1xuICAgICAgICB5MiA9IHkyIC0gc2luKHJhZCkgKiBkO1xuICAgIH1cbiAgICB2YXIgYXJyb3dTaGFwZSA9IG5ldyBQYXRoKHtcbiAgICAgICAgdHlwZTogJ3BhdGgnLFxuICAgICAgICBjYW52YXM6IHNoYXBlLmdldCgnY2FudmFzJyksXG4gICAgICAgIGlzQXJyb3dTaGFwZTogdHJ1ZSxcbiAgICAgICAgYXR0cnM6IF9fYXNzaWduKF9fYXNzaWduKHt9LCByZXN0QXR0cnMpLCB7IFxuICAgICAgICAgICAgLy8g5pSv5oyB5Y2V54us6K6+572u566t5aS055qEIHN0cm9rZSDlkowgbGluZVdpZHRo77yM6Iul5Li656m65YiZ5L2/55SoIHNoYXBlIOeahOWAvFxuICAgICAgICAgICAgc3Ryb2tlOiBhcnJvd1N0cm9rZSB8fCBzdHJva2UsIGxpbmVXaWR0aDogYXJyb3dMaW5lV2lkdGggfHwgbGluZVdpZHRoLCBcbiAgICAgICAgICAgIC8vIOeureWktOaYr+WQpuWhq+WFhemcgOimgeaJi+WKqOiuvue9ru+8jOS4jeS8mue7p+aJv+iHqiBzaGFwZSDnmoTlgLxcbiAgICAgICAgICAgIGZpbGw6IGFycm93RmlsbCB9KSxcbiAgICB9KTtcbiAgICBhcnJvd1NoYXBlLnRyYW5zbGF0ZSh4MiwgeTIpO1xuICAgIGFycm93U2hhcGUucm90YXRlQXRQb2ludCh4MiwgeTIsIHJhZCk7XG4gICAgc2hhcGUuc2V0KGlzU3RhcnQgPyAnc3RhcnRBcnJvd1NoYXBlJyA6ICdlbmRBcnJvd1NoYXBlJywgYXJyb3dTaGFwZSk7XG59XG4vKipcbiAqIOWmguaenOiHquWumuS5ieeureWktOW5tuS4lOaciSBkIOmcgOimgeWBmuWBj+enu++8jOWmguaenOebtOaOpeeUu++8jOe6v+adoeS8mui2heWHuueureWktOWwluerr++8jOWboOatpOmcgOimgeagueaNrueureWktOWBj+enuyBkLCDov5Tlm57nur/pnIDopoHnvKnnn63nmoTot53nprtcbiAqIHwtLS0tLS0tLS0tLS0tLS0tXG4gKiB8PHwtLS0tLS0tLS0tLS0tLVxuICogfFxuICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnrq3lpLTkvZznlKjngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkyIOeureWktOS9nOeUqOeCuSB5XG4gKiBAcGFyYW0ge251bWJlcn0gZCAg566t5aS05rK/57q/5p2h5pa55ZCR55qE5YGP56e76Led56a7XG4gKiBAcmV0dXJuIHt7ZHg6IG51bWJlciwgZHk6IG51bWJlcn19IOi/lOWbnue6v+adoeWBj+enu+i3neemu1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2hvcnRlbk9mZnNldCh4MSwgeTEsIHgyLCB5MiwgZCkge1xuICAgIHZhciByYWQgPSBhdGFuMih5MiAtIHkxLCB4MiAtIHgxKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBkeDogY29zKHJhZCkgKiBkLFxuICAgICAgICBkeTogc2luKHJhZCkgKiBkLFxuICAgIH07XG59XG4vKipcbiAqIOe7mOWItui1t+Wni+eureWktFxuICogQHBhcmFtIHtJU2hhcGV9IHNoYXBlIOWbvuW9olxuICogQHBhcmFtIHtTaGFwZUF0dHJzfSBhdHRycyBzaGFwZSDnmoTnu5jlm77lsZ7mgKdcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MSDotbflp4vngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkxIOi1t+Wni+eCuSB5XG4gKiBAcGFyYW0ge251bWJlcn0geDIg566t5aS05L2c55So54K5IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSB5MiDnrq3lpLTkvZznlKjngrkgeVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkU3RhcnRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgaWYgKHR5cGVvZiBhdHRycy5zdGFydEFycm93ID09PSAnb2JqZWN0Jykge1xuICAgICAgICBfYWRkQ3VzdG9taXplZEFycm93KHNoYXBlLCBhdHRycywgeDEsIHkxLCB4MiwgeTIsIHRydWUpO1xuICAgIH1cbiAgICBlbHNlIGlmIChhdHRycy5zdGFydEFycm93KSB7XG4gICAgICAgIF9hZGREZWZhdWx0QXJyb3coc2hhcGUsIGF0dHJzLCB4MSwgeTEsIHgyLCB5MiwgdHJ1ZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzaGFwZS5zZXQoJ3N0YXJ0QXJyb3dTaGFwZScsIG51bGwpO1xuICAgIH1cbn1cbi8qKlxuICog57uY5Yi257uT5p2f566t5aS0XG4gKiBAcGFyYW0ge0lTaGFwZX0gc2hhcGUg5Zu+5b2iXG4gKiBAcGFyYW0ge1NoYXBlQXR0cnN9IGF0dHJzIHNoYXBlIOeahOe7mOWbvuWxnuaAp1xuICogQHBhcmFtIHtudW1iZXJ9IHgxIOi1t+Wni+eCuSB4XG4gKiBAcGFyYW0ge251bWJlcn0geTEg6LW35aeL54K5IHlcbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiDnrq3lpLTkvZznlKjngrkgeFxuICogQHBhcmFtIHtudW1iZXJ9IHkyIOeureWktOS9nOeUqOeCuSB5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRFbmRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgaWYgKHR5cGVvZiBhdHRycy5lbmRBcnJvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgX2FkZEN1c3RvbWl6ZWRBcnJvdyhzaGFwZSwgYXR0cnMsIHgxLCB5MSwgeDIsIHkyLCBmYWxzZSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGF0dHJzLmVuZEFycm93KSB7XG4gICAgICAgIF9hZGREZWZhdWx0QXJyb3coc2hhcGUsIGF0dHJzLCB4MSwgeTEsIHgyLCB5MiwgZmFsc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2hhcGUuc2V0KCdzdGFydEFycm93U2hhcGUnLCBudWxsKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hcnJvdy5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///33\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return setShadow; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return setTransform; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return setClip; });\n/* harmony import */ var _dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26);\n\nfunction setShadow(model, context) {\n var el = model.cfg.el;\n var attrs = model.attr();\n var cfg = {\n dx: attrs.shadowOffsetX,\n dy: attrs.shadowOffsetY,\n blur: attrs.shadowBlur,\n color: attrs.shadowColor,\n };\n if (!cfg.dx && !cfg.dy && !cfg.blur && !cfg.color) {\n el.removeAttribute('filter');\n }\n else {\n var id = context.find('filter', cfg);\n if (!id) {\n id = context.addShadow(cfg);\n }\n el.setAttribute('filter', \"url(#\" + id + \")\");\n }\n}\nfunction setTransform(model) {\n var matrix = model.attr().matrix;\n if (matrix) {\n var el = model.cfg.el;\n var transform = [];\n for (var i = 0; i < 9; i += 3) {\n transform.push(matrix[i] + \",\" + matrix[i + 1]);\n }\n transform = transform.join(',');\n if (transform.indexOf('NaN') === -1) {\n el.setAttribute('transform', \"matrix(\" + transform + \")\");\n }\n else {\n console.warn('invalid matrix:', matrix);\n }\n }\n}\nfunction setClip(model, context) {\n var clip = model.getClip();\n var el = model.get('el');\n if (!clip) {\n el.removeAttribute('clip-path');\n }\n else if (clip && !el.hasAttribute('clip-path')) {\n Object(_dom__WEBPACK_IMPORTED_MODULE_0__[/* createDom */ \"a\"])(clip);\n clip.createPath(context);\n var id = context.addClip(clip);\n el.setAttribute('clip-path', \"url(#\" + id + \")\");\n }\n}\n//# sourceMappingURL=svg.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1zdmcvZXNtL3V0aWwvc3ZnLmpzPzAwZjkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0M7QUFDM0I7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsT0FBTztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDhEQUFTO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIzNC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyZWF0ZURvbSB9IGZyb20gJy4vZG9tJztcbmV4cG9ydCBmdW5jdGlvbiBzZXRTaGFkb3cobW9kZWwsIGNvbnRleHQpIHtcbiAgICB2YXIgZWwgPSBtb2RlbC5jZmcuZWw7XG4gICAgdmFyIGF0dHJzID0gbW9kZWwuYXR0cigpO1xuICAgIHZhciBjZmcgPSB7XG4gICAgICAgIGR4OiBhdHRycy5zaGFkb3dPZmZzZXRYLFxuICAgICAgICBkeTogYXR0cnMuc2hhZG93T2Zmc2V0WSxcbiAgICAgICAgYmx1cjogYXR0cnMuc2hhZG93Qmx1cixcbiAgICAgICAgY29sb3I6IGF0dHJzLnNoYWRvd0NvbG9yLFxuICAgIH07XG4gICAgaWYgKCFjZmcuZHggJiYgIWNmZy5keSAmJiAhY2ZnLmJsdXIgJiYgIWNmZy5jb2xvcikge1xuICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2ZpbHRlcicpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmFyIGlkID0gY29udGV4dC5maW5kKCdmaWx0ZXInLCBjZmcpO1xuICAgICAgICBpZiAoIWlkKSB7XG4gICAgICAgICAgICBpZCA9IGNvbnRleHQuYWRkU2hhZG93KGNmZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdmaWx0ZXInLCBcInVybCgjXCIgKyBpZCArIFwiKVwiKTtcbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtKG1vZGVsKSB7XG4gICAgdmFyIG1hdHJpeCA9IG1vZGVsLmF0dHIoKS5tYXRyaXg7XG4gICAgaWYgKG1hdHJpeCkge1xuICAgICAgICB2YXIgZWwgPSBtb2RlbC5jZmcuZWw7XG4gICAgICAgIHZhciB0cmFuc2Zvcm0gPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA5OyBpICs9IDMpIHtcbiAgICAgICAgICAgIHRyYW5zZm9ybS5wdXNoKG1hdHJpeFtpXSArIFwiLFwiICsgbWF0cml4W2kgKyAxXSk7XG4gICAgICAgIH1cbiAgICAgICAgdHJhbnNmb3JtID0gdHJhbnNmb3JtLmpvaW4oJywnKTtcbiAgICAgICAgaWYgKHRyYW5zZm9ybS5pbmRleE9mKCdOYU4nKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywgXCJtYXRyaXgoXCIgKyB0cmFuc2Zvcm0gKyBcIilcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ2ludmFsaWQgbWF0cml4OicsIG1hdHJpeCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gc2V0Q2xpcChtb2RlbCwgY29udGV4dCkge1xuICAgIHZhciBjbGlwID0gbW9kZWwuZ2V0Q2xpcCgpO1xuICAgIHZhciBlbCA9IG1vZGVsLmdldCgnZWwnKTtcbiAgICBpZiAoIWNsaXApIHtcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCdjbGlwLXBhdGgnKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY2xpcCAmJiAhZWwuaGFzQXR0cmlidXRlKCdjbGlwLXBhdGgnKSkge1xuICAgICAgICBjcmVhdGVEb20oY2xpcCk7XG4gICAgICAgIGNsaXAuY3JlYXRlUGF0aChjb250ZXh0KTtcbiAgICAgICAgdmFyIGlkID0gY29udGV4dC5hZGRDbGlwKGNsaXApO1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsaXAtcGF0aCcsIFwidXJsKCNcIiArIGlkICsgXCIpXCIpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN2Zy5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///34\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return gl; });\n/**\n * WebGL 枚举值\n * @see http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14\n * 使用 babel 插件对常量进行内联,以减少最终打包产物大小\n * @see https://github.com/uber/deck.gl/blob/7.1-release/dev-docs/roadmaps/dist-size-roadmap.md#inline-gl-constants\n * 为了支持 WebGPU,新增 TextureUsage\n * @see https://gpuweb.github.io/gpuweb/#gputextureusage\n */\nvar gl;\n\n(function (gl) {\n gl[gl["DEPTH_BUFFER_BIT"] = 256] = "DEPTH_BUFFER_BIT";\n gl[gl["STENCIL_BUFFER_BIT"] = 1024] = "STENCIL_BUFFER_BIT";\n gl[gl["COLOR_BUFFER_BIT"] = 16384] = "COLOR_BUFFER_BIT";\n gl[gl["POINTS"] = 0] = "POINTS";\n gl[gl["LINES"] = 1] = "LINES";\n gl[gl["LINE_LOOP"] = 2] = "LINE_LOOP";\n gl[gl["LINE_STRIP"] = 3] = "LINE_STRIP";\n gl[gl["TRIANGLES"] = 4] = "TRIANGLES";\n gl[gl["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP";\n gl[gl["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN";\n gl[gl["ZERO"] = 0] = "ZERO";\n gl[gl["ONE"] = 1] = "ONE";\n gl[gl["SRC_COLOR"] = 768] = "SRC_COLOR";\n gl[gl["ONE_MINUS_SRC_COLOR"] = 769] = "ONE_MINUS_SRC_COLOR";\n gl[gl["SRC_ALPHA"] = 770] = "SRC_ALPHA";\n gl[gl["ONE_MINUS_SRC_ALPHA"] = 771] = "ONE_MINUS_SRC_ALPHA";\n gl[gl["DST_ALPHA"] = 772] = "DST_ALPHA";\n gl[gl["ONE_MINUS_DST_ALPHA"] = 773] = "ONE_MINUS_DST_ALPHA";\n gl[gl["DST_COLOR"] = 774] = "DST_COLOR";\n gl[gl["ONE_MINUS_DST_COLOR"] = 775] = "ONE_MINUS_DST_COLOR";\n gl[gl["SRC_ALPHA_SATURATE"] = 776] = "SRC_ALPHA_SATURATE";\n gl[gl["FUNC_ADD"] = 32774] = "FUNC_ADD";\n gl[gl["BLEND_EQUATION"] = 32777] = "BLEND_EQUATION";\n gl[gl["BLEND_EQUATION_RGB"] = 32777] = "BLEND_EQUATION_RGB";\n gl[gl["BLEND_EQUATION_ALPHA"] = 34877] = "BLEND_EQUATION_ALPHA";\n gl[gl["FUNC_SUBTRACT"] = 32778] = "FUNC_SUBTRACT";\n gl[gl["FUNC_REVERSE_SUBTRACT"] = 32779] = "FUNC_REVERSE_SUBTRACT";\n gl[gl["MAX_EXT"] = 32776] = "MAX_EXT";\n gl[gl["MIN_EXT"] = 32775] = "MIN_EXT";\n gl[gl["BLEND_DST_RGB"] = 32968] = "BLEND_DST_RGB";\n gl[gl["BLEND_SRC_RGB"] = 32969] = "BLEND_SRC_RGB";\n gl[gl["BLEND_DST_ALPHA"] = 32970] = "BLEND_DST_ALPHA";\n gl[gl["BLEND_SRC_ALPHA"] = 32971] = "BLEND_SRC_ALPHA";\n gl[gl["CONSTANT_COLOR"] = 32769] = "CONSTANT_COLOR";\n gl[gl["ONE_MINUS_CONSTANT_COLOR"] = 32770] = "ONE_MINUS_CONSTANT_COLOR";\n gl[gl["CONSTANT_ALPHA"] = 32771] = "CONSTANT_ALPHA";\n gl[gl["ONE_MINUS_CONSTANT_ALPHA"] = 32772] = "ONE_MINUS_CONSTANT_ALPHA";\n gl[gl["BLEND_COLOR"] = 32773] = "BLEND_COLOR";\n gl[gl["ARRAY_BUFFER"] = 34962] = "ARRAY_BUFFER";\n gl[gl["ELEMENT_ARRAY_BUFFER"] = 34963] = "ELEMENT_ARRAY_BUFFER";\n gl[gl["ARRAY_BUFFER_BINDING"] = 34964] = "ARRAY_BUFFER_BINDING";\n gl[gl["ELEMENT_ARRAY_BUFFER_BINDING"] = 34965] = "ELEMENT_ARRAY_BUFFER_BINDING";\n gl[gl["STREAM_DRAW"] = 35040] = "STREAM_DRAW";\n gl[gl["STATIC_DRAW"] = 35044] = "STATIC_DRAW";\n gl[gl["DYNAMIC_DRAW"] = 35048] = "DYNAMIC_DRAW";\n gl[gl["BUFFER_SIZE"] = 34660] = "BUFFER_SIZE";\n gl[gl["BUFFER_USAGE"] = 34661] = "BUFFER_USAGE";\n gl[gl["CURRENT_VERTEX_ATTRIB"] = 34342] = "CURRENT_VERTEX_ATTRIB";\n gl[gl["FRONT"] = 1028] = "FRONT";\n gl[gl["BACK"] = 1029] = "BACK";\n gl[gl["FRONT_AND_BACK"] = 1032] = "FRONT_AND_BACK";\n gl[gl["CULL_FACE"] = 2884] = "CULL_FACE";\n gl[gl["BLEND"] = 3042] = "BLEND";\n gl[gl["DITHER"] = 3024] = "DITHER";\n gl[gl["STENCIL_TEST"] = 2960] = "STENCIL_TEST";\n gl[gl["DEPTH_TEST"] = 2929] = "DEPTH_TEST";\n gl[gl["SCISSOR_TEST"] = 3089] = "SCISSOR_TEST";\n gl[gl["POLYGON_OFFSET_FILL"] = 32823] = "POLYGON_OFFSET_FILL";\n gl[gl["SAMPLE_ALPHA_TO_COVERAGE"] = 32926] = "SAMPLE_ALPHA_TO_COVERAGE";\n gl[gl["SAMPLE_COVERAGE"] = 32928] = "SAMPLE_COVERAGE";\n gl[gl["NO_ERROR"] = 0] = "NO_ERROR";\n gl[gl["INVALID_ENUM"] = 1280] = "INVALID_ENUM";\n gl[gl["INVALID_VALUE"] = 1281] = "INVALID_VALUE";\n gl[gl["INVALID_OPERATION"] = 1282] = "INVALID_OPERATION";\n gl[gl["OUT_OF_MEMORY"] = 1285] = "OUT_OF_MEMORY";\n gl[gl["CW"] = 2304] = "CW";\n gl[gl["CCW"] = 2305] = "CCW";\n gl[gl["LINE_WIDTH"] = 2849] = "LINE_WIDTH";\n gl[gl["ALIASED_POINT_SIZE_RANGE"] = 33901] = "ALIASED_POINT_SIZE_RANGE";\n gl[gl["ALIASED_LINE_WIDTH_RANGE"] = 33902] = "ALIASED_LINE_WIDTH_RANGE";\n gl[gl["CULL_FACE_MODE"] = 2885] = "CULL_FACE_MODE";\n gl[gl["FRONT_FACE"] = 2886] = "FRONT_FACE";\n gl[gl["DEPTH_RANGE"] = 2928] = "DEPTH_RANGE";\n gl[gl["DEPTH_WRITEMASK"] = 2930] = "DEPTH_WRITEMASK";\n gl[gl["DEPTH_CLEAR_VALUE"] = 2931] = "DEPTH_CLEAR_VALUE";\n gl[gl["DEPTH_FUNC"] = 2932] = "DEPTH_FUNC";\n gl[gl["STENCIL_CLEAR_VALUE"] = 2961] = "STENCIL_CLEAR_VALUE";\n gl[gl["STENCIL_FUNC"] = 2962] = "STENCIL_FUNC";\n gl[gl["STENCIL_FAIL"] = 2964] = "STENCIL_FAIL";\n gl[gl["STENCIL_PASS_DEPTH_FAIL"] = 2965] = "STENCIL_PASS_DEPTH_FAIL";\n gl[gl["STENCIL_PASS_DEPTH_PASS"] = 2966] = "STENCIL_PASS_DEPTH_PASS";\n gl[gl["STENCIL_REF"] = 2967] = "STENCIL_REF";\n gl[gl["STENCIL_VALUE_MASK"] = 2963] = "STENCIL_VALUE_MASK";\n gl[gl["STENCIL_WRITEMASK"] = 2968] = "STENCIL_WRITEMASK";\n gl[gl["STENCIL_BACK_FUNC"] = 34816] = "STENCIL_BACK_FUNC";\n gl[gl["STENCIL_BACK_FAIL"] = 34817] = "STENCIL_BACK_FAIL";\n gl[gl["STENCIL_BACK_PASS_DEPTH_FAIL"] = 34818] = "STENCIL_BACK_PASS_DEPTH_FAIL";\n gl[gl["STENCIL_BACK_PASS_DEPTH_PASS"] = 34819] = "STENCIL_BACK_PASS_DEPTH_PASS";\n gl[gl["STENCIL_BACK_REF"] = 36003] = "STENCIL_BACK_REF";\n gl[gl["STENCIL_BACK_VALUE_MASK"] = 36004] = "STENCIL_BACK_VALUE_MASK";\n gl[gl["STENCIL_BACK_WRITEMASK"] = 36005] = "STENCIL_BACK_WRITEMASK";\n gl[gl["VIEWPORT"] = 2978] = "VIEWPORT";\n gl[gl["SCISSOR_BOX"] = 3088] = "SCISSOR_BOX";\n gl[gl["COLOR_CLEAR_VALUE"] = 3106] = "COLOR_CLEAR_VALUE";\n gl[gl["COLOR_WRITEMASK"] = 3107] = "COLOR_WRITEMASK";\n gl[gl["UNPACK_ALIGNMENT"] = 3317] = "UNPACK_ALIGNMENT";\n gl[gl["PACK_ALIGNMENT"] = 3333] = "PACK_ALIGNMENT";\n gl[gl["MAX_TEXTURE_SIZE"] = 3379] = "MAX_TEXTURE_SIZE";\n gl[gl["MAX_VIEWPORT_DIMS"] = 3386] = "MAX_VIEWPORT_DIMS";\n gl[gl["SUBPIXEL_BITS"] = 3408] = "SUBPIXEL_BITS";\n gl[gl["RED_BITS"] = 3410] = "RED_BITS";\n gl[gl["GREEN_BITS"] = 3411] = "GREEN_BITS";\n gl[gl["BLUE_BITS"] = 3412] = "BLUE_BITS";\n gl[gl["ALPHA_BITS"] = 3413] = "ALPHA_BITS";\n gl[gl["DEPTH_BITS"] = 3414] = "DEPTH_BITS";\n gl[gl["STENCIL_BITS"] = 3415] = "STENCIL_BITS";\n gl[gl["POLYGON_OFFSET_UNITS"] = 10752] = "POLYGON_OFFSET_UNITS";\n gl[gl["POLYGON_OFFSET_FACTOR"] = 32824] = "POLYGON_OFFSET_FACTOR";\n gl[gl["TEXTURE_BINDING_2D"] = 32873] = "TEXTURE_BINDING_2D";\n gl[gl["SAMPLE_BUFFERS"] = 32936] = "SAMPLE_BUFFERS";\n gl[gl["SAMPLES"] = 32937] = "SAMPLES";\n gl[gl["SAMPLE_COVERAGE_VALUE"] = 32938] = "SAMPLE_COVERAGE_VALUE";\n gl[gl["SAMPLE_COVERAGE_INVERT"] = 32939] = "SAMPLE_COVERAGE_INVERT";\n gl[gl["COMPRESSED_TEXTURE_FORMATS"] = 34467] = "COMPRESSED_TEXTURE_FORMATS";\n gl[gl["DONT_CARE"] = 4352] = "DONT_CARE";\n gl[gl["FASTEST"] = 4353] = "FASTEST";\n gl[gl["NICEST"] = 4354] = "NICEST";\n gl[gl["GENERATE_MIPMAP_HINT"] = 33170] = "GENERATE_MIPMAP_HINT";\n gl[gl["BYTE"] = 5120] = "BYTE";\n gl[gl["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE";\n gl[gl["SHORT"] = 5122] = "SHORT";\n gl[gl["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT";\n gl[gl["INT"] = 5124] = "INT";\n gl[gl["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT";\n gl[gl["FLOAT"] = 5126] = "FLOAT";\n gl[gl["DEPTH_COMPONENT"] = 6402] = "DEPTH_COMPONENT";\n gl[gl["ALPHA"] = 6406] = "ALPHA";\n gl[gl["RGB"] = 6407] = "RGB";\n gl[gl["RGBA"] = 6408] = "RGBA";\n gl[gl["LUMINANCE"] = 6409] = "LUMINANCE";\n gl[gl["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA";\n gl[gl["UNSIGNED_SHORT_4_4_4_4"] = 32819] = "UNSIGNED_SHORT_4_4_4_4";\n gl[gl["UNSIGNED_SHORT_5_5_5_1"] = 32820] = "UNSIGNED_SHORT_5_5_5_1";\n gl[gl["UNSIGNED_SHORT_5_6_5"] = 33635] = "UNSIGNED_SHORT_5_6_5";\n gl[gl["FRAGMENT_SHADER"] = 35632] = "FRAGMENT_SHADER";\n gl[gl["VERTEX_SHADER"] = 35633] = "VERTEX_SHADER";\n gl[gl["MAX_VERTEX_ATTRIBS"] = 34921] = "MAX_VERTEX_ATTRIBS";\n gl[gl["MAX_VERTEX_UNIFORM_VECTORS"] = 36347] = "MAX_VERTEX_UNIFORM_VECTORS";\n gl[gl["MAX_VARYING_VECTORS"] = 36348] = "MAX_VARYING_VECTORS";\n gl[gl["MAX_COMBINED_TEXTURE_IMAGE_UNITS"] = 35661] = "MAX_COMBINED_TEXTURE_IMAGE_UNITS";\n gl[gl["MAX_VERTEX_TEXTURE_IMAGE_UNITS"] = 35660] = "MAX_VERTEX_TEXTURE_IMAGE_UNITS";\n gl[gl["MAX_TEXTURE_IMAGE_UNITS"] = 34930] = "MAX_TEXTURE_IMAGE_UNITS";\n gl[gl["MAX_FRAGMENT_UNIFORM_VECTORS"] = 36349] = "MAX_FRAGMENT_UNIFORM_VECTORS";\n gl[gl["SHADER_TYPE"] = 35663] = "SHADER_TYPE";\n gl[gl["DELETE_STATUS"] = 35712] = "DELETE_STATUS";\n gl[gl["LINK_STATUS"] = 35714] = "LINK_STATUS";\n gl[gl["VALIDATE_STATUS"] = 35715] = "VALIDATE_STATUS";\n gl[gl["ATTACHED_SHADERS"] = 35717] = "ATTACHED_SHADERS";\n gl[gl["ACTIVE_UNIFORMS"] = 35718] = "ACTIVE_UNIFORMS";\n gl[gl["ACTIVE_ATTRIBUTES"] = 35721] = "ACTIVE_ATTRIBUTES";\n gl[gl["SHADING_LANGUAGE_VERSION"] = 35724] = "SHADING_LANGUAGE_VERSION";\n gl[gl["CURRENT_PROGRAM"] = 35725] = "CURRENT_PROGRAM";\n gl[gl["NEVER"] = 512] = "NEVER";\n gl[gl["LESS"] = 513] = "LESS";\n gl[gl["EQUAL"] = 514] = "EQUAL";\n gl[gl["LEQUAL"] = 515] = "LEQUAL";\n gl[gl["GREATER"] = 516] = "GREATER";\n gl[gl["NOTEQUAL"] = 517] = "NOTEQUAL";\n gl[gl["GEQUAL"] = 518] = "GEQUAL";\n gl[gl["ALWAYS"] = 519] = "ALWAYS";\n gl[gl["KEEP"] = 7680] = "KEEP";\n gl[gl["REPLACE"] = 7681] = "REPLACE";\n gl[gl["INCR"] = 7682] = "INCR";\n gl[gl["DECR"] = 7683] = "DECR";\n gl[gl["INVERT"] = 5386] = "INVERT";\n gl[gl["INCR_WRAP"] = 34055] = "INCR_WRAP";\n gl[gl["DECR_WRAP"] = 34056] = "DECR_WRAP";\n gl[gl["VENDOR"] = 7936] = "VENDOR";\n gl[gl["RENDERER"] = 7937] = "RENDERER";\n gl[gl["VERSION"] = 7938] = "VERSION";\n gl[gl["NEAREST"] = 9728] = "NEAREST";\n gl[gl["LINEAR"] = 9729] = "LINEAR";\n gl[gl["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST";\n gl[gl["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST";\n gl[gl["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR";\n gl[gl["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR";\n gl[gl["TEXTURE_MAG_FILTER"] = 10240] = "TEXTURE_MAG_FILTER";\n gl[gl["TEXTURE_MIN_FILTER"] = 10241] = "TEXTURE_MIN_FILTER";\n gl[gl["TEXTURE_WRAP_S"] = 10242] = "TEXTURE_WRAP_S";\n gl[gl["TEXTURE_WRAP_T"] = 10243] = "TEXTURE_WRAP_T";\n gl[gl["TEXTURE_2D"] = 3553] = "TEXTURE_2D";\n gl[gl["TEXTURE"] = 5890] = "TEXTURE";\n gl[gl["TEXTURE_CUBE_MAP"] = 34067] = "TEXTURE_CUBE_MAP";\n gl[gl["TEXTURE_BINDING_CUBE_MAP"] = 34068] = "TEXTURE_BINDING_CUBE_MAP";\n gl[gl["TEXTURE_CUBE_MAP_POSITIVE_X"] = 34069] = "TEXTURE_CUBE_MAP_POSITIVE_X";\n gl[gl["TEXTURE_CUBE_MAP_NEGATIVE_X"] = 34070] = "TEXTURE_CUBE_MAP_NEGATIVE_X";\n gl[gl["TEXTURE_CUBE_MAP_POSITIVE_Y"] = 34071] = "TEXTURE_CUBE_MAP_POSITIVE_Y";\n gl[gl["TEXTURE_CUBE_MAP_NEGATIVE_Y"] = 34072] = "TEXTURE_CUBE_MAP_NEGATIVE_Y";\n gl[gl["TEXTURE_CUBE_MAP_POSITIVE_Z"] = 34073] = "TEXTURE_CUBE_MAP_POSITIVE_Z";\n gl[gl["TEXTURE_CUBE_MAP_NEGATIVE_Z"] = 34074] = "TEXTURE_CUBE_MAP_NEGATIVE_Z";\n gl[gl["MAX_CUBE_MAP_TEXTURE_SIZE"] = 34076] = "MAX_CUBE_MAP_TEXTURE_SIZE";\n gl[gl["TEXTURE0"] = 33984] = "TEXTURE0";\n gl[gl["TEXTURE1"] = 33985] = "TEXTURE1";\n gl[gl["TEXTURE2"] = 33986] = "TEXTURE2";\n gl[gl["TEXTURE3"] = 33987] = "TEXTURE3";\n gl[gl["TEXTURE4"] = 33988] = "TEXTURE4";\n gl[gl["TEXTURE5"] = 33989] = "TEXTURE5";\n gl[gl["TEXTURE6"] = 33990] = "TEXTURE6";\n gl[gl["TEXTURE7"] = 33991] = "TEXTURE7";\n gl[gl["TEXTURE8"] = 33992] = "TEXTURE8";\n gl[gl["TEXTURE9"] = 33993] = "TEXTURE9";\n gl[gl["TEXTURE10"] = 33994] = "TEXTURE10";\n gl[gl["TEXTURE11"] = 33995] = "TEXTURE11";\n gl[gl["TEXTURE12"] = 33996] = "TEXTURE12";\n gl[gl["TEXTURE13"] = 33997] = "TEXTURE13";\n gl[gl["TEXTURE14"] = 33998] = "TEXTURE14";\n gl[gl["TEXTURE15"] = 33999] = "TEXTURE15";\n gl[gl["TEXTURE16"] = 34000] = "TEXTURE16";\n gl[gl["TEXTURE17"] = 34001] = "TEXTURE17";\n gl[gl["TEXTURE18"] = 34002] = "TEXTURE18";\n gl[gl["TEXTURE19"] = 34003] = "TEXTURE19";\n gl[gl["TEXTURE20"] = 34004] = "TEXTURE20";\n gl[gl["TEXTURE21"] = 34005] = "TEXTURE21";\n gl[gl["TEXTURE22"] = 34006] = "TEXTURE22";\n gl[gl["TEXTURE23"] = 34007] = "TEXTURE23";\n gl[gl["TEXTURE24"] = 34008] = "TEXTURE24";\n gl[gl["TEXTURE25"] = 34009] = "TEXTURE25";\n gl[gl["TEXTURE26"] = 34010] = "TEXTURE26";\n gl[gl["TEXTURE27"] = 34011] = "TEXTURE27";\n gl[gl["TEXTURE28"] = 34012] = "TEXTURE28";\n gl[gl["TEXTURE29"] = 34013] = "TEXTURE29";\n gl[gl["TEXTURE30"] = 34014] = "TEXTURE30";\n gl[gl["TEXTURE31"] = 34015] = "TEXTURE31";\n gl[gl["ACTIVE_TEXTURE"] = 34016] = "ACTIVE_TEXTURE";\n gl[gl["REPEAT"] = 10497] = "REPEAT";\n gl[gl["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE";\n gl[gl["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT";\n gl[gl["FLOAT_VEC2"] = 35664] = "FLOAT_VEC2";\n gl[gl["FLOAT_VEC3"] = 35665] = "FLOAT_VEC3";\n gl[gl["FLOAT_VEC4"] = 35666] = "FLOAT_VEC4";\n gl[gl["INT_VEC2"] = 35667] = "INT_VEC2";\n gl[gl["INT_VEC3"] = 35668] = "INT_VEC3";\n gl[gl["INT_VEC4"] = 35669] = "INT_VEC4";\n gl[gl["BOOL"] = 35670] = "BOOL";\n gl[gl["BOOL_VEC2"] = 35671] = "BOOL_VEC2";\n gl[gl["BOOL_VEC3"] = 35672] = "BOOL_VEC3";\n gl[gl["BOOL_VEC4"] = 35673] = "BOOL_VEC4";\n gl[gl["FLOAT_MAT2"] = 35674] = "FLOAT_MAT2";\n gl[gl["FLOAT_MAT3"] = 35675] = "FLOAT_MAT3";\n gl[gl["FLOAT_MAT4"] = 35676] = "FLOAT_MAT4";\n gl[gl["SAMPLER_2D"] = 35678] = "SAMPLER_2D";\n gl[gl["SAMPLER_CUBE"] = 35680] = "SAMPLER_CUBE";\n gl[gl["VERTEX_ATTRIB_ARRAY_ENABLED"] = 34338] = "VERTEX_ATTRIB_ARRAY_ENABLED";\n gl[gl["VERTEX_ATTRIB_ARRAY_SIZE"] = 34339] = "VERTEX_ATTRIB_ARRAY_SIZE";\n gl[gl["VERTEX_ATTRIB_ARRAY_STRIDE"] = 34340] = "VERTEX_ATTRIB_ARRAY_STRIDE";\n gl[gl["VERTEX_ATTRIB_ARRAY_TYPE"] = 34341] = "VERTEX_ATTRIB_ARRAY_TYPE";\n gl[gl["VERTEX_ATTRIB_ARRAY_NORMALIZED"] = 34922] = "VERTEX_ATTRIB_ARRAY_NORMALIZED";\n gl[gl["VERTEX_ATTRIB_ARRAY_POINTER"] = 34373] = "VERTEX_ATTRIB_ARRAY_POINTER";\n gl[gl["VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"] = 34975] = "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING";\n gl[gl["COMPILE_STATUS"] = 35713] = "COMPILE_STATUS";\n gl[gl["LOW_FLOAT"] = 36336] = "LOW_FLOAT";\n gl[gl["MEDIUM_FLOAT"] = 36337] = "MEDIUM_FLOAT";\n gl[gl["HIGH_FLOAT"] = 36338] = "HIGH_FLOAT";\n gl[gl["LOW_INT"] = 36339] = "LOW_INT";\n gl[gl["MEDIUM_INT"] = 36340] = "MEDIUM_INT";\n gl[gl["HIGH_INT"] = 36341] = "HIGH_INT";\n gl[gl["FRAMEBUFFER"] = 36160] = "FRAMEBUFFER";\n gl[gl["RENDERBUFFER"] = 36161] = "RENDERBUFFER";\n gl[gl["RGBA4"] = 32854] = "RGBA4";\n gl[gl["RGB5_A1"] = 32855] = "RGB5_A1";\n gl[gl["RGB565"] = 36194] = "RGB565";\n gl[gl["DEPTH_COMPONENT16"] = 33189] = "DEPTH_COMPONENT16";\n gl[gl["STENCIL_INDEX"] = 6401] = "STENCIL_INDEX";\n gl[gl["STENCIL_INDEX8"] = 36168] = "STENCIL_INDEX8";\n gl[gl["DEPTH_STENCIL"] = 34041] = "DEPTH_STENCIL";\n gl[gl["RENDERBUFFER_WIDTH"] = 36162] = "RENDERBUFFER_WIDTH";\n gl[gl["RENDERBUFFER_HEIGHT"] = 36163] = "RENDERBUFFER_HEIGHT";\n gl[gl["RENDERBUFFER_INTERNAL_FORMAT"] = 36164] = "RENDERBUFFER_INTERNAL_FORMAT";\n gl[gl["RENDERBUFFER_RED_SIZE"] = 36176] = "RENDERBUFFER_RED_SIZE";\n gl[gl["RENDERBUFFER_GREEN_SIZE"] = 36177] = "RENDERBUFFER_GREEN_SIZE";\n gl[gl["RENDERBUFFER_BLUE_SIZE"] = 36178] = "RENDERBUFFER_BLUE_SIZE";\n gl[gl["RENDERBUFFER_ALPHA_SIZE"] = 36179] = "RENDERBUFFER_ALPHA_SIZE";\n gl[gl["RENDERBUFFER_DEPTH_SIZE"] = 36180] = "RENDERBUFFER_DEPTH_SIZE";\n gl[gl["RENDERBUFFER_STENCIL_SIZE"] = 36181] = "RENDERBUFFER_STENCIL_SIZE";\n gl[gl["FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE"] = 36048] = "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE";\n gl[gl["FRAMEBUFFER_ATTACHMENT_OBJECT_NAME"] = 36049] = "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME";\n gl[gl["FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL"] = 36050] = "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL";\n gl[gl["FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE"] = 36051] = "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE";\n gl[gl["COLOR_ATTACHMENT0"] = 36064] = "COLOR_ATTACHMENT0";\n gl[gl["DEPTH_ATTACHMENT"] = 36096] = "DEPTH_ATTACHMENT";\n gl[gl["STENCIL_ATTACHMENT"] = 36128] = "STENCIL_ATTACHMENT";\n gl[gl["DEPTH_STENCIL_ATTACHMENT"] = 33306] = "DEPTH_STENCIL_ATTACHMENT";\n gl[gl["NONE"] = 0] = "NONE";\n gl[gl["FRAMEBUFFER_COMPLETE"] = 36053] = "FRAMEBUFFER_COMPLETE";\n gl[gl["FRAMEBUFFER_INCOMPLETE_ATTACHMENT"] = 36054] = "FRAMEBUFFER_INCOMPLETE_ATTACHMENT";\n gl[gl["FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"] = 36055] = "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";\n gl[gl["FRAMEBUFFER_INCOMPLETE_DIMENSIONS"] = 36057] = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";\n gl[gl["FRAMEBUFFER_UNSUPPORTED"] = 36061] = "FRAMEBUFFER_UNSUPPORTED";\n gl[gl["FRAMEBUFFER_BINDING"] = 36006] = "FRAMEBUFFER_BINDING";\n gl[gl["RENDERBUFFER_BINDING"] = 36007] = "RENDERBUFFER_BINDING";\n gl[gl["MAX_RENDERBUFFER_SIZE"] = 34024] = "MAX_RENDERBUFFER_SIZE";\n gl[gl["INVALID_FRAMEBUFFER_OPERATION"] = 1286] = "INVALID_FRAMEBUFFER_OPERATION";\n gl[gl["UNPACK_FLIP_Y_WEBGL"] = 37440] = "UNPACK_FLIP_Y_WEBGL";\n gl[gl["UNPACK_PREMULTIPLY_ALPHA_WEBGL"] = 37441] = "UNPACK_PREMULTIPLY_ALPHA_WEBGL";\n gl[gl["CONTEXT_LOST_WEBGL"] = 37442] = "CONTEXT_LOST_WEBGL";\n gl[gl["UNPACK_COLORSPACE_CONVERSION_WEBGL"] = 37443] = "UNPACK_COLORSPACE_CONVERSION_WEBGL";\n gl[gl["BROWSER_DEFAULT_WEBGL"] = 37444] = "BROWSER_DEFAULT_WEBGL";\n gl[gl["COPY_SRC"] = 1] = "COPY_SRC";\n gl[gl["COPY_DST"] = 2] = "COPY_DST";\n gl[gl["SAMPLED"] = 4] = "SAMPLED";\n gl[gl["STORAGE"] = 8] = "STORAGE";\n gl[gl["RENDER_ATTACHMENT"] = 16] = "RENDER_ATTACHMENT";\n})(gl || (gl = {}));\n//# sourceMappingURL=gl.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy13ZWJncHUtY29yZS9lcy9jb21wb25lbnRzL3JlbmRlcmVyL2dsLmpzPzkzYWMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyxnQkFBZ0I7QUFDakIiLCJmaWxlIjoiMzUuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFdlYkdMIOaemuS4vuWAvFxuICogQHNlZSBodHRwOi8vd3d3Lmtocm9ub3Mub3JnL3JlZ2lzdHJ5L3dlYmdsL3NwZWNzL2xhdGVzdC8xLjAvIzUuMTRcbiAqIOS9v+eUqCBiYWJlbCDmj5Lku7blr7nluLjph4/ov5vooYzlhoXogZTvvIzku6Xlh4/lsJHmnIDnu4jmiZPljIXkuqfnianlpKflsI9cbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3ViZXIvZGVjay5nbC9ibG9iLzcuMS1yZWxlYXNlL2Rldi1kb2NzL3JvYWRtYXBzL2Rpc3Qtc2l6ZS1yb2FkbWFwLm1kI2lubGluZS1nbC1jb25zdGFudHNcbiAqIOS4uuS6huaUr+aMgSBXZWJHUFXvvIzmlrDlop4gVGV4dHVyZVVzYWdlXG4gKiBAc2VlIGh0dHBzOi8vZ3B1d2ViLmdpdGh1Yi5pby9ncHV3ZWIvI2dwdXRleHR1cmV1c2FnZVxuICovXG5leHBvcnQgdmFyIGdsO1xuXG4oZnVuY3Rpb24gKGdsKSB7XG4gIGdsW2dsW1wiREVQVEhfQlVGRkVSX0JJVFwiXSA9IDI1Nl0gPSBcIkRFUFRIX0JVRkZFUl9CSVRcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JVRkZFUl9CSVRcIl0gPSAxMDI0XSA9IFwiU1RFTkNJTF9CVUZGRVJfQklUXCI7XG4gIGdsW2dsW1wiQ09MT1JfQlVGRkVSX0JJVFwiXSA9IDE2Mzg0XSA9IFwiQ09MT1JfQlVGRkVSX0JJVFwiO1xuICBnbFtnbFtcIlBPSU5UU1wiXSA9IDBdID0gXCJQT0lOVFNcIjtcbiAgZ2xbZ2xbXCJMSU5FU1wiXSA9IDFdID0gXCJMSU5FU1wiO1xuICBnbFtnbFtcIkxJTkVfTE9PUFwiXSA9IDJdID0gXCJMSU5FX0xPT1BcIjtcbiAgZ2xbZ2xbXCJMSU5FX1NUUklQXCJdID0gM10gPSBcIkxJTkVfU1RSSVBcIjtcbiAgZ2xbZ2xbXCJUUklBTkdMRVNcIl0gPSA0XSA9IFwiVFJJQU5HTEVTXCI7XG4gIGdsW2dsW1wiVFJJQU5HTEVfU1RSSVBcIl0gPSA1XSA9IFwiVFJJQU5HTEVfU1RSSVBcIjtcbiAgZ2xbZ2xbXCJUUklBTkdMRV9GQU5cIl0gPSA2XSA9IFwiVFJJQU5HTEVfRkFOXCI7XG4gIGdsW2dsW1wiWkVST1wiXSA9IDBdID0gXCJaRVJPXCI7XG4gIGdsW2dsW1wiT05FXCJdID0gMV0gPSBcIk9ORVwiO1xuICBnbFtnbFtcIlNSQ19DT0xPUlwiXSA9IDc2OF0gPSBcIlNSQ19DT0xPUlwiO1xuICBnbFtnbFtcIk9ORV9NSU5VU19TUkNfQ09MT1JcIl0gPSA3NjldID0gXCJPTkVfTUlOVVNfU1JDX0NPTE9SXCI7XG4gIGdsW2dsW1wiU1JDX0FMUEhBXCJdID0gNzcwXSA9IFwiU1JDX0FMUEhBXCI7XG4gIGdsW2dsW1wiT05FX01JTlVTX1NSQ19BTFBIQVwiXSA9IDc3MV0gPSBcIk9ORV9NSU5VU19TUkNfQUxQSEFcIjtcbiAgZ2xbZ2xbXCJEU1RfQUxQSEFcIl0gPSA3NzJdID0gXCJEU1RfQUxQSEFcIjtcbiAgZ2xbZ2xbXCJPTkVfTUlOVVNfRFNUX0FMUEhBXCJdID0gNzczXSA9IFwiT05FX01JTlVTX0RTVF9BTFBIQVwiO1xuICBnbFtnbFtcIkRTVF9DT0xPUlwiXSA9IDc3NF0gPSBcIkRTVF9DT0xPUlwiO1xuICBnbFtnbFtcIk9ORV9NSU5VU19EU1RfQ09MT1JcIl0gPSA3NzVdID0gXCJPTkVfTUlOVVNfRFNUX0NPTE9SXCI7XG4gIGdsW2dsW1wiU1JDX0FMUEhBX1NBVFVSQVRFXCJdID0gNzc2XSA9IFwiU1JDX0FMUEhBX1NBVFVSQVRFXCI7XG4gIGdsW2dsW1wiRlVOQ19BRERcIl0gPSAzMjc3NF0gPSBcIkZVTkNfQUREXCI7XG4gIGdsW2dsW1wiQkxFTkRfRVFVQVRJT05cIl0gPSAzMjc3N10gPSBcIkJMRU5EX0VRVUFUSU9OXCI7XG4gIGdsW2dsW1wiQkxFTkRfRVFVQVRJT05fUkdCXCJdID0gMzI3NzddID0gXCJCTEVORF9FUVVBVElPTl9SR0JcIjtcbiAgZ2xbZ2xbXCJCTEVORF9FUVVBVElPTl9BTFBIQVwiXSA9IDM0ODc3XSA9IFwiQkxFTkRfRVFVQVRJT05fQUxQSEFcIjtcbiAgZ2xbZ2xbXCJGVU5DX1NVQlRSQUNUXCJdID0gMzI3NzhdID0gXCJGVU5DX1NVQlRSQUNUXCI7XG4gIGdsW2dsW1wiRlVOQ19SRVZFUlNFX1NVQlRSQUNUXCJdID0gMzI3NzldID0gXCJGVU5DX1JFVkVSU0VfU1VCVFJBQ1RcIjtcbiAgZ2xbZ2xbXCJNQVhfRVhUXCJdID0gMzI3NzZdID0gXCJNQVhfRVhUXCI7XG4gIGdsW2dsW1wiTUlOX0VYVFwiXSA9IDMyNzc1XSA9IFwiTUlOX0VYVFwiO1xuICBnbFtnbFtcIkJMRU5EX0RTVF9SR0JcIl0gPSAzMjk2OF0gPSBcIkJMRU5EX0RTVF9SR0JcIjtcbiAgZ2xbZ2xbXCJCTEVORF9TUkNfUkdCXCJdID0gMzI5NjldID0gXCJCTEVORF9TUkNfUkdCXCI7XG4gIGdsW2dsW1wiQkxFTkRfRFNUX0FMUEhBXCJdID0gMzI5NzBdID0gXCJCTEVORF9EU1RfQUxQSEFcIjtcbiAgZ2xbZ2xbXCJCTEVORF9TUkNfQUxQSEFcIl0gPSAzMjk3MV0gPSBcIkJMRU5EX1NSQ19BTFBIQVwiO1xuICBnbFtnbFtcIkNPTlNUQU5UX0NPTE9SXCJdID0gMzI3NjldID0gXCJDT05TVEFOVF9DT0xPUlwiO1xuICBnbFtnbFtcIk9ORV9NSU5VU19DT05TVEFOVF9DT0xPUlwiXSA9IDMyNzcwXSA9IFwiT05FX01JTlVTX0NPTlNUQU5UX0NPTE9SXCI7XG4gIGdsW2dsW1wiQ09OU1RBTlRfQUxQSEFcIl0gPSAzMjc3MV0gPSBcIkNPTlNUQU5UX0FMUEhBXCI7XG4gIGdsW2dsW1wiT05FX01JTlVTX0NPTlNUQU5UX0FMUEhBXCJdID0gMzI3NzJdID0gXCJPTkVfTUlOVVNfQ09OU1RBTlRfQUxQSEFcIjtcbiAgZ2xbZ2xbXCJCTEVORF9DT0xPUlwiXSA9IDMyNzczXSA9IFwiQkxFTkRfQ09MT1JcIjtcbiAgZ2xbZ2xbXCJBUlJBWV9CVUZGRVJcIl0gPSAzNDk2Ml0gPSBcIkFSUkFZX0JVRkZFUlwiO1xuICBnbFtnbFtcIkVMRU1FTlRfQVJSQVlfQlVGRkVSXCJdID0gMzQ5NjNdID0gXCJFTEVNRU5UX0FSUkFZX0JVRkZFUlwiO1xuICBnbFtnbFtcIkFSUkFZX0JVRkZFUl9CSU5ESU5HXCJdID0gMzQ5NjRdID0gXCJBUlJBWV9CVUZGRVJfQklORElOR1wiO1xuICBnbFtnbFtcIkVMRU1FTlRfQVJSQVlfQlVGRkVSX0JJTkRJTkdcIl0gPSAzNDk2NV0gPSBcIkVMRU1FTlRfQVJSQVlfQlVGRkVSX0JJTkRJTkdcIjtcbiAgZ2xbZ2xbXCJTVFJFQU1fRFJBV1wiXSA9IDM1MDQwXSA9IFwiU1RSRUFNX0RSQVdcIjtcbiAgZ2xbZ2xbXCJTVEFUSUNfRFJBV1wiXSA9IDM1MDQ0XSA9IFwiU1RBVElDX0RSQVdcIjtcbiAgZ2xbZ2xbXCJEWU5BTUlDX0RSQVdcIl0gPSAzNTA0OF0gPSBcIkRZTkFNSUNfRFJBV1wiO1xuICBnbFtnbFtcIkJVRkZFUl9TSVpFXCJdID0gMzQ2NjBdID0gXCJCVUZGRVJfU0laRVwiO1xuICBnbFtnbFtcIkJVRkZFUl9VU0FHRVwiXSA9IDM0NjYxXSA9IFwiQlVGRkVSX1VTQUdFXCI7XG4gIGdsW2dsW1wiQ1VSUkVOVF9WRVJURVhfQVRUUklCXCJdID0gMzQzNDJdID0gXCJDVVJSRU5UX1ZFUlRFWF9BVFRSSUJcIjtcbiAgZ2xbZ2xbXCJGUk9OVFwiXSA9IDEwMjhdID0gXCJGUk9OVFwiO1xuICBnbFtnbFtcIkJBQ0tcIl0gPSAxMDI5XSA9IFwiQkFDS1wiO1xuICBnbFtnbFtcIkZST05UX0FORF9CQUNLXCJdID0gMTAzMl0gPSBcIkZST05UX0FORF9CQUNLXCI7XG4gIGdsW2dsW1wiQ1VMTF9GQUNFXCJdID0gMjg4NF0gPSBcIkNVTExfRkFDRVwiO1xuICBnbFtnbFtcIkJMRU5EXCJdID0gMzA0Ml0gPSBcIkJMRU5EXCI7XG4gIGdsW2dsW1wiRElUSEVSXCJdID0gMzAyNF0gPSBcIkRJVEhFUlwiO1xuICBnbFtnbFtcIlNURU5DSUxfVEVTVFwiXSA9IDI5NjBdID0gXCJTVEVOQ0lMX1RFU1RcIjtcbiAgZ2xbZ2xbXCJERVBUSF9URVNUXCJdID0gMjkyOV0gPSBcIkRFUFRIX1RFU1RcIjtcbiAgZ2xbZ2xbXCJTQ0lTU09SX1RFU1RcIl0gPSAzMDg5XSA9IFwiU0NJU1NPUl9URVNUXCI7XG4gIGdsW2dsW1wiUE9MWUdPTl9PRkZTRVRfRklMTFwiXSA9IDMyODIzXSA9IFwiUE9MWUdPTl9PRkZTRVRfRklMTFwiO1xuICBnbFtnbFtcIlNBTVBMRV9BTFBIQV9UT19DT1ZFUkFHRVwiXSA9IDMyOTI2XSA9IFwiU0FNUExFX0FMUEhBX1RPX0NPVkVSQUdFXCI7XG4gIGdsW2dsW1wiU0FNUExFX0NPVkVSQUdFXCJdID0gMzI5MjhdID0gXCJTQU1QTEVfQ09WRVJBR0VcIjtcbiAgZ2xbZ2xbXCJOT19FUlJPUlwiXSA9IDBdID0gXCJOT19FUlJPUlwiO1xuICBnbFtnbFtcIklOVkFMSURfRU5VTVwiXSA9IDEyODBdID0gXCJJTlZBTElEX0VOVU1cIjtcbiAgZ2xbZ2xbXCJJTlZBTElEX1ZBTFVFXCJdID0gMTI4MV0gPSBcIklOVkFMSURfVkFMVUVcIjtcbiAgZ2xbZ2xbXCJJTlZBTElEX09QRVJBVElPTlwiXSA9IDEyODJdID0gXCJJTlZBTElEX09QRVJBVElPTlwiO1xuICBnbFtnbFtcIk9VVF9PRl9NRU1PUllcIl0gPSAxMjg1XSA9IFwiT1VUX09GX01FTU9SWVwiO1xuICBnbFtnbFtcIkNXXCJdID0gMjMwNF0gPSBcIkNXXCI7XG4gIGdsW2dsW1wiQ0NXXCJdID0gMjMwNV0gPSBcIkNDV1wiO1xuICBnbFtnbFtcIkxJTkVfV0lEVEhcIl0gPSAyODQ5XSA9IFwiTElORV9XSURUSFwiO1xuICBnbFtnbFtcIkFMSUFTRURfUE9JTlRfU0laRV9SQU5HRVwiXSA9IDMzOTAxXSA9IFwiQUxJQVNFRF9QT0lOVF9TSVpFX1JBTkdFXCI7XG4gIGdsW2dsW1wiQUxJQVNFRF9MSU5FX1dJRFRIX1JBTkdFXCJdID0gMzM5MDJdID0gXCJBTElBU0VEX0xJTkVfV0lEVEhfUkFOR0VcIjtcbiAgZ2xbZ2xbXCJDVUxMX0ZBQ0VfTU9ERVwiXSA9IDI4ODVdID0gXCJDVUxMX0ZBQ0VfTU9ERVwiO1xuICBnbFtnbFtcIkZST05UX0ZBQ0VcIl0gPSAyODg2XSA9IFwiRlJPTlRfRkFDRVwiO1xuICBnbFtnbFtcIkRFUFRIX1JBTkdFXCJdID0gMjkyOF0gPSBcIkRFUFRIX1JBTkdFXCI7XG4gIGdsW2dsW1wiREVQVEhfV1JJVEVNQVNLXCJdID0gMjkzMF0gPSBcIkRFUFRIX1dSSVRFTUFTS1wiO1xuICBnbFtnbFtcIkRFUFRIX0NMRUFSX1ZBTFVFXCJdID0gMjkzMV0gPSBcIkRFUFRIX0NMRUFSX1ZBTFVFXCI7XG4gIGdsW2dsW1wiREVQVEhfRlVOQ1wiXSA9IDI5MzJdID0gXCJERVBUSF9GVU5DXCI7XG4gIGdsW2dsW1wiU1RFTkNJTF9DTEVBUl9WQUxVRVwiXSA9IDI5NjFdID0gXCJTVEVOQ0lMX0NMRUFSX1ZBTFVFXCI7XG4gIGdsW2dsW1wiU1RFTkNJTF9GVU5DXCJdID0gMjk2Ml0gPSBcIlNURU5DSUxfRlVOQ1wiO1xuICBnbFtnbFtcIlNURU5DSUxfRkFJTFwiXSA9IDI5NjRdID0gXCJTVEVOQ0lMX0ZBSUxcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX1BBU1NfREVQVEhfRkFJTFwiXSA9IDI5NjVdID0gXCJTVEVOQ0lMX1BBU1NfREVQVEhfRkFJTFwiO1xuICBnbFtnbFtcIlNURU5DSUxfUEFTU19ERVBUSF9QQVNTXCJdID0gMjk2Nl0gPSBcIlNURU5DSUxfUEFTU19ERVBUSF9QQVNTXCI7XG4gIGdsW2dsW1wiU1RFTkNJTF9SRUZcIl0gPSAyOTY3XSA9IFwiU1RFTkNJTF9SRUZcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX1ZBTFVFX01BU0tcIl0gPSAyOTYzXSA9IFwiU1RFTkNJTF9WQUxVRV9NQVNLXCI7XG4gIGdsW2dsW1wiU1RFTkNJTF9XUklURU1BU0tcIl0gPSAyOTY4XSA9IFwiU1RFTkNJTF9XUklURU1BU0tcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JBQ0tfRlVOQ1wiXSA9IDM0ODE2XSA9IFwiU1RFTkNJTF9CQUNLX0ZVTkNcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JBQ0tfRkFJTFwiXSA9IDM0ODE3XSA9IFwiU1RFTkNJTF9CQUNLX0ZBSUxcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JBQ0tfUEFTU19ERVBUSF9GQUlMXCJdID0gMzQ4MThdID0gXCJTVEVOQ0lMX0JBQ0tfUEFTU19ERVBUSF9GQUlMXCI7XG4gIGdsW2dsW1wiU1RFTkNJTF9CQUNLX1BBU1NfREVQVEhfUEFTU1wiXSA9IDM0ODE5XSA9IFwiU1RFTkNJTF9CQUNLX1BBU1NfREVQVEhfUEFTU1wiO1xuICBnbFtnbFtcIlNURU5DSUxfQkFDS19SRUZcIl0gPSAzNjAwM10gPSBcIlNURU5DSUxfQkFDS19SRUZcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JBQ0tfVkFMVUVfTUFTS1wiXSA9IDM2MDA0XSA9IFwiU1RFTkNJTF9CQUNLX1ZBTFVFX01BU0tcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JBQ0tfV1JJVEVNQVNLXCJdID0gMzYwMDVdID0gXCJTVEVOQ0lMX0JBQ0tfV1JJVEVNQVNLXCI7XG4gIGdsW2dsW1wiVklFV1BPUlRcIl0gPSAyOTc4XSA9IFwiVklFV1BPUlRcIjtcbiAgZ2xbZ2xbXCJTQ0lTU09SX0JPWFwiXSA9IDMwODhdID0gXCJTQ0lTU09SX0JPWFwiO1xuICBnbFtnbFtcIkNPTE9SX0NMRUFSX1ZBTFVFXCJdID0gMzEwNl0gPSBcIkNPTE9SX0NMRUFSX1ZBTFVFXCI7XG4gIGdsW2dsW1wiQ09MT1JfV1JJVEVNQVNLXCJdID0gMzEwN10gPSBcIkNPTE9SX1dSSVRFTUFTS1wiO1xuICBnbFtnbFtcIlVOUEFDS19BTElHTk1FTlRcIl0gPSAzMzE3XSA9IFwiVU5QQUNLX0FMSUdOTUVOVFwiO1xuICBnbFtnbFtcIlBBQ0tfQUxJR05NRU5UXCJdID0gMzMzM10gPSBcIlBBQ0tfQUxJR05NRU5UXCI7XG4gIGdsW2dsW1wiTUFYX1RFWFRVUkVfU0laRVwiXSA9IDMzNzldID0gXCJNQVhfVEVYVFVSRV9TSVpFXCI7XG4gIGdsW2dsW1wiTUFYX1ZJRVdQT1JUX0RJTVNcIl0gPSAzMzg2XSA9IFwiTUFYX1ZJRVdQT1JUX0RJTVNcIjtcbiAgZ2xbZ2xbXCJTVUJQSVhFTF9CSVRTXCJdID0gMzQwOF0gPSBcIlNVQlBJWEVMX0JJVFNcIjtcbiAgZ2xbZ2xbXCJSRURfQklUU1wiXSA9IDM0MTBdID0gXCJSRURfQklUU1wiO1xuICBnbFtnbFtcIkdSRUVOX0JJVFNcIl0gPSAzNDExXSA9IFwiR1JFRU5fQklUU1wiO1xuICBnbFtnbFtcIkJMVUVfQklUU1wiXSA9IDM0MTJdID0gXCJCTFVFX0JJVFNcIjtcbiAgZ2xbZ2xbXCJBTFBIQV9CSVRTXCJdID0gMzQxM10gPSBcIkFMUEhBX0JJVFNcIjtcbiAgZ2xbZ2xbXCJERVBUSF9CSVRTXCJdID0gMzQxNF0gPSBcIkRFUFRIX0JJVFNcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0JJVFNcIl0gPSAzNDE1XSA9IFwiU1RFTkNJTF9CSVRTXCI7XG4gIGdsW2dsW1wiUE9MWUdPTl9PRkZTRVRfVU5JVFNcIl0gPSAxMDc1Ml0gPSBcIlBPTFlHT05fT0ZGU0VUX1VOSVRTXCI7XG4gIGdsW2dsW1wiUE9MWUdPTl9PRkZTRVRfRkFDVE9SXCJdID0gMzI4MjRdID0gXCJQT0xZR09OX09GRlNFVF9GQUNUT1JcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFX0JJTkRJTkdfMkRcIl0gPSAzMjg3M10gPSBcIlRFWFRVUkVfQklORElOR18yRFwiO1xuICBnbFtnbFtcIlNBTVBMRV9CVUZGRVJTXCJdID0gMzI5MzZdID0gXCJTQU1QTEVfQlVGRkVSU1wiO1xuICBnbFtnbFtcIlNBTVBMRVNcIl0gPSAzMjkzN10gPSBcIlNBTVBMRVNcIjtcbiAgZ2xbZ2xbXCJTQU1QTEVfQ09WRVJBR0VfVkFMVUVcIl0gPSAzMjkzOF0gPSBcIlNBTVBMRV9DT1ZFUkFHRV9WQUxVRVwiO1xuICBnbFtnbFtcIlNBTVBMRV9DT1ZFUkFHRV9JTlZFUlRcIl0gPSAzMjkzOV0gPSBcIlNBTVBMRV9DT1ZFUkFHRV9JTlZFUlRcIjtcbiAgZ2xbZ2xbXCJDT01QUkVTU0VEX1RFWFRVUkVfRk9STUFUU1wiXSA9IDM0NDY3XSA9IFwiQ09NUFJFU1NFRF9URVhUVVJFX0ZPUk1BVFNcIjtcbiAgZ2xbZ2xbXCJET05UX0NBUkVcIl0gPSA0MzUyXSA9IFwiRE9OVF9DQVJFXCI7XG4gIGdsW2dsW1wiRkFTVEVTVFwiXSA9IDQzNTNdID0gXCJGQVNURVNUXCI7XG4gIGdsW2dsW1wiTklDRVNUXCJdID0gNDM1NF0gPSBcIk5JQ0VTVFwiO1xuICBnbFtnbFtcIkdFTkVSQVRFX01JUE1BUF9ISU5UXCJdID0gMzMxNzBdID0gXCJHRU5FUkFURV9NSVBNQVBfSElOVFwiO1xuICBnbFtnbFtcIkJZVEVcIl0gPSA1MTIwXSA9IFwiQllURVwiO1xuICBnbFtnbFtcIlVOU0lHTkVEX0JZVEVcIl0gPSA1MTIxXSA9IFwiVU5TSUdORURfQllURVwiO1xuICBnbFtnbFtcIlNIT1JUXCJdID0gNTEyMl0gPSBcIlNIT1JUXCI7XG4gIGdsW2dsW1wiVU5TSUdORURfU0hPUlRcIl0gPSA1MTIzXSA9IFwiVU5TSUdORURfU0hPUlRcIjtcbiAgZ2xbZ2xbXCJJTlRcIl0gPSA1MTI0XSA9IFwiSU5UXCI7XG4gIGdsW2dsW1wiVU5TSUdORURfSU5UXCJdID0gNTEyNV0gPSBcIlVOU0lHTkVEX0lOVFwiO1xuICBnbFtnbFtcIkZMT0FUXCJdID0gNTEyNl0gPSBcIkZMT0FUXCI7XG4gIGdsW2dsW1wiREVQVEhfQ09NUE9ORU5UXCJdID0gNjQwMl0gPSBcIkRFUFRIX0NPTVBPTkVOVFwiO1xuICBnbFtnbFtcIkFMUEhBXCJdID0gNjQwNl0gPSBcIkFMUEhBXCI7XG4gIGdsW2dsW1wiUkdCXCJdID0gNjQwN10gPSBcIlJHQlwiO1xuICBnbFtnbFtcIlJHQkFcIl0gPSA2NDA4XSA9IFwiUkdCQVwiO1xuICBnbFtnbFtcIkxVTUlOQU5DRVwiXSA9IDY0MDldID0gXCJMVU1JTkFOQ0VcIjtcbiAgZ2xbZ2xbXCJMVU1JTkFOQ0VfQUxQSEFcIl0gPSA2NDEwXSA9IFwiTFVNSU5BTkNFX0FMUEhBXCI7XG4gIGdsW2dsW1wiVU5TSUdORURfU0hPUlRfNF80XzRfNFwiXSA9IDMyODE5XSA9IFwiVU5TSUdORURfU0hPUlRfNF80XzRfNFwiO1xuICBnbFtnbFtcIlVOU0lHTkVEX1NIT1JUXzVfNV81XzFcIl0gPSAzMjgyMF0gPSBcIlVOU0lHTkVEX1NIT1JUXzVfNV81XzFcIjtcbiAgZ2xbZ2xbXCJVTlNJR05FRF9TSE9SVF81XzZfNVwiXSA9IDMzNjM1XSA9IFwiVU5TSUdORURfU0hPUlRfNV82XzVcIjtcbiAgZ2xbZ2xbXCJGUkFHTUVOVF9TSEFERVJcIl0gPSAzNTYzMl0gPSBcIkZSQUdNRU5UX1NIQURFUlwiO1xuICBnbFtnbFtcIlZFUlRFWF9TSEFERVJcIl0gPSAzNTYzM10gPSBcIlZFUlRFWF9TSEFERVJcIjtcbiAgZ2xbZ2xbXCJNQVhfVkVSVEVYX0FUVFJJQlNcIl0gPSAzNDkyMV0gPSBcIk1BWF9WRVJURVhfQVRUUklCU1wiO1xuICBnbFtnbFtcIk1BWF9WRVJURVhfVU5JRk9STV9WRUNUT1JTXCJdID0gMzYzNDddID0gXCJNQVhfVkVSVEVYX1VOSUZPUk1fVkVDVE9SU1wiO1xuICBnbFtnbFtcIk1BWF9WQVJZSU5HX1ZFQ1RPUlNcIl0gPSAzNjM0OF0gPSBcIk1BWF9WQVJZSU5HX1ZFQ1RPUlNcIjtcbiAgZ2xbZ2xbXCJNQVhfQ09NQklORURfVEVYVFVSRV9JTUFHRV9VTklUU1wiXSA9IDM1NjYxXSA9IFwiTUFYX0NPTUJJTkVEX1RFWFRVUkVfSU1BR0VfVU5JVFNcIjtcbiAgZ2xbZ2xbXCJNQVhfVkVSVEVYX1RFWFRVUkVfSU1BR0VfVU5JVFNcIl0gPSAzNTY2MF0gPSBcIk1BWF9WRVJURVhfVEVYVFVSRV9JTUFHRV9VTklUU1wiO1xuICBnbFtnbFtcIk1BWF9URVhUVVJFX0lNQUdFX1VOSVRTXCJdID0gMzQ5MzBdID0gXCJNQVhfVEVYVFVSRV9JTUFHRV9VTklUU1wiO1xuICBnbFtnbFtcIk1BWF9GUkFHTUVOVF9VTklGT1JNX1ZFQ1RPUlNcIl0gPSAzNjM0OV0gPSBcIk1BWF9GUkFHTUVOVF9VTklGT1JNX1ZFQ1RPUlNcIjtcbiAgZ2xbZ2xbXCJTSEFERVJfVFlQRVwiXSA9IDM1NjYzXSA9IFwiU0hBREVSX1RZUEVcIjtcbiAgZ2xbZ2xbXCJERUxFVEVfU1RBVFVTXCJdID0gMzU3MTJdID0gXCJERUxFVEVfU1RBVFVTXCI7XG4gIGdsW2dsW1wiTElOS19TVEFUVVNcIl0gPSAzNTcxNF0gPSBcIkxJTktfU1RBVFVTXCI7XG4gIGdsW2dsW1wiVkFMSURBVEVfU1RBVFVTXCJdID0gMzU3MTVdID0gXCJWQUxJREFURV9TVEFUVVNcIjtcbiAgZ2xbZ2xbXCJBVFRBQ0hFRF9TSEFERVJTXCJdID0gMzU3MTddID0gXCJBVFRBQ0hFRF9TSEFERVJTXCI7XG4gIGdsW2dsW1wiQUNUSVZFX1VOSUZPUk1TXCJdID0gMzU3MThdID0gXCJBQ1RJVkVfVU5JRk9STVNcIjtcbiAgZ2xbZ2xbXCJBQ1RJVkVfQVRUUklCVVRFU1wiXSA9IDM1NzIxXSA9IFwiQUNUSVZFX0FUVFJJQlVURVNcIjtcbiAgZ2xbZ2xbXCJTSEFESU5HX0xBTkdVQUdFX1ZFUlNJT05cIl0gPSAzNTcyNF0gPSBcIlNIQURJTkdfTEFOR1VBR0VfVkVSU0lPTlwiO1xuICBnbFtnbFtcIkNVUlJFTlRfUFJPR1JBTVwiXSA9IDM1NzI1XSA9IFwiQ1VSUkVOVF9QUk9HUkFNXCI7XG4gIGdsW2dsW1wiTkVWRVJcIl0gPSA1MTJdID0gXCJORVZFUlwiO1xuICBnbFtnbFtcIkxFU1NcIl0gPSA1MTNdID0gXCJMRVNTXCI7XG4gIGdsW2dsW1wiRVFVQUxcIl0gPSA1MTRdID0gXCJFUVVBTFwiO1xuICBnbFtnbFtcIkxFUVVBTFwiXSA9IDUxNV0gPSBcIkxFUVVBTFwiO1xuICBnbFtnbFtcIkdSRUFURVJcIl0gPSA1MTZdID0gXCJHUkVBVEVSXCI7XG4gIGdsW2dsW1wiTk9URVFVQUxcIl0gPSA1MTddID0gXCJOT1RFUVVBTFwiO1xuICBnbFtnbFtcIkdFUVVBTFwiXSA9IDUxOF0gPSBcIkdFUVVBTFwiO1xuICBnbFtnbFtcIkFMV0FZU1wiXSA9IDUxOV0gPSBcIkFMV0FZU1wiO1xuICBnbFtnbFtcIktFRVBcIl0gPSA3NjgwXSA9IFwiS0VFUFwiO1xuICBnbFtnbFtcIlJFUExBQ0VcIl0gPSA3NjgxXSA9IFwiUkVQTEFDRVwiO1xuICBnbFtnbFtcIklOQ1JcIl0gPSA3NjgyXSA9IFwiSU5DUlwiO1xuICBnbFtnbFtcIkRFQ1JcIl0gPSA3NjgzXSA9IFwiREVDUlwiO1xuICBnbFtnbFtcIklOVkVSVFwiXSA9IDUzODZdID0gXCJJTlZFUlRcIjtcbiAgZ2xbZ2xbXCJJTkNSX1dSQVBcIl0gPSAzNDA1NV0gPSBcIklOQ1JfV1JBUFwiO1xuICBnbFtnbFtcIkRFQ1JfV1JBUFwiXSA9IDM0MDU2XSA9IFwiREVDUl9XUkFQXCI7XG4gIGdsW2dsW1wiVkVORE9SXCJdID0gNzkzNl0gPSBcIlZFTkRPUlwiO1xuICBnbFtnbFtcIlJFTkRFUkVSXCJdID0gNzkzN10gPSBcIlJFTkRFUkVSXCI7XG4gIGdsW2dsW1wiVkVSU0lPTlwiXSA9IDc5MzhdID0gXCJWRVJTSU9OXCI7XG4gIGdsW2dsW1wiTkVBUkVTVFwiXSA9IDk3MjhdID0gXCJORUFSRVNUXCI7XG4gIGdsW2dsW1wiTElORUFSXCJdID0gOTcyOV0gPSBcIkxJTkVBUlwiO1xuICBnbFtnbFtcIk5FQVJFU1RfTUlQTUFQX05FQVJFU1RcIl0gPSA5OTg0XSA9IFwiTkVBUkVTVF9NSVBNQVBfTkVBUkVTVFwiO1xuICBnbFtnbFtcIkxJTkVBUl9NSVBNQVBfTkVBUkVTVFwiXSA9IDk5ODVdID0gXCJMSU5FQVJfTUlQTUFQX05FQVJFU1RcIjtcbiAgZ2xbZ2xbXCJORUFSRVNUX01JUE1BUF9MSU5FQVJcIl0gPSA5OTg2XSA9IFwiTkVBUkVTVF9NSVBNQVBfTElORUFSXCI7XG4gIGdsW2dsW1wiTElORUFSX01JUE1BUF9MSU5FQVJcIl0gPSA5OTg3XSA9IFwiTElORUFSX01JUE1BUF9MSU5FQVJcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFX01BR19GSUxURVJcIl0gPSAxMDI0MF0gPSBcIlRFWFRVUkVfTUFHX0ZJTFRFUlwiO1xuICBnbFtnbFtcIlRFWFRVUkVfTUlOX0ZJTFRFUlwiXSA9IDEwMjQxXSA9IFwiVEVYVFVSRV9NSU5fRklMVEVSXCI7XG4gIGdsW2dsW1wiVEVYVFVSRV9XUkFQX1NcIl0gPSAxMDI0Ml0gPSBcIlRFWFRVUkVfV1JBUF9TXCI7XG4gIGdsW2dsW1wiVEVYVFVSRV9XUkFQX1RcIl0gPSAxMDI0M10gPSBcIlRFWFRVUkVfV1JBUF9UXCI7XG4gIGdsW2dsW1wiVEVYVFVSRV8yRFwiXSA9IDM1NTNdID0gXCJURVhUVVJFXzJEXCI7XG4gIGdsW2dsW1wiVEVYVFVSRVwiXSA9IDU4OTBdID0gXCJURVhUVVJFXCI7XG4gIGdsW2dsW1wiVEVYVFVSRV9DVUJFX01BUFwiXSA9IDM0MDY3XSA9IFwiVEVYVFVSRV9DVUJFX01BUFwiO1xuICBnbFtnbFtcIlRFWFRVUkVfQklORElOR19DVUJFX01BUFwiXSA9IDM0MDY4XSA9IFwiVEVYVFVSRV9CSU5ESU5HX0NVQkVfTUFQXCI7XG4gIGdsW2dsW1wiVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9YXCJdID0gMzQwNjldID0gXCJURVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1hcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1hcIl0gPSAzNDA3MF0gPSBcIlRFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWFwiO1xuICBnbFtnbFtcIlRFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWVwiXSA9IDM0MDcxXSA9IFwiVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9ZXCI7XG4gIGdsW2dsW1wiVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9ZXCJdID0gMzQwNzJdID0gXCJURVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1lcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1pcIl0gPSAzNDA3M10gPSBcIlRFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWlwiO1xuICBnbFtnbFtcIlRFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWlwiXSA9IDM0MDc0XSA9IFwiVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9aXCI7XG4gIGdsW2dsW1wiTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRVwiXSA9IDM0MDc2XSA9IFwiTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRVwiO1xuICBnbFtnbFtcIlRFWFRVUkUwXCJdID0gMzM5ODRdID0gXCJURVhUVVJFMFwiO1xuICBnbFtnbFtcIlRFWFRVUkUxXCJdID0gMzM5ODVdID0gXCJURVhUVVJFMVwiO1xuICBnbFtnbFtcIlRFWFRVUkUyXCJdID0gMzM5ODZdID0gXCJURVhUVVJFMlwiO1xuICBnbFtnbFtcIlRFWFRVUkUzXCJdID0gMzM5ODddID0gXCJURVhUVVJFM1wiO1xuICBnbFtnbFtcIlRFWFRVUkU0XCJdID0gMzM5ODhdID0gXCJURVhUVVJFNFwiO1xuICBnbFtnbFtcIlRFWFRVUkU1XCJdID0gMzM5ODldID0gXCJURVhUVVJFNVwiO1xuICBnbFtnbFtcIlRFWFRVUkU2XCJdID0gMzM5OTBdID0gXCJURVhUVVJFNlwiO1xuICBnbFtnbFtcIlRFWFRVUkU3XCJdID0gMzM5OTFdID0gXCJURVhUVVJFN1wiO1xuICBnbFtnbFtcIlRFWFRVUkU4XCJdID0gMzM5OTJdID0gXCJURVhUVVJFOFwiO1xuICBnbFtnbFtcIlRFWFRVUkU5XCJdID0gMzM5OTNdID0gXCJURVhUVVJFOVwiO1xuICBnbFtnbFtcIlRFWFRVUkUxMFwiXSA9IDMzOTk0XSA9IFwiVEVYVFVSRTEwXCI7XG4gIGdsW2dsW1wiVEVYVFVSRTExXCJdID0gMzM5OTVdID0gXCJURVhUVVJFMTFcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMTJcIl0gPSAzMzk5Nl0gPSBcIlRFWFRVUkUxMlwiO1xuICBnbFtnbFtcIlRFWFRVUkUxM1wiXSA9IDMzOTk3XSA9IFwiVEVYVFVSRTEzXCI7XG4gIGdsW2dsW1wiVEVYVFVSRTE0XCJdID0gMzM5OThdID0gXCJURVhUVVJFMTRcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMTVcIl0gPSAzMzk5OV0gPSBcIlRFWFRVUkUxNVwiO1xuICBnbFtnbFtcIlRFWFRVUkUxNlwiXSA9IDM0MDAwXSA9IFwiVEVYVFVSRTE2XCI7XG4gIGdsW2dsW1wiVEVYVFVSRTE3XCJdID0gMzQwMDFdID0gXCJURVhUVVJFMTdcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMThcIl0gPSAzNDAwMl0gPSBcIlRFWFRVUkUxOFwiO1xuICBnbFtnbFtcIlRFWFRVUkUxOVwiXSA9IDM0MDAzXSA9IFwiVEVYVFVSRTE5XCI7XG4gIGdsW2dsW1wiVEVYVFVSRTIwXCJdID0gMzQwMDRdID0gXCJURVhUVVJFMjBcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMjFcIl0gPSAzNDAwNV0gPSBcIlRFWFRVUkUyMVwiO1xuICBnbFtnbFtcIlRFWFRVUkUyMlwiXSA9IDM0MDA2XSA9IFwiVEVYVFVSRTIyXCI7XG4gIGdsW2dsW1wiVEVYVFVSRTIzXCJdID0gMzQwMDddID0gXCJURVhUVVJFMjNcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMjRcIl0gPSAzNDAwOF0gPSBcIlRFWFRVUkUyNFwiO1xuICBnbFtnbFtcIlRFWFRVUkUyNVwiXSA9IDM0MDA5XSA9IFwiVEVYVFVSRTI1XCI7XG4gIGdsW2dsW1wiVEVYVFVSRTI2XCJdID0gMzQwMTBdID0gXCJURVhUVVJFMjZcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMjdcIl0gPSAzNDAxMV0gPSBcIlRFWFRVUkUyN1wiO1xuICBnbFtnbFtcIlRFWFRVUkUyOFwiXSA9IDM0MDEyXSA9IFwiVEVYVFVSRTI4XCI7XG4gIGdsW2dsW1wiVEVYVFVSRTI5XCJdID0gMzQwMTNdID0gXCJURVhUVVJFMjlcIjtcbiAgZ2xbZ2xbXCJURVhUVVJFMzBcIl0gPSAzNDAxNF0gPSBcIlRFWFRVUkUzMFwiO1xuICBnbFtnbFtcIlRFWFRVUkUzMVwiXSA9IDM0MDE1XSA9IFwiVEVYVFVSRTMxXCI7XG4gIGdsW2dsW1wiQUNUSVZFX1RFWFRVUkVcIl0gPSAzNDAxNl0gPSBcIkFDVElWRV9URVhUVVJFXCI7XG4gIGdsW2dsW1wiUkVQRUFUXCJdID0gMTA0OTddID0gXCJSRVBFQVRcIjtcbiAgZ2xbZ2xbXCJDTEFNUF9UT19FREdFXCJdID0gMzMwNzFdID0gXCJDTEFNUF9UT19FREdFXCI7XG4gIGdsW2dsW1wiTUlSUk9SRURfUkVQRUFUXCJdID0gMzM2NDhdID0gXCJNSVJST1JFRF9SRVBFQVRcIjtcbiAgZ2xbZ2xbXCJGTE9BVF9WRUMyXCJdID0gMzU2NjRdID0gXCJGTE9BVF9WRUMyXCI7XG4gIGdsW2dsW1wiRkxPQVRfVkVDM1wiXSA9IDM1NjY1XSA9IFwiRkxPQVRfVkVDM1wiO1xuICBnbFtnbFtcIkZMT0FUX1ZFQzRcIl0gPSAzNTY2Nl0gPSBcIkZMT0FUX1ZFQzRcIjtcbiAgZ2xbZ2xbXCJJTlRfVkVDMlwiXSA9IDM1NjY3XSA9IFwiSU5UX1ZFQzJcIjtcbiAgZ2xbZ2xbXCJJTlRfVkVDM1wiXSA9IDM1NjY4XSA9IFwiSU5UX1ZFQzNcIjtcbiAgZ2xbZ2xbXCJJTlRfVkVDNFwiXSA9IDM1NjY5XSA9IFwiSU5UX1ZFQzRcIjtcbiAgZ2xbZ2xbXCJCT09MXCJdID0gMzU2NzBdID0gXCJCT09MXCI7XG4gIGdsW2dsW1wiQk9PTF9WRUMyXCJdID0gMzU2NzFdID0gXCJCT09MX1ZFQzJcIjtcbiAgZ2xbZ2xbXCJCT09MX1ZFQzNcIl0gPSAzNTY3Ml0gPSBcIkJPT0xfVkVDM1wiO1xuICBnbFtnbFtcIkJPT0xfVkVDNFwiXSA9IDM1NjczXSA9IFwiQk9PTF9WRUM0XCI7XG4gIGdsW2dsW1wiRkxPQVRfTUFUMlwiXSA9IDM1Njc0XSA9IFwiRkxPQVRfTUFUMlwiO1xuICBnbFtnbFtcIkZMT0FUX01BVDNcIl0gPSAzNTY3NV0gPSBcIkZMT0FUX01BVDNcIjtcbiAgZ2xbZ2xbXCJGTE9BVF9NQVQ0XCJdID0gMzU2NzZdID0gXCJGTE9BVF9NQVQ0XCI7XG4gIGdsW2dsW1wiU0FNUExFUl8yRFwiXSA9IDM1Njc4XSA9IFwiU0FNUExFUl8yRFwiO1xuICBnbFtnbFtcIlNBTVBMRVJfQ1VCRVwiXSA9IDM1NjgwXSA9IFwiU0FNUExFUl9DVUJFXCI7XG4gIGdsW2dsW1wiVkVSVEVYX0FUVFJJQl9BUlJBWV9FTkFCTEVEXCJdID0gMzQzMzhdID0gXCJWRVJURVhfQVRUUklCX0FSUkFZX0VOQUJMRURcIjtcbiAgZ2xbZ2xbXCJWRVJURVhfQVRUUklCX0FSUkFZX1NJWkVcIl0gPSAzNDMzOV0gPSBcIlZFUlRFWF9BVFRSSUJfQVJSQVlfU0laRVwiO1xuICBnbFtnbFtcIlZFUlRFWF9BVFRSSUJfQVJSQVlfU1RSSURFXCJdID0gMzQzNDBdID0gXCJWRVJURVhfQVRUUklCX0FSUkFZX1NUUklERVwiO1xuICBnbFtnbFtcIlZFUlRFWF9BVFRSSUJfQVJSQVlfVFlQRVwiXSA9IDM0MzQxXSA9IFwiVkVSVEVYX0FUVFJJQl9BUlJBWV9UWVBFXCI7XG4gIGdsW2dsW1wiVkVSVEVYX0FUVFJJQl9BUlJBWV9OT1JNQUxJWkVEXCJdID0gMzQ5MjJdID0gXCJWRVJURVhfQVRUUklCX0FSUkFZX05PUk1BTElaRURcIjtcbiAgZ2xbZ2xbXCJWRVJURVhfQVRUUklCX0FSUkFZX1BPSU5URVJcIl0gPSAzNDM3M10gPSBcIlZFUlRFWF9BVFRSSUJfQVJSQVlfUE9JTlRFUlwiO1xuICBnbFtnbFtcIlZFUlRFWF9BVFRSSUJfQVJSQVlfQlVGRkVSX0JJTkRJTkdcIl0gPSAzNDk3NV0gPSBcIlZFUlRFWF9BVFRSSUJfQVJSQVlfQlVGRkVSX0JJTkRJTkdcIjtcbiAgZ2xbZ2xbXCJDT01QSUxFX1NUQVRVU1wiXSA9IDM1NzEzXSA9IFwiQ09NUElMRV9TVEFUVVNcIjtcbiAgZ2xbZ2xbXCJMT1dfRkxPQVRcIl0gPSAzNjMzNl0gPSBcIkxPV19GTE9BVFwiO1xuICBnbFtnbFtcIk1FRElVTV9GTE9BVFwiXSA9IDM2MzM3XSA9IFwiTUVESVVNX0ZMT0FUXCI7XG4gIGdsW2dsW1wiSElHSF9GTE9BVFwiXSA9IDM2MzM4XSA9IFwiSElHSF9GTE9BVFwiO1xuICBnbFtnbFtcIkxPV19JTlRcIl0gPSAzNjMzOV0gPSBcIkxPV19JTlRcIjtcbiAgZ2xbZ2xbXCJNRURJVU1fSU5UXCJdID0gMzYzNDBdID0gXCJNRURJVU1fSU5UXCI7XG4gIGdsW2dsW1wiSElHSF9JTlRcIl0gPSAzNjM0MV0gPSBcIkhJR0hfSU5UXCI7XG4gIGdsW2dsW1wiRlJBTUVCVUZGRVJcIl0gPSAzNjE2MF0gPSBcIkZSQU1FQlVGRkVSXCI7XG4gIGdsW2dsW1wiUkVOREVSQlVGRkVSXCJdID0gMzYxNjFdID0gXCJSRU5ERVJCVUZGRVJcIjtcbiAgZ2xbZ2xbXCJSR0JBNFwiXSA9IDMyODU0XSA9IFwiUkdCQTRcIjtcbiAgZ2xbZ2xbXCJSR0I1X0ExXCJdID0gMzI4NTVdID0gXCJSR0I1X0ExXCI7XG4gIGdsW2dsW1wiUkdCNTY1XCJdID0gMzYxOTRdID0gXCJSR0I1NjVcIjtcbiAgZ2xbZ2xbXCJERVBUSF9DT01QT05FTlQxNlwiXSA9IDMzMTg5XSA9IFwiREVQVEhfQ09NUE9ORU5UMTZcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0lOREVYXCJdID0gNjQwMV0gPSBcIlNURU5DSUxfSU5ERVhcIjtcbiAgZ2xbZ2xbXCJTVEVOQ0lMX0lOREVYOFwiXSA9IDM2MTY4XSA9IFwiU1RFTkNJTF9JTkRFWDhcIjtcbiAgZ2xbZ2xbXCJERVBUSF9TVEVOQ0lMXCJdID0gMzQwNDFdID0gXCJERVBUSF9TVEVOQ0lMXCI7XG4gIGdsW2dsW1wiUkVOREVSQlVGRkVSX1dJRFRIXCJdID0gMzYxNjJdID0gXCJSRU5ERVJCVUZGRVJfV0lEVEhcIjtcbiAgZ2xbZ2xbXCJSRU5ERVJCVUZGRVJfSEVJR0hUXCJdID0gMzYxNjNdID0gXCJSRU5ERVJCVUZGRVJfSEVJR0hUXCI7XG4gIGdsW2dsW1wiUkVOREVSQlVGRkVSX0lOVEVSTkFMX0ZPUk1BVFwiXSA9IDM2MTY0XSA9IFwiUkVOREVSQlVGRkVSX0lOVEVSTkFMX0ZPUk1BVFwiO1xuICBnbFtnbFtcIlJFTkRFUkJVRkZFUl9SRURfU0laRVwiXSA9IDM2MTc2XSA9IFwiUkVOREVSQlVGRkVSX1JFRF9TSVpFXCI7XG4gIGdsW2dsW1wiUkVOREVSQlVGRkVSX0dSRUVOX1NJWkVcIl0gPSAzNjE3N10gPSBcIlJFTkRFUkJVRkZFUl9HUkVFTl9TSVpFXCI7XG4gIGdsW2dsW1wiUkVOREVSQlVGRkVSX0JMVUVfU0laRVwiXSA9IDM2MTc4XSA9IFwiUkVOREVSQlVGRkVSX0JMVUVfU0laRVwiO1xuICBnbFtnbFtcIlJFTkRFUkJVRkZFUl9BTFBIQV9TSVpFXCJdID0gMzYxNzldID0gXCJSRU5ERVJCVUZGRVJfQUxQSEFfU0laRVwiO1xuICBnbFtnbFtcIlJFTkRFUkJVRkZFUl9ERVBUSF9TSVpFXCJdID0gMzYxODBdID0gXCJSRU5ERVJCVUZGRVJfREVQVEhfU0laRVwiO1xuICBnbFtnbFtcIlJFTkRFUkJVRkZFUl9TVEVOQ0lMX1NJWkVcIl0gPSAzNjE4MV0gPSBcIlJFTkRFUkJVRkZFUl9TVEVOQ0lMX1NJWkVcIjtcbiAgZ2xbZ2xbXCJGUkFNRUJVRkZFUl9BVFRBQ0hNRU5UX09CSkVDVF9UWVBFXCJdID0gMzYwNDhdID0gXCJGUkFNRUJVRkZFUl9BVFRBQ0hNRU5UX09CSkVDVF9UWVBFXCI7XG4gIGdsW2dsW1wiRlJBTUVCVUZGRVJfQVRUQUNITUVOVF9PQkpFQ1RfTkFNRVwiXSA9IDM2MDQ5XSA9IFwiRlJBTUVCVUZGRVJfQVRUQUNITUVOVF9PQkpFQ1RfTkFNRVwiO1xuICBnbFtnbFtcIkZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfVEVYVFVSRV9MRVZFTFwiXSA9IDM2MDUwXSA9IFwiRlJBTUVCVUZGRVJfQVRUQUNITUVOVF9URVhUVVJFX0xFVkVMXCI7XG4gIGdsW2dsW1wiRlJBTUVCVUZGRVJfQVRUQUNITUVOVF9URVhUVVJFX0NVQkVfTUFQX0ZBQ0VcIl0gPSAzNjA1MV0gPSBcIkZSQU1FQlVGRkVSX0FUVEFDSE1FTlRfVEVYVFVSRV9DVUJFX01BUF9GQUNFXCI7XG4gIGdsW2dsW1wiQ09MT1JfQVRUQUNITUVOVDBcIl0gPSAzNjA2NF0gPSBcIkNPTE9SX0FUVEFDSE1FTlQwXCI7XG4gIGdsW2dsW1wiREVQVEhfQVRUQUNITUVOVFwiXSA9IDM2MDk2XSA9IFwiREVQVEhfQVRUQUNITUVOVFwiO1xuICBnbFtnbFtcIlNURU5DSUxfQVRUQUNITUVOVFwiXSA9IDM2MTI4XSA9IFwiU1RFTkNJTF9BVFRBQ0hNRU5UXCI7XG4gIGdsW2dsW1wiREVQVEhfU1RFTkNJTF9BVFRBQ0hNRU5UXCJdID0gMzMzMDZdID0gXCJERVBUSF9TVEVOQ0lMX0FUVEFDSE1FTlRcIjtcbiAgZ2xbZ2xbXCJOT05FXCJdID0gMF0gPSBcIk5PTkVcIjtcbiAgZ2xbZ2xbXCJGUkFNRUJVRkZFUl9DT01QTEVURVwiXSA9IDM2MDUzXSA9IFwiRlJBTUVCVUZGRVJfQ09NUExFVEVcIjtcbiAgZ2xbZ2xbXCJGUkFNRUJVRkZFUl9JTkNPTVBMRVRFX0FUVEFDSE1FTlRcIl0gPSAzNjA1NF0gPSBcIkZSQU1FQlVGRkVSX0lOQ09NUExFVEVfQVRUQUNITUVOVFwiO1xuICBnbFtnbFtcIkZSQU1FQlVGRkVSX0lOQ09NUExFVEVfTUlTU0lOR19BVFRBQ0hNRU5UXCJdID0gMzYwNTVdID0gXCJGUkFNRUJVRkZFUl9JTkNPTVBMRVRFX01JU1NJTkdfQVRUQUNITUVOVFwiO1xuICBnbFtnbFtcIkZSQU1FQlVGRkVSX0lOQ09NUExFVEVfRElNRU5TSU9OU1wiXSA9IDM2MDU3XSA9IFwiRlJBTUVCVUZGRVJfSU5DT01QTEVURV9ESU1FTlNJT05TXCI7XG4gIGdsW2dsW1wiRlJBTUVCVUZGRVJfVU5TVVBQT1JURURcIl0gPSAzNjA2MV0gPSBcIkZSQU1FQlVGRkVSX1VOU1VQUE9SVEVEXCI7XG4gIGdsW2dsW1wiRlJBTUVCVUZGRVJfQklORElOR1wiXSA9IDM2MDA2XSA9IFwiRlJBTUVCVUZGRVJfQklORElOR1wiO1xuICBnbFtnbFtcIlJFTkRFUkJVRkZFUl9CSU5ESU5HXCJdID0gMzYwMDddID0gXCJSRU5ERVJCVUZGRVJfQklORElOR1wiO1xuICBnbFtnbFtcIk1BWF9SRU5ERVJCVUZGRVJfU0laRVwiXSA9IDM0MDI0XSA9IFwiTUFYX1JFTkRFUkJVRkZFUl9TSVpFXCI7XG4gIGdsW2dsW1wiSU5WQUxJRF9GUkFNRUJVRkZFUl9PUEVSQVRJT05cIl0gPSAxMjg2XSA9IFwiSU5WQUxJRF9GUkFNRUJVRkZFUl9PUEVSQVRJT05cIjtcbiAgZ2xbZ2xbXCJVTlBBQ0tfRkxJUF9ZX1dFQkdMXCJdID0gMzc0NDBdID0gXCJVTlBBQ0tfRkxJUF9ZX1dFQkdMXCI7XG4gIGdsW2dsW1wiVU5QQUNLX1BSRU1VTFRJUExZX0FMUEhBX1dFQkdMXCJdID0gMzc0NDFdID0gXCJVTlBBQ0tfUFJFTVVMVElQTFlfQUxQSEFfV0VCR0xcIjtcbiAgZ2xbZ2xbXCJDT05URVhUX0xPU1RfV0VCR0xcIl0gPSAzNzQ0Ml0gPSBcIkNPTlRFWFRfTE9TVF9XRUJHTFwiO1xuICBnbFtnbFtcIlVOUEFDS19DT0xPUlNQQUNFX0NPTlZFUlNJT05fV0VCR0xcIl0gPSAzNzQ0M10gPSBcIlVOUEFDS19DT0xPUlNQQUNFX0NPTlZFUlNJT05fV0VCR0xcIjtcbiAgZ2xbZ2xbXCJCUk9XU0VSX0RFRkFVTFRfV0VCR0xcIl0gPSAzNzQ0NF0gPSBcIkJST1dTRVJfREVGQVVMVF9XRUJHTFwiO1xuICBnbFtnbFtcIkNPUFlfU1JDXCJdID0gMV0gPSBcIkNPUFlfU1JDXCI7XG4gIGdsW2dsW1wiQ09QWV9EU1RcIl0gPSAyXSA9IFwiQ09QWV9EU1RcIjtcbiAgZ2xbZ2xbXCJTQU1QTEVEXCJdID0gNF0gPSBcIlNBTVBMRURcIjtcbiAgZ2xbZ2xbXCJTVE9SQUdFXCJdID0gOF0gPSBcIlNUT1JBR0VcIjtcbiAgZ2xbZ2xbXCJSRU5ERVJfQVRUQUNITUVOVFwiXSA9IDE2XSA9IFwiUkVOREVSX0FUVEFDSE1FTlRcIjtcbn0pKGdsIHx8IChnbCA9IHt9KSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nbC5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///35\n')},function(module,exports,__webpack_require__){"use strict";eval('/* eslint "no-console": off */\n\n\n\nvar _ = __webpack_require__(28);\nvar Graph = __webpack_require__(46).Graph;\n\nmodule.exports = {\n addDummyNode: addDummyNode,\n simplify: simplify,\n asNonCompoundGraph: asNonCompoundGraph,\n successorWeights: successorWeights,\n predecessorWeights: predecessorWeights,\n intersectRect: intersectRect,\n buildLayerMatrix: buildLayerMatrix,\n normalizeRanks: normalizeRanks,\n removeEmptyRanks: removeEmptyRanks,\n addBorderNode: addBorderNode,\n maxRank: maxRank,\n partition: partition,\n time: time,\n notime: notime\n};\n\n/*\n * Adds a dummy node to the graph and return v.\n */\nfunction addDummyNode(g, type, attrs, name) {\n var v;\n do {\n v = _.uniqueId(name);\n } while (g.hasNode(v));\n\n attrs.dummy = type;\n g.setNode(v, attrs);\n return v;\n}\n\n/*\n * Returns a new graph with only simple edges. Handles aggregation of data\n * associated with multi-edges.\n */\nfunction simplify(g) {\n var simplified = new Graph().setGraph(g.graph());\n _.forEach(g.nodes(), function(v) { simplified.setNode(v, g.node(v)); });\n _.forEach(g.edges(), function(e) {\n var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 };\n var label = g.edge(e);\n simplified.setEdge(e.v, e.w, {\n weight: simpleLabel.weight + label.weight,\n minlen: Math.max(simpleLabel.minlen, label.minlen)\n });\n });\n return simplified;\n}\n\nfunction asNonCompoundGraph(g) {\n var simplified = new Graph({ multigraph: g.isMultigraph() }).setGraph(g.graph());\n _.forEach(g.nodes(), function(v) {\n if (!g.children(v).length) {\n simplified.setNode(v, g.node(v));\n }\n });\n _.forEach(g.edges(), function(e) {\n simplified.setEdge(e, g.edge(e));\n });\n return simplified;\n}\n\nfunction successorWeights(g) {\n var weightMap = _.map(g.nodes(), function(v) {\n var sucs = {};\n _.forEach(g.outEdges(v), function(e) {\n sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight;\n });\n return sucs;\n });\n return _.zipObject(g.nodes(), weightMap);\n}\n\nfunction predecessorWeights(g) {\n var weightMap = _.map(g.nodes(), function(v) {\n var preds = {};\n _.forEach(g.inEdges(v), function(e) {\n preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight;\n });\n return preds;\n });\n return _.zipObject(g.nodes(), weightMap);\n}\n\n/*\n * Finds where a line starting at point ({x, y}) would intersect a rectangle\n * ({x, y, width, height}) if it were pointing at the rectangle\'s center.\n */\nfunction intersectRect(rect, point) {\n var x = rect.x;\n var y = rect.y;\n\n // Rectangle intersection algorithm from:\n // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes\n var dx = point.x - x;\n var dy = point.y - y;\n var w = rect.width / 2;\n var h = rect.height / 2;\n\n if (!dx && !dy) {\n throw new Error("Not possible to find intersection inside of the rectangle");\n }\n\n var sx, sy;\n if (Math.abs(dy) * w > Math.abs(dx) * h) {\n // Intersection is top or bottom of rect.\n if (dy < 0) {\n h = -h;\n }\n sx = h * dx / dy;\n sy = h;\n } else {\n // Intersection is left or right of rect.\n if (dx < 0) {\n w = -w;\n }\n sx = w;\n sy = w * dy / dx;\n }\n\n return { x: x + sx, y: y + sy };\n}\n\n/*\n * Given a DAG with each node assigned "rank" and "order" properties, this\n * function will produce a matrix with the ids of each node.\n */\nfunction buildLayerMatrix(g) {\n var layering = _.map(_.range(maxRank(g) + 1), function() { return []; });\n _.forEach(g.nodes(), function(v) {\n var node = g.node(v);\n var rank = node.rank;\n if (!_.isUndefined(rank)) {\n layering[rank][node.order] = v;\n }\n });\n return layering;\n}\n\n/*\n * Adjusts the ranks for all nodes in the graph such that all nodes v have\n * rank(v) >= 0 and at least one node w has rank(w) = 0.\n */\nfunction normalizeRanks(g) {\n var min = _.min(_.map(g.nodes(), function(v) { return g.node(v).rank; }));\n _.forEach(g.nodes(), function(v) {\n var node = g.node(v);\n if (_.has(node, "rank")) {\n node.rank -= min;\n }\n });\n}\n\nfunction removeEmptyRanks(g) {\n // Ranks may not start at 0, so we need to offset them\n var offset = _.min(_.map(g.nodes(), function(v) { return g.node(v).rank; }));\n\n var layers = [];\n _.forEach(g.nodes(), function(v) {\n var rank = g.node(v).rank - offset;\n if (!layers[rank]) {\n layers[rank] = [];\n }\n layers[rank].push(v);\n });\n\n var delta = 0;\n var nodeRankFactor = g.graph().nodeRankFactor;\n _.forEach(layers, function(vs, i) {\n if (_.isUndefined(vs) && i % nodeRankFactor !== 0) {\n --delta;\n } else if (delta) {\n _.forEach(vs, function(v) { g.node(v).rank += delta; });\n }\n });\n}\n\nfunction addBorderNode(g, prefix, rank, order) {\n var node = {\n width: 0,\n height: 0\n };\n if (arguments.length >= 4) {\n node.rank = rank;\n node.order = order;\n }\n return addDummyNode(g, "border", node, prefix);\n}\n\nfunction maxRank(g) {\n return _.max(_.map(g.nodes(), function(v) {\n var rank = g.node(v).rank;\n if (!_.isUndefined(rank)) {\n return rank;\n }\n }));\n}\n\n/*\n * Partition a collection into two groups: `lhs` and `rhs`. If the supplied\n * function returns true for an entry it goes into `lhs`. Otherwise it goes\n * into `rhs.\n */\nfunction partition(collection, fn) {\n var result = { lhs: [], rhs: [] };\n _.forEach(collection, function(value) {\n if (fn(value)) {\n result.lhs.push(value);\n } else {\n result.rhs.push(value);\n }\n });\n return result;\n}\n\n/*\n * Returns a new function that wraps `fn` with a timer. The wrapper logs the\n * time it takes to execute the function.\n */\nfunction time(name, fn) {\n var start = _.now();\n try {\n return fn();\n } finally {\n console.log(name + " time: " + (_.now() - start) + "ms");\n }\n}\n\nfunction notime(name, fn) {\n return fn();\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZGFncmVqcy9saWIvdXRpbC5qcz82NjNjIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVhOztBQUViLFFBQVEsbUJBQU8sQ0FBQyxFQUFVO0FBQzFCLFlBQVksbUJBQU8sQ0FBQyxFQUFZOztBQUVoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLGtDQUFrQyxFQUFFO0FBQ3hFO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsOEJBQThCLCtCQUErQjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBLDBDQUEwQyxLQUFLO0FBQy9DLEtBQUssb0JBQW9CO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVO0FBQ1Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RCxXQUFXLEVBQUU7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCx1QkFBdUIsRUFBRTtBQUN6RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQSxtREFBbUQsdUJBQXVCLEVBQUU7O0FBRTVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLGlDQUFpQyx5QkFBeUIsRUFBRTtBQUM1RDtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMzYuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQgXCJuby1jb25zb2xlXCI6IG9mZiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIF8gPSByZXF1aXJlKFwiLi9sb2Rhc2hcIik7XG52YXIgR3JhcGggPSByZXF1aXJlKFwiLi9ncmFwaGxpYlwiKS5HcmFwaDtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGFkZER1bW15Tm9kZTogYWRkRHVtbXlOb2RlLFxuICBzaW1wbGlmeTogc2ltcGxpZnksXG4gIGFzTm9uQ29tcG91bmRHcmFwaDogYXNOb25Db21wb3VuZEdyYXBoLFxuICBzdWNjZXNzb3JXZWlnaHRzOiBzdWNjZXNzb3JXZWlnaHRzLFxuICBwcmVkZWNlc3NvcldlaWdodHM6IHByZWRlY2Vzc29yV2VpZ2h0cyxcbiAgaW50ZXJzZWN0UmVjdDogaW50ZXJzZWN0UmVjdCxcbiAgYnVpbGRMYXllck1hdHJpeDogYnVpbGRMYXllck1hdHJpeCxcbiAgbm9ybWFsaXplUmFua3M6IG5vcm1hbGl6ZVJhbmtzLFxuICByZW1vdmVFbXB0eVJhbmtzOiByZW1vdmVFbXB0eVJhbmtzLFxuICBhZGRCb3JkZXJOb2RlOiBhZGRCb3JkZXJOb2RlLFxuICBtYXhSYW5rOiBtYXhSYW5rLFxuICBwYXJ0aXRpb246IHBhcnRpdGlvbixcbiAgdGltZTogdGltZSxcbiAgbm90aW1lOiBub3RpbWVcbn07XG5cbi8qXG4gKiBBZGRzIGEgZHVtbXkgbm9kZSB0byB0aGUgZ3JhcGggYW5kIHJldHVybiB2LlxuICovXG5mdW5jdGlvbiBhZGREdW1teU5vZGUoZywgdHlwZSwgYXR0cnMsIG5hbWUpIHtcbiAgdmFyIHY7XG4gIGRvIHtcbiAgICB2ID0gXy51bmlxdWVJZChuYW1lKTtcbiAgfSB3aGlsZSAoZy5oYXNOb2RlKHYpKTtcblxuICBhdHRycy5kdW1teSA9IHR5cGU7XG4gIGcuc2V0Tm9kZSh2LCBhdHRycyk7XG4gIHJldHVybiB2O1xufVxuXG4vKlxuICogUmV0dXJucyBhIG5ldyBncmFwaCB3aXRoIG9ubHkgc2ltcGxlIGVkZ2VzLiBIYW5kbGVzIGFnZ3JlZ2F0aW9uIG9mIGRhdGFcbiAqIGFzc29jaWF0ZWQgd2l0aCBtdWx0aS1lZGdlcy5cbiAqL1xuZnVuY3Rpb24gc2ltcGxpZnkoZykge1xuICB2YXIgc2ltcGxpZmllZCA9IG5ldyBHcmFwaCgpLnNldEdyYXBoKGcuZ3JhcGgoKSk7XG4gIF8uZm9yRWFjaChnLm5vZGVzKCksIGZ1bmN0aW9uKHYpIHsgc2ltcGxpZmllZC5zZXROb2RlKHYsIGcubm9kZSh2KSk7IH0pO1xuICBfLmZvckVhY2goZy5lZGdlcygpLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIHNpbXBsZUxhYmVsID0gc2ltcGxpZmllZC5lZGdlKGUudiwgZS53KSB8fCB7IHdlaWdodDogMCwgbWlubGVuOiAxIH07XG4gICAgdmFyIGxhYmVsID0gZy5lZGdlKGUpO1xuICAgIHNpbXBsaWZpZWQuc2V0RWRnZShlLnYsIGUudywge1xuICAgICAgd2VpZ2h0OiBzaW1wbGVMYWJlbC53ZWlnaHQgKyBsYWJlbC53ZWlnaHQsXG4gICAgICBtaW5sZW46IE1hdGgubWF4KHNpbXBsZUxhYmVsLm1pbmxlbiwgbGFiZWwubWlubGVuKVxuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIHNpbXBsaWZpZWQ7XG59XG5cbmZ1bmN0aW9uIGFzTm9uQ29tcG91bmRHcmFwaChnKSB7XG4gIHZhciBzaW1wbGlmaWVkID0gbmV3IEdyYXBoKHsgbXVsdGlncmFwaDogZy5pc011bHRpZ3JhcGgoKSB9KS5zZXRHcmFwaChnLmdyYXBoKCkpO1xuICBfLmZvckVhY2goZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7XG4gICAgaWYgKCFnLmNoaWxkcmVuKHYpLmxlbmd0aCkge1xuICAgICAgc2ltcGxpZmllZC5zZXROb2RlKHYsIGcubm9kZSh2KSk7XG4gICAgfVxuICB9KTtcbiAgXy5mb3JFYWNoKGcuZWRnZXMoKSwgZnVuY3Rpb24oZSkge1xuICAgIHNpbXBsaWZpZWQuc2V0RWRnZShlLCBnLmVkZ2UoZSkpO1xuICB9KTtcbiAgcmV0dXJuIHNpbXBsaWZpZWQ7XG59XG5cbmZ1bmN0aW9uIHN1Y2Nlc3NvcldlaWdodHMoZykge1xuICB2YXIgd2VpZ2h0TWFwID0gXy5tYXAoZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7XG4gICAgdmFyIHN1Y3MgPSB7fTtcbiAgICBfLmZvckVhY2goZy5vdXRFZGdlcyh2KSwgZnVuY3Rpb24oZSkge1xuICAgICAgc3Vjc1tlLnddID0gKHN1Y3NbZS53XSB8fCAwKSArIGcuZWRnZShlKS53ZWlnaHQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIHN1Y3M7XG4gIH0pO1xuICByZXR1cm4gXy56aXBPYmplY3QoZy5ub2RlcygpLCB3ZWlnaHRNYXApO1xufVxuXG5mdW5jdGlvbiBwcmVkZWNlc3NvcldlaWdodHMoZykge1xuICB2YXIgd2VpZ2h0TWFwID0gXy5tYXAoZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7XG4gICAgdmFyIHByZWRzID0ge307XG4gICAgXy5mb3JFYWNoKGcuaW5FZGdlcyh2KSwgZnVuY3Rpb24oZSkge1xuICAgICAgcHJlZHNbZS52XSA9IChwcmVkc1tlLnZdIHx8IDApICsgZy5lZGdlKGUpLndlaWdodDtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJlZHM7XG4gIH0pO1xuICByZXR1cm4gXy56aXBPYmplY3QoZy5ub2RlcygpLCB3ZWlnaHRNYXApO1xufVxuXG4vKlxuICogRmluZHMgd2hlcmUgYSBsaW5lIHN0YXJ0aW5nIGF0IHBvaW50ICh7eCwgeX0pIHdvdWxkIGludGVyc2VjdCBhIHJlY3RhbmdsZVxuICogKHt4LCB5LCB3aWR0aCwgaGVpZ2h0fSkgaWYgaXQgd2VyZSBwb2ludGluZyBhdCB0aGUgcmVjdGFuZ2xlJ3MgY2VudGVyLlxuICovXG5mdW5jdGlvbiBpbnRlcnNlY3RSZWN0KHJlY3QsIHBvaW50KSB7XG4gIHZhciB4ID0gcmVjdC54O1xuICB2YXIgeSA9IHJlY3QueTtcblxuICAvLyBSZWN0YW5nbGUgaW50ZXJzZWN0aW9uIGFsZ29yaXRobSBmcm9tOlxuICAvLyBodHRwOi8vbWF0aC5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvMTA4MTEzL2ZpbmQtZWRnZS1iZXR3ZWVuLXR3by1ib3hlc1xuICB2YXIgZHggPSBwb2ludC54IC0geDtcbiAgdmFyIGR5ID0gcG9pbnQueSAtIHk7XG4gIHZhciB3ID0gcmVjdC53aWR0aCAvIDI7XG4gIHZhciBoID0gcmVjdC5oZWlnaHQgLyAyO1xuXG4gIGlmICghZHggJiYgIWR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IHBvc3NpYmxlIHRvIGZpbmQgaW50ZXJzZWN0aW9uIGluc2lkZSBvZiB0aGUgcmVjdGFuZ2xlXCIpO1xuICB9XG5cbiAgdmFyIHN4LCBzeTtcbiAgaWYgKE1hdGguYWJzKGR5KSAqIHcgPiBNYXRoLmFicyhkeCkgKiBoKSB7XG4gICAgLy8gSW50ZXJzZWN0aW9uIGlzIHRvcCBvciBib3R0b20gb2YgcmVjdC5cbiAgICBpZiAoZHkgPCAwKSB7XG4gICAgICBoID0gLWg7XG4gICAgfVxuICAgIHN4ID0gaCAqIGR4IC8gZHk7XG4gICAgc3kgPSBoO1xuICB9IGVsc2Uge1xuICAgIC8vIEludGVyc2VjdGlvbiBpcyBsZWZ0IG9yIHJpZ2h0IG9mIHJlY3QuXG4gICAgaWYgKGR4IDwgMCkge1xuICAgICAgdyA9IC13O1xuICAgIH1cbiAgICBzeCA9IHc7XG4gICAgc3kgPSB3ICogZHkgLyBkeDtcbiAgfVxuXG4gIHJldHVybiB7IHg6IHggKyBzeCwgeTogeSArIHN5IH07XG59XG5cbi8qXG4gKiBHaXZlbiBhIERBRyB3aXRoIGVhY2ggbm9kZSBhc3NpZ25lZCBcInJhbmtcIiBhbmQgXCJvcmRlclwiIHByb3BlcnRpZXMsIHRoaXNcbiAqIGZ1bmN0aW9uIHdpbGwgcHJvZHVjZSBhIG1hdHJpeCB3aXRoIHRoZSBpZHMgb2YgZWFjaCBub2RlLlxuICovXG5mdW5jdGlvbiBidWlsZExheWVyTWF0cml4KGcpIHtcbiAgdmFyIGxheWVyaW5nID0gXy5tYXAoXy5yYW5nZShtYXhSYW5rKGcpICsgMSksIGZ1bmN0aW9uKCkgeyByZXR1cm4gW107IH0pO1xuICBfLmZvckVhY2goZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7XG4gICAgdmFyIG5vZGUgPSBnLm5vZGUodik7XG4gICAgdmFyIHJhbmsgPSBub2RlLnJhbms7XG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHJhbmspKSB7XG4gICAgICBsYXllcmluZ1tyYW5rXVtub2RlLm9yZGVyXSA9IHY7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGxheWVyaW5nO1xufVxuXG4vKlxuICogQWRqdXN0cyB0aGUgcmFua3MgZm9yIGFsbCBub2RlcyBpbiB0aGUgZ3JhcGggc3VjaCB0aGF0IGFsbCBub2RlcyB2IGhhdmVcbiAqIHJhbmsodikgPj0gMCBhbmQgYXQgbGVhc3Qgb25lIG5vZGUgdyBoYXMgcmFuayh3KSA9IDAuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJhbmtzKGcpIHtcbiAgdmFyIG1pbiA9IF8ubWluKF8ubWFwKGcubm9kZXMoKSwgZnVuY3Rpb24odikgeyByZXR1cm4gZy5ub2RlKHYpLnJhbms7IH0pKTtcbiAgXy5mb3JFYWNoKGcubm9kZXMoKSwgZnVuY3Rpb24odikge1xuICAgIHZhciBub2RlID0gZy5ub2RlKHYpO1xuICAgIGlmIChfLmhhcyhub2RlLCBcInJhbmtcIikpIHtcbiAgICAgIG5vZGUucmFuayAtPSBtaW47XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRW1wdHlSYW5rcyhnKSB7XG4gIC8vIFJhbmtzIG1heSBub3Qgc3RhcnQgYXQgMCwgc28gd2UgbmVlZCB0byBvZmZzZXQgdGhlbVxuICB2YXIgb2Zmc2V0ID0gXy5taW4oXy5tYXAoZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7IHJldHVybiBnLm5vZGUodikucmFuazsgfSkpO1xuXG4gIHZhciBsYXllcnMgPSBbXTtcbiAgXy5mb3JFYWNoKGcubm9kZXMoKSwgZnVuY3Rpb24odikge1xuICAgIHZhciByYW5rID0gZy5ub2RlKHYpLnJhbmsgLSBvZmZzZXQ7XG4gICAgaWYgKCFsYXllcnNbcmFua10pIHtcbiAgICAgIGxheWVyc1tyYW5rXSA9IFtdO1xuICAgIH1cbiAgICBsYXllcnNbcmFua10ucHVzaCh2KTtcbiAgfSk7XG5cbiAgdmFyIGRlbHRhID0gMDtcbiAgdmFyIG5vZGVSYW5rRmFjdG9yID0gZy5ncmFwaCgpLm5vZGVSYW5rRmFjdG9yO1xuICBfLmZvckVhY2gobGF5ZXJzLCBmdW5jdGlvbih2cywgaSkge1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKHZzKSAmJiBpICUgbm9kZVJhbmtGYWN0b3IgIT09IDApIHtcbiAgICAgIC0tZGVsdGE7XG4gICAgfSBlbHNlIGlmIChkZWx0YSkge1xuICAgICAgXy5mb3JFYWNoKHZzLCBmdW5jdGlvbih2KSB7IGcubm9kZSh2KS5yYW5rICs9IGRlbHRhOyB9KTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhZGRCb3JkZXJOb2RlKGcsIHByZWZpeCwgcmFuaywgb3JkZXIpIHtcbiAgdmFyIG5vZGUgPSB7XG4gICAgd2lkdGg6IDAsXG4gICAgaGVpZ2h0OiAwXG4gIH07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIHtcbiAgICBub2RlLnJhbmsgPSByYW5rO1xuICAgIG5vZGUub3JkZXIgPSBvcmRlcjtcbiAgfVxuICByZXR1cm4gYWRkRHVtbXlOb2RlKGcsIFwiYm9yZGVyXCIsIG5vZGUsIHByZWZpeCk7XG59XG5cbmZ1bmN0aW9uIG1heFJhbmsoZykge1xuICByZXR1cm4gXy5tYXgoXy5tYXAoZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7XG4gICAgdmFyIHJhbmsgPSBnLm5vZGUodikucmFuaztcbiAgICBpZiAoIV8uaXNVbmRlZmluZWQocmFuaykpIHtcbiAgICAgIHJldHVybiByYW5rO1xuICAgIH1cbiAgfSkpO1xufVxuXG4vKlxuICogUGFydGl0aW9uIGEgY29sbGVjdGlvbiBpbnRvIHR3byBncm91cHM6IGBsaHNgIGFuZCBgcmhzYC4gSWYgdGhlIHN1cHBsaWVkXG4gKiBmdW5jdGlvbiByZXR1cm5zIHRydWUgZm9yIGFuIGVudHJ5IGl0IGdvZXMgaW50byBgbGhzYC4gT3RoZXJ3aXNlIGl0IGdvZXNcbiAqIGludG8gYHJocy5cbiAqL1xuZnVuY3Rpb24gcGFydGl0aW9uKGNvbGxlY3Rpb24sIGZuKSB7XG4gIHZhciByZXN1bHQgPSB7IGxoczogW10sIHJoczogW10gfTtcbiAgXy5mb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKGZuKHZhbHVlKSkge1xuICAgICAgcmVzdWx0Lmxocy5wdXNoKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnJocy5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKlxuICogUmV0dXJucyBhIG5ldyBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmbmAgd2l0aCBhIHRpbWVyLiBUaGUgd3JhcHBlciBsb2dzIHRoZVxuICogdGltZSBpdCB0YWtlcyB0byBleGVjdXRlIHRoZSBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gdGltZShuYW1lLCBmbikge1xuICB2YXIgc3RhcnQgPSBfLm5vdygpO1xuICB0cnkge1xuICAgIHJldHVybiBmbigpO1xuICB9IGZpbmFsbHkge1xuICAgIGNvbnNvbGUubG9nKG5hbWUgKyBcIiB0aW1lOiBcIiArIChfLm5vdygpIC0gc3RhcnQpICsgXCJtc1wiKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3RpbWUobmFtZSwgZm4pIHtcbiAgcmV0dXJuIGZuKCk7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///36\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, \"a\", function() { return /* reexport */ catmull_rom_2_bezier; });\n__webpack_require__.d(__webpack_exports__, \"b\", function() { return /* reexport */ parsePathString; });\n__webpack_require__.d(__webpack_exports__, \"c\", function() { return /* reexport */ pathToAbsolute; });\n__webpack_require__.d(__webpack_exports__, \"d\", function() { return /* reexport */ getSegments; });\n\n// UNUSED EXPORTS: parsePath, fillPath, fillPathByDiff, formatPath, pathIntersection, parsePathArray, path2Curve, reactPath, getArcParams, getLineIntersect, isPolygonsIntersect, isPointInPolygon\n\n// EXTERNAL MODULE: ./node_modules/@antv/util/esm/index.js + 110 modules\nvar esm = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/parse-path.js\n\nvar regexTags = /[MLHVQTCSAZ]([^MLHVQTCSAZ]*)/ig;\nvar regexDot = /[^\\s\\,]+/ig;\nfunction parsePath(p) {\n var path = p || [];\n if (Object(esm[\"isArray\"])(path)) {\n return path;\n }\n if (Object(esm[\"isString\"])(path)) {\n path = path.match(regexTags);\n Object(esm[\"each\"])(path, function (item, index) {\n // @ts-ignore\n item = item.match(regexDot);\n if (item[0].length > 1) {\n var tag = item[0].charAt(0);\n // @ts-ignore\n item.splice(1, 0, item[0].substr(1));\n // @ts-ignore\n item[0] = tag;\n }\n // @ts-ignore\n Object(esm[\"each\"])(item, function (sub, i) {\n if (!isNaN(sub)) {\n // @ts-ignore\n item[i] = +sub;\n }\n });\n // @ts-ignore\n path[index] = item;\n });\n return path;\n }\n}\n/* harmony default export */ var parse_path = (parsePath);\n//# sourceMappingURL=parse-path.js.map\n// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/index.js + 4 modules\nvar gl_matrix_esm = __webpack_require__(2);\n\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/node_modules/@antv/matrix-util/esm/ext.js\n/**\n * @description 扩展方法,提供 gl-matrix 为提供的方法\n * */\n\nfunction leftTranslate(out, a, v) {\n var transMat = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n gl_matrix_esm[\"a\" /* mat3 */].fromTranslation(transMat, v);\n return gl_matrix_esm[\"a\" /* mat3 */].multiply(out, transMat, a);\n}\nfunction leftRotate(out, a, rad) {\n var rotateMat = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n gl_matrix_esm[\"a\" /* mat3 */].fromRotation(rotateMat, rad);\n return gl_matrix_esm[\"a\" /* mat3 */].multiply(out, rotateMat, a);\n}\nfunction leftScale(out, a, v) {\n var scaleMat = [0, 0, 0, 0, 0, 0, 0, 0, 0];\n gl_matrix_esm[\"a\" /* mat3 */].fromScaling(scaleMat, v);\n return gl_matrix_esm[\"a\" /* mat3 */].multiply(out, scaleMat, a);\n}\nfunction leftMultiply(out, a, a1) {\n return gl_matrix_esm[\"a\" /* mat3 */].multiply(out, a1, a);\n}\n/**\n * 根据 actions 来做 transform\n * @param m\n * @param actions\n */\nfunction transform(m, actions) {\n var matrix = m ? [].concat(m) : [1, 0, 0, 0, 1, 0, 0, 0, 1];\n for (var i = 0, len = actions.length; i < len; i++) {\n var action = actions[i];\n switch (action[0]) {\n case 't':\n leftTranslate(matrix, matrix, [action[1], action[2]]);\n break;\n case 's':\n leftScale(matrix, matrix, [action[1], action[2]]);\n break;\n case 'r':\n leftRotate(matrix, matrix, action[1]);\n break;\n case 'm':\n leftMultiply(matrix, matrix, action[1]);\n break;\n default:\n break;\n }\n }\n return matrix;\n}\n/**\n * 向量 v1 到 向量 v2 夹角的方向\n * @param {Array} v1 向量\n * @param {Array} v2 向量\n * @return {Boolean} >= 0 顺时针 < 0 逆时针\n */\nfunction direction(v1, v2) {\n return v1[0] * v2[1] - v2[0] * v1[1];\n}\n/**\n * 二维向量 v1 到 v2 的夹角\n * @param v1\n * @param v2\n * @param direct\n */\nfunction angleTo(v1, v2, direct) {\n var ang = gl_matrix_esm[\"d\" /* vec2 */].angle(v1, v2);\n var angleLargeThanPI = direction(v1, v2) >= 0;\n if (direct) {\n if (angleLargeThanPI) {\n return Math.PI * 2 - ang;\n }\n return ang;\n }\n if (angleLargeThanPI) {\n return ang;\n }\n return Math.PI * 2 - ang;\n}\n/**\n * 计算二维向量的垂直向量\n * @param out\n * @param v\n * @param flag\n */\nfunction vertical(out, v, flag) {\n if (flag) {\n out[0] = v[1];\n out[1] = -1 * v[0];\n }\n else {\n out[0] = -1 * v[1];\n out[1] = v[0];\n }\n return out;\n}\n//# sourceMappingURL=ext.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/node_modules/@antv/matrix-util/esm/index.js\n\n\n\n//# sourceMappingURL=index.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/catmull-rom-2-bezier.js\n\nfunction smoothBezier(points, smooth, isLoop, constraint) {\n var cps = [];\n var hasConstraint = !!constraint;\n var prevPoint;\n var nextPoint;\n var min;\n var max;\n var nextCp0;\n var cp1;\n var cp0;\n if (hasConstraint) {\n min = constraint[0], max = constraint[1];\n for (var i = 0, l = points.length; i < l; i += 1) {\n var point = points[i];\n min = gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], min, point);\n max = gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], max, point);\n }\n }\n for (var i = 0, len = points.length; i < len; i += 1) {\n var point = points[i];\n if (i === 0 && !isLoop) {\n cp0 = point;\n }\n else if (i === len - 1 && !isLoop) {\n cp1 = point;\n cps.push(cp0);\n cps.push(cp1);\n }\n else {\n var prevIdx = [i ? i - 1 : len - 1, i - 1][isLoop ? 0 : 1];\n prevPoint = points[prevIdx];\n nextPoint = points[isLoop ? (i + 1) % len : i + 1];\n var v = [0, 0];\n v = gl_matrix_esm[\"d\" /* vec2 */].sub(v, nextPoint, prevPoint);\n v = gl_matrix_esm[\"d\" /* vec2 */].scale(v, v, smooth);\n var d0 = gl_matrix_esm[\"d\" /* vec2 */].distance(point, prevPoint);\n var d1 = gl_matrix_esm[\"d\" /* vec2 */].distance(point, nextPoint);\n var sum = d0 + d1;\n if (sum !== 0) {\n d0 /= sum;\n d1 /= sum;\n }\n var v1 = gl_matrix_esm[\"d\" /* vec2 */].scale([0, 0], v, -d0);\n var v2 = gl_matrix_esm[\"d\" /* vec2 */].scale([0, 0], v, d1);\n cp1 = gl_matrix_esm[\"d\" /* vec2 */].add([0, 0], point, v1);\n nextCp0 = gl_matrix_esm[\"d\" /* vec2 */].add([0, 0], point, v2);\n // 下一个控制点必须在这个点和下一个点之间\n nextCp0 = gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], nextCp0, gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], nextPoint, point));\n nextCp0 = gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], nextCp0, gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], nextPoint, point));\n // 重新计算 cp1 的值\n v1 = gl_matrix_esm[\"d\" /* vec2 */].sub([0, 0], nextCp0, point);\n v1 = gl_matrix_esm[\"d\" /* vec2 */].scale([0, 0], v1, -d0 / d1);\n cp1 = gl_matrix_esm[\"d\" /* vec2 */].add([0, 0], point, v1);\n // 上一个控制点必须要在上一个点和这一个点之间\n cp1 = gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], cp1, gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], prevPoint, point));\n cp1 = gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], cp1, gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], prevPoint, point));\n // 重新计算 nextCp0 的值\n v2 = gl_matrix_esm[\"d\" /* vec2 */].sub([0, 0], point, cp1);\n v2 = gl_matrix_esm[\"d\" /* vec2 */].scale([0, 0], v2, d1 / d0);\n nextCp0 = gl_matrix_esm[\"d\" /* vec2 */].add([0, 0], point, v2);\n if (hasConstraint) {\n cp1 = gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], cp1, min);\n cp1 = gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], cp1, max);\n nextCp0 = gl_matrix_esm[\"d\" /* vec2 */].max([0, 0], nextCp0, min);\n nextCp0 = gl_matrix_esm[\"d\" /* vec2 */].min([0, 0], nextCp0, max);\n }\n cps.push(cp0);\n cps.push(cp1);\n cp0 = nextCp0;\n }\n }\n if (isLoop) {\n cps.push(cps.shift());\n }\n return cps;\n}\n/**\n * create bezier spline from catmull rom spline\n * @param {Array} crp Catmull Rom Points\n * @param {boolean} z Spline is loop\n * @param {Array} constraint Constraint\n */\nfunction catmullRom2Bezier(crp, z, constraint) {\n if (z === void 0) { z = false; }\n if (constraint === void 0) { constraint = [\n [0, 0],\n [1, 1],\n ]; }\n var isLoop = !!z;\n var pointList = [];\n for (var i = 0, l = crp.length; i < l; i += 2) {\n pointList.push([crp[i], crp[i + 1]]);\n }\n var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);\n var len = pointList.length;\n var d1 = [];\n var cp1;\n var cp2;\n var p;\n for (var i = 0; i < len - 1; i += 1) {\n cp1 = controlPointList[i * 2];\n cp2 = controlPointList[i * 2 + 1];\n p = pointList[i + 1];\n d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]);\n }\n if (isLoop) {\n cp1 = controlPointList[len];\n cp2 = controlPointList[len + 1];\n p = pointList[0];\n d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]]);\n }\n return d1;\n}\n/* harmony default export */ var catmull_rom_2_bezier = (catmullRom2Bezier);\n//# sourceMappingURL=catmull-rom-2-bezier.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/fill-path.js\nfunction decasteljau(points, t) {\n var left = [];\n var right = [];\n function recurse(points, t) {\n if (points.length === 1) {\n left.push(points[0]);\n right.push(points[0]);\n }\n else {\n var middlePoints = [];\n for (var i = 0; i < points.length - 1; i++) {\n if (i === 0) {\n left.push(points[0]);\n }\n if (i === points.length - 2) {\n right.push(points[i + 1]);\n }\n middlePoints[i] = [(1 - t) * points[i][0] + t * points[i + 1][0], (1 - t) * points[i][1] + t * points[i + 1][1]];\n }\n recurse(middlePoints, t);\n }\n }\n if (points.length) {\n recurse(points, t);\n }\n return { left: left, right: right.reverse() };\n}\nfunction splitCurve(start, end, count) {\n var points = [[start[1], start[2]]];\n count = count || 2;\n var segments = [];\n if (end[0] === 'A') {\n points.push(end[6]);\n points.push(end[7]);\n }\n else if (end[0] === 'C') {\n points.push([end[1], end[2]]);\n points.push([end[3], end[4]]);\n points.push([end[5], end[6]]);\n }\n else if (end[0] === 'S' || end[0] === 'Q') {\n points.push([end[1], end[2]]);\n points.push([end[3], end[4]]);\n }\n else {\n points.push([end[1], end[2]]);\n }\n var leftSegments = points;\n var t = 1 / count;\n for (var i = 0; i < count - 1; i++) {\n var rt = t / (1 - t * i);\n var split = decasteljau(leftSegments, rt);\n segments.push(split.left);\n leftSegments = split.right;\n }\n segments.push(leftSegments);\n var result = segments.map(function (segment) {\n var cmd = [];\n if (segment.length === 4) {\n cmd.push('C');\n cmd = cmd.concat(segment[2]);\n }\n if (segment.length >= 3) {\n if (segment.length === 3) {\n cmd.push('Q');\n }\n cmd = cmd.concat(segment[1]);\n }\n if (segment.length === 2) {\n cmd.push('L');\n }\n cmd = cmd.concat(segment[segment.length - 1]);\n return cmd;\n });\n return result;\n}\nfunction splitSegment(start, end, count) {\n if (count === 1) {\n return [[].concat(start)];\n }\n var segments = [];\n if (end[0] === 'L' || end[0] === 'C' || end[0] === 'Q') {\n segments = segments.concat(splitCurve(start, end, count));\n }\n else {\n var temp = [].concat(start);\n if (temp[0] === 'M') {\n temp[0] = 'L';\n }\n for (var i = 0; i <= count - 1; i++) {\n segments.push(temp);\n }\n }\n return segments;\n}\nfunction fillPath(source, target) {\n if (source.length === 1) {\n return source;\n }\n var sourceLen = source.length - 1;\n var targetLen = target.length - 1;\n var ratio = sourceLen / targetLen;\n var segmentsToFill = [];\n if (source.length === 1 && source[0][0] === 'M') {\n for (var i = 0; i < targetLen - sourceLen; i++) {\n source.push(source[0]);\n }\n return source;\n }\n for (var i = 0; i < targetLen; i++) {\n var index = Math.floor(ratio * i);\n segmentsToFill[index] = (segmentsToFill[index] || 0) + 1;\n }\n var filled = segmentsToFill.reduce(function (filled, count, i) {\n if (i === sourceLen) {\n return filled.concat(source[sourceLen]);\n }\n return filled.concat(splitSegment(source[i], source[i + 1], count));\n }, []);\n filled.unshift(source[0]);\n if (target[targetLen] === 'Z' || target[targetLen] === 'z') {\n filled.push('Z');\n }\n return filled;\n}\n//# sourceMappingURL=fill-path.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/fill-path-by-diff.js\n\nfunction getMinDiff(del, add, modify) {\n var type = null;\n var min = modify;\n if (add < min) {\n min = add;\n type = 'add';\n }\n if (del < min) {\n min = del;\n type = 'del';\n }\n return {\n type: type,\n min: min,\n };\n}\n/*\n * https://en.wikipedia.org/wiki/Levenshtein_distance\n * 计算两条path的编辑距离\n */\nvar levenshteinDistance = function (source, target) {\n var sourceLen = source.length;\n var targetLen = target.length;\n var sourceSegment, targetSegment;\n var temp = 0;\n if (sourceLen === 0 || targetLen === 0) {\n return null;\n }\n var dist = [];\n for (var i = 0; i <= sourceLen; i++) {\n dist[i] = [];\n dist[i][0] = { min: i };\n }\n for (var j = 0; j <= targetLen; j++) {\n dist[0][j] = { min: j };\n }\n for (var i = 1; i <= sourceLen; i++) {\n sourceSegment = source[i - 1];\n for (var j = 1; j <= targetLen; j++) {\n targetSegment = target[j - 1];\n if (Object(esm[\"isEqual\"])(sourceSegment, targetSegment)) {\n temp = 0;\n }\n else {\n temp = 1;\n }\n var del = dist[i - 1][j].min + 1;\n var add = dist[i][j - 1].min + 1;\n var modify = dist[i - 1][j - 1].min + temp;\n dist[i][j] = getMinDiff(del, add, modify);\n }\n }\n return dist;\n};\nfunction fillPathByDiff(source, target) {\n var diffMatrix = levenshteinDistance(source, target);\n var sourceLen = source.length;\n var targetLen = target.length;\n var changes = [];\n var index = 1;\n var minPos = 1;\n // 如果source和target不是完全不相等\n // @ts-ignore\n if (diffMatrix[sourceLen][targetLen] !== sourceLen) {\n // 获取从source到target所需改动\n for (var i = 1; i <= sourceLen; i++) {\n var min = diffMatrix[i][i].min;\n minPos = i;\n for (var j = index; j <= targetLen; j++) {\n if (diffMatrix[i][j].min < min) {\n min = diffMatrix[i][j].min;\n minPos = j;\n }\n }\n index = minPos;\n if (diffMatrix[i][index].type) {\n changes.push({ index: i - 1, type: diffMatrix[i][index].type });\n }\n }\n // 对source进行增删path\n for (var i = changes.length - 1; i >= 0; i--) {\n index = changes[i].index;\n if (changes[i].type === 'add') {\n // @ts-ignore\n source.splice(index, 0, [].concat(source[index]));\n }\n else {\n // @ts-ignore\n source.splice(index, 1);\n }\n }\n }\n // source尾部补齐\n sourceLen = source.length;\n if (sourceLen < targetLen) {\n for (var i = 0; i < (targetLen - sourceLen); i++) {\n if (source[sourceLen - 1][0] === 'z' || source[sourceLen - 1][0] === 'Z') {\n // @ts-ignore\n source.splice(sourceLen - 2, 0, source[sourceLen - 2]);\n }\n else {\n // @ts-ignore\n source.push(source[sourceLen - 1]);\n }\n }\n }\n return source;\n}\n//# sourceMappingURL=fill-path-by-diff.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/format-path.js\n/*\n * 抽取pathSegment中的关键点\n * M,L,A,Q,H,V一个端点\n * Q, S抽取一个端点,一个控制点\n * C抽取一个端点,两个控制点\n */\nfunction _getSegmentPoints(segment) {\n var points = [];\n switch (segment[0]) {\n case 'M':\n points.push([segment[1], segment[2]]);\n break;\n case 'L':\n points.push([segment[1], segment[2]]);\n break;\n case 'A':\n points.push([segment[6], segment[7]]);\n break;\n case 'Q':\n points.push([segment[3], segment[4]]);\n points.push([segment[1], segment[2]]);\n break;\n case 'T':\n points.push([segment[1], segment[2]]);\n break;\n case 'C':\n points.push([segment[5], segment[6]]);\n points.push([segment[1], segment[2]]);\n points.push([segment[3], segment[4]]);\n break;\n case 'S':\n points.push([segment[3], segment[4]]);\n points.push([segment[1], segment[2]]);\n break;\n case 'H':\n points.push([segment[1], segment[1]]);\n break;\n case 'V':\n points.push([segment[1], segment[1]]);\n break;\n default:\n }\n return points;\n}\n// 将两个点均分成count个点\nfunction _splitPoints(points, former, count) {\n var result = [].concat(points);\n var index;\n var t = 1 / (count + 1);\n var formerEnd = _getSegmentPoints(former)[0];\n for (var i = 1; i <= count; i++) {\n t *= i;\n index = Math.floor(points.length * t);\n if (index === 0) {\n result.unshift([formerEnd[0] * t + points[index][0] * (1 - t), formerEnd[1] * t + points[index][1] * (1 - t)]);\n }\n else {\n result.splice(index, 0, [formerEnd[0] * t + points[index][0] * (1 - t), formerEnd[1] * t + points[index][1] * (1 - t)]);\n }\n }\n return result;\n}\nfunction formatPath(fromPath, toPath) {\n if (fromPath.length <= 1) {\n return fromPath;\n }\n var points;\n for (var i = 0; i < toPath.length; i++) {\n if (fromPath[i][0] !== toPath[i][0]) {\n // 获取fromPath的pathSegment的端点,根据toPath的指令对其改造\n points = _getSegmentPoints(fromPath[i]);\n switch (toPath[i][0]) {\n case 'M':\n fromPath[i] = ['M'].concat(points[0]);\n break;\n case 'L':\n fromPath[i] = ['L'].concat(points[0]);\n break;\n case 'A':\n fromPath[i] = [].concat(toPath[i]);\n fromPath[i][6] = points[0][0];\n fromPath[i][7] = points[0][1];\n break;\n case 'Q':\n if (points.length < 2) {\n if (i > 0) {\n points = _splitPoints(points, fromPath[i - 1], 1);\n }\n else {\n fromPath[i] = toPath[i];\n break;\n }\n }\n fromPath[i] = ['Q'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, []));\n break;\n case 'T':\n fromPath[i] = ['T'].concat(points[0]);\n break;\n case 'C':\n if (points.length < 3) {\n if (i > 0) {\n points = _splitPoints(points, fromPath[i - 1], 2);\n }\n else {\n fromPath[i] = toPath[i];\n break;\n }\n }\n fromPath[i] = ['C'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, []));\n break;\n case 'S':\n if (points.length < 2) {\n if (i > 0) {\n points = _splitPoints(points, fromPath[i - 1], 1);\n }\n else {\n fromPath[i] = toPath[i];\n break;\n }\n }\n fromPath[i] = ['S'].concat(points.reduce(function (arr, i) { return arr.concat(i); }, []));\n break;\n default:\n fromPath[i] = toPath[i];\n }\n }\n }\n return fromPath;\n}\n//# sourceMappingURL=format-path.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/rect-path.js\nfunction rectPath(x, y, w, h, r) {\n if (r) {\n return [\n ['M', +x + (+r), y],\n ['l', w - r * 2, 0],\n ['a', r, r, 0, 0, 1, r, r],\n ['l', 0, h - r * 2],\n ['a', r, r, 0, 0, 1, -r, r],\n ['l', r * 2 - w, 0],\n ['a', r, r, 0, 0, 1, -r, -r],\n ['l', 0, r * 2 - h],\n ['a', r, r, 0, 0, 1, r, -r],\n ['z'],\n ];\n }\n return [\n ['M', x, y],\n ['l', w, 0],\n ['l', 0, h],\n ['l', -w, 0],\n ['z'],\n ];\n // res.parsePathArray = parsePathArray;\n}\n//# sourceMappingURL=rect-path.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/parse-path-string.js\n\nvar SPACES = '\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029';\nvar PATH_COMMAND = new RegExp('([a-z])[' + SPACES + ',]*((-?\\\\d*\\\\.?\\\\d*(?:e[\\\\-+]?\\\\d+)?[' + SPACES + ']*,?[' + SPACES + ']*)+)', 'ig');\nvar PATH_VALUES = new RegExp('(-?\\\\d*\\\\.?\\\\d*(?:e[\\\\-+]?\\\\d+)?)[' + SPACES + ']*,?[' + SPACES + ']*', 'ig');\n// Parses given path string into an array of arrays of path segments\nfunction parsePathString(pathString) {\n if (!pathString) {\n return null;\n }\n if (Object(esm[\"isArray\"])(pathString)) {\n return pathString;\n }\n var paramCounts = {\n a: 7,\n c: 6,\n o: 2,\n h: 1,\n l: 2,\n m: 2,\n r: 4,\n q: 4,\n s: 4,\n t: 2,\n v: 1,\n u: 3,\n z: 0,\n };\n var data = [];\n String(pathString).replace(PATH_COMMAND, function (a, b, c) {\n var params = [];\n var name = b.toLowerCase();\n c.replace(PATH_VALUES, function (a, b) {\n b && params.push(+b);\n });\n if (name === 'm' && params.length > 2) {\n data.push([b].concat(params.splice(0, 2)));\n name = 'l';\n b = b === 'm' ? 'l' : 'L';\n }\n if (name === 'o' && params.length === 1) {\n data.push([b, params[0]]);\n }\n if (name === 'r') {\n data.push([b].concat(params));\n }\n else {\n while (params.length >= paramCounts[name]) {\n data.push([b].concat(params.splice(0, paramCounts[name])));\n if (!paramCounts[name]) {\n break;\n }\n }\n }\n return '';\n });\n return data;\n}\n//# sourceMappingURL=parse-path-string.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/path-2-absolute.js\n\nvar REGEX_MD = /[a-z]/;\nfunction toSymmetry(p, c) {\n return [\n c[0] + (c[0] - p[0]),\n c[1] + (c[1] - p[1]),\n ];\n}\nfunction pathToAbsolute(pathString) {\n var pathArray = parsePathString(pathString);\n if (!pathArray || !pathArray.length) {\n return [\n ['M', 0, 0],\n ];\n }\n var needProcess = false; // 如果存在小写的命令或者 V,H,T,S 则需要处理\n for (var i = 0; i < pathArray.length; i++) {\n var cmd = pathArray[i][0];\n // 如果存在相对位置的命令,则中断返回\n if (REGEX_MD.test(cmd) || ['V', 'H', 'T', 'S'].indexOf(cmd) >= 0) {\n needProcess = true;\n break;\n }\n }\n // 如果不存在相对命令,则直接返回\n // 如果在业务上都写绝对路径,这种方式最快,仅做了一次检测\n if (!needProcess) {\n return pathArray;\n }\n var res = [];\n var x = 0;\n var y = 0;\n var mx = 0;\n var my = 0;\n var start = 0;\n var pa0;\n var dots;\n var first = pathArray[0];\n if (first[0] === 'M' || first[0] === 'm') {\n x = +first[1];\n y = +first[2];\n mx = x;\n my = y;\n start++;\n res[0] = ['M', x, y];\n }\n for (var i = start, ii = pathArray.length; i < ii; i++) {\n var pa = pathArray[i];\n var preParams = res[i - 1]; // 取前一个已经处理后的节点,否则会出现问题\n var r = [];\n var cmd = pa[0];\n var upCmd = cmd.toUpperCase();\n if (cmd !== upCmd) {\n r[0] = upCmd;\n switch (upCmd) {\n case 'A':\n r[1] = pa[1];\n r[2] = pa[2];\n r[3] = pa[3];\n r[4] = pa[4];\n r[5] = pa[5];\n r[6] = +pa[6] + x;\n r[7] = +pa[7] + y;\n break;\n case 'V':\n r[1] = +pa[1] + y;\n break;\n case 'H':\n r[1] = +pa[1] + x;\n break;\n case 'M':\n mx = +pa[1] + x;\n my = +pa[2] + y;\n r[1] = mx;\n r[2] = my;\n break; // for lint\n default:\n for (var j = 1, jj = pa.length; j < jj; j++) {\n r[j] = +pa[j] + ((j % 2) ? x : y);\n }\n }\n }\n else { // 如果本来已经大写,则不处理\n r = pathArray[i];\n }\n // 需要在外面统一做,同时处理 V,H,S,T 等特殊指令\n switch (upCmd) {\n case 'Z':\n x = +mx;\n y = +my;\n break;\n case 'H':\n x = r[1];\n r = ['L', x, y];\n break;\n case 'V':\n y = r[1];\n r = ['L', x, y];\n break;\n case 'T':\n x = r[1];\n y = r[2];\n // 以 x, y 为中心的,上一个控制点的对称点\n // 需要假设上一个节点的命令为 Q\n var symetricT = toSymmetry([preParams[1], preParams[2]], [preParams[3], preParams[4]]);\n r = ['Q', symetricT[0], symetricT[1], x, y];\n break;\n case 'S':\n x = r[r.length - 2];\n y = r[r.length - 1];\n // 以 x,y 为中心,取上一个控制点,\n // 需要假设上一个线段为 C 或者 S\n var length_1 = preParams.length;\n var symetricS = toSymmetry([preParams[length_1 - 4], preParams[length_1 - 3]], [preParams[length_1 - 2], preParams[length_1 - 1]]);\n r = ['C', symetricS[0], symetricS[1], r[1], r[2], x, y];\n break;\n case 'M':\n mx = r[r.length - 2];\n my = r[r.length - 1];\n break; // for lint\n default:\n x = r[r.length - 2];\n y = r[r.length - 1];\n }\n res.push(r);\n }\n return res;\n}\n//# sourceMappingURL=path-2-absolute.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/process/arc-2-cubic.js\nvar TAU = Math.PI * 2;\nvar mapToEllipse = function (_a, rx, ry, cosphi, sinphi, centerx, centery) {\n var x = _a.x, y = _a.y;\n x *= rx;\n y *= ry;\n var xp = cosphi * x - sinphi * y;\n var yp = sinphi * x + cosphi * y;\n return {\n x: xp + centerx,\n y: yp + centery\n };\n};\nvar approxUnitArc = function (ang1, ang2) {\n // If 90 degree circular arc, use a constant\n // as derived from http://spencermortensen.com/articles/bezier-circle\n var a = ang2 === 1.5707963267948966\n ? 0.551915024494\n : ang2 === -1.5707963267948966\n ? -0.551915024494\n : 4 / 3 * Math.tan(ang2 / 4);\n var x1 = Math.cos(ang1);\n var y1 = Math.sin(ang1);\n var x2 = Math.cos(ang1 + ang2);\n var y2 = Math.sin(ang1 + ang2);\n return [\n {\n x: x1 - y1 * a,\n y: y1 + x1 * a\n },\n {\n x: x2 + y2 * a,\n y: y2 - x2 * a\n },\n {\n x: x2,\n y: y2\n }\n ];\n};\nvar vectorAngle = function (ux, uy, vx, vy) {\n var sign = (ux * vy - uy * vx < 0) ? -1 : 1;\n var dot = ux * vx + uy * vy;\n if (dot > 1) {\n dot = 1;\n }\n if (dot < -1) {\n dot = -1;\n }\n return sign * Math.acos(dot);\n};\nvar getArcCenter = function (px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinphi, cosphi, pxp, pyp) {\n var rxsq = Math.pow(rx, 2);\n var rysq = Math.pow(ry, 2);\n var pxpsq = Math.pow(pxp, 2);\n var pypsq = Math.pow(pyp, 2);\n var radicant = (rxsq * rysq) - (rxsq * pypsq) - (rysq * pxpsq);\n if (radicant < 0) {\n radicant = 0;\n }\n radicant /= (rxsq * pypsq) + (rysq * pxpsq);\n radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1);\n var centerxp = radicant * rx / ry * pyp;\n var centeryp = radicant * -ry / rx * pxp;\n var centerx = cosphi * centerxp - sinphi * centeryp + (px + cx) / 2;\n var centery = sinphi * centerxp + cosphi * centeryp + (py + cy) / 2;\n var vx1 = (pxp - centerxp) / rx;\n var vy1 = (pyp - centeryp) / ry;\n var vx2 = (-pxp - centerxp) / rx;\n var vy2 = (-pyp - centeryp) / ry;\n var ang1 = vectorAngle(1, 0, vx1, vy1);\n var ang2 = vectorAngle(vx1, vy1, vx2, vy2);\n if (sweepFlag === 0 && ang2 > 0) {\n ang2 -= TAU;\n }\n if (sweepFlag === 1 && ang2 < 0) {\n ang2 += TAU;\n }\n return [centerx, centery, ang1, ang2];\n};\nvar arcToBezier = function (_a) {\n var px = _a.px, py = _a.py, cx = _a.cx, cy = _a.cy, rx = _a.rx, ry = _a.ry, _b = _a.xAxisRotation, xAxisRotation = _b === void 0 ? 0 : _b, _c = _a.largeArcFlag, largeArcFlag = _c === void 0 ? 0 : _c, _d = _a.sweepFlag, sweepFlag = _d === void 0 ? 0 : _d;\n var curves = [];\n if (rx === 0 || ry === 0) {\n return [{ x1: 0, y1: 0, x2: 0, y2: 0, x: cx, y: cy }];\n }\n var sinphi = Math.sin(xAxisRotation * TAU / 360);\n var cosphi = Math.cos(xAxisRotation * TAU / 360);\n var pxp = cosphi * (px - cx) / 2 + sinphi * (py - cy) / 2;\n var pyp = -sinphi * (px - cx) / 2 + cosphi * (py - cy) / 2;\n if (pxp === 0 && pyp === 0) {\n return [{ x1: 0, y1: 0, x2: 0, y2: 0, x: cx, y: cy }];\n }\n rx = Math.abs(rx);\n ry = Math.abs(ry);\n var lambda = Math.pow(pxp, 2) / Math.pow(rx, 2) +\n Math.pow(pyp, 2) / Math.pow(ry, 2);\n if (lambda > 1) {\n rx *= Math.sqrt(lambda);\n ry *= Math.sqrt(lambda);\n }\n var _e = getArcCenter(px, py, cx, cy, rx, ry, largeArcFlag, sweepFlag, sinphi, cosphi, pxp, pyp), centerx = _e[0], centery = _e[1], ang1 = _e[2], ang2 = _e[3];\n // If 'ang2' == 90.0000000001, then `ratio` will evaluate to\n // 1.0000000001. This causes `segments` to be greater than one, which is an\n // unecessary split, and adds extra points to the bezier curve. To alleviate\n // this issue, we round to 1.0 when the ratio is close to 1.0.\n var ratio = Math.abs(ang2) / (TAU / 4);\n if (Math.abs(1.0 - ratio) < 0.0000001) {\n ratio = 1.0;\n }\n var segments = Math.max(Math.ceil(ratio), 1);\n ang2 /= segments;\n for (var i = 0; i < segments; i++) {\n curves.push(approxUnitArc(ang1, ang2));\n ang1 += ang2;\n }\n return curves.map(function (curve) {\n var _a = mapToEllipse(curve[0], rx, ry, cosphi, sinphi, centerx, centery), x1 = _a.x, y1 = _a.y;\n var _b = mapToEllipse(curve[1], rx, ry, cosphi, sinphi, centerx, centery), x2 = _b.x, y2 = _b.y;\n var _c = mapToEllipse(curve[2], rx, ry, cosphi, sinphi, centerx, centery), x = _c.x, y = _c.y;\n return { x1: x1, y1: y1, x2: x2, y2: y2, x: x, y: y };\n });\n};\nfunction arcToCubic(x1, y1, rx, ry, angle, LAF, SF, x2, y2) {\n var curves = arcToBezier({\n px: x1,\n py: y1,\n cx: x2,\n cy: y2,\n rx: rx,\n ry: ry,\n xAxisRotation: angle,\n largeArcFlag: LAF,\n sweepFlag: SF,\n });\n return curves.reduce(function (prev, cur) {\n var x1 = cur.x1, y1 = cur.y1, x2 = cur.x2, y2 = cur.y2, x = cur.x, y = cur.y;\n prev.push(x1, y1, x2, y2, x, y);\n return prev;\n }, []);\n}\n//# sourceMappingURL=arc-2-cubic.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/process/quad-2-cubic.js\nfunction quadToCubic(x1, y1, qx, qy, x2, y2) {\n var r13 = 1 / 3;\n var r23 = 2 / 3;\n return [\n r13 * x1 + r23 * qx,\n r13 * y1 + r23 * qy,\n r13 * x2 + r23 * qx,\n r13 * y2 + r23 * qy,\n x2, y2, // x,y\n ];\n}\n//# sourceMappingURL=quad-2-cubic.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/process/line-2-cubic.js\n// export function getPointAtSegLength(p1x: number, p1y: number, c1x: number, c1y: number, c2x: number, c2y: number, p2x: number, p2y: number, t: number) {\n// const t1 = 1 - t;\n// return {\n// x: (t1 ** 3) * p1x\n// + t1 * t1 * 3 * t * c1x\n// + t1 * 3 * t * t * c2x\n// + (t ** 3) * p2x,\n// y: (t1 ** 3) * p1y\n// + t1 * t1 * 3 * t * c1y\n// + t1 * 3 * t * t * c2y\n// + (t ** 3) * p2y,\n// };\n// }\n// export function midPoint(a: number[], b: number[], t: number) {\n// const ax = a[0];\n// const ay = a[1];\n// const bx = b[0];\n// const by = b[1];\n// return [ax + (bx - ax) * t, ay + (by - ay) * t];\n// }\nfunction lineToCubic(x1, y1, x2, y2) {\n return [x1, y1, x2, y2, x2, y2];\n // const t = 0.5;\n // const p0 = [x1, y1];\n // const p1 = [x2, y2];\n // const p2 = midPoint(p0, p1, t);\n // const p3 = midPoint(p1, p2, t);\n // const p4 = midPoint(p2, p3, t);\n // const p5 = midPoint(p3, p4, t);\n // const p6 = midPoint(p4, p5, t);\n // const cp1 = getPointAtSegLength.apply(0, p0.concat(p2, p4, p6, t));\n // const cp2 = getPointAtSegLength.apply(0, p6.concat(p5, p3, p1, 0));\n // return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2];\n}\n//# sourceMappingURL=line-2-cubic.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/process/segment-2-cubic.js\n\n\n\nfunction segmentToCubic(segment, params) {\n if ('TQ'.indexOf(segment[0]) < 0) {\n params.qx = null;\n params.qy = null;\n }\n var _a = segment.slice(1), s1 = _a[0], s2 = _a[1];\n switch (segment[0]) {\n case 'M':\n params.x = s1;\n params.y = s2;\n return segment;\n case 'A':\n return ['C'].concat(arcToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1))));\n case 'Q':\n params.qx = s1;\n params.qy = s2;\n return ['C'].concat(quadToCubic.apply(0, [params.x1, params.y1].concat(segment.slice(1))));\n case 'L':\n // @ts-ignore\n return ['C'].concat(lineToCubic(params.x1, params.y1, segment[1], segment[2]));\n case 'H':\n // @ts-ignore\n return ['C'].concat(lineToCubic(params.x1, params.y1, segment[1], params.y1));\n case 'V':\n // @ts-ignore\n return ['C'].concat(lineToCubic(params.x1, params.y1, params.x1, segment[1]));\n case 'Z':\n // @ts-ignore\n return ['C'].concat(lineToCubic(params.x1, params.y1, params.x, params.y));\n default:\n }\n return segment;\n}\n//# sourceMappingURL=segment-2-cubic.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/path-2-curve.js\n\n\nfunction pathToCurve(path, needZCommandIndexes) {\n if (needZCommandIndexes === void 0) { needZCommandIndexes = false; }\n var pathArray = pathToAbsolute(path);\n var params = {\n x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null,\n };\n var allPathCommands = [];\n var pathCommand = '';\n var ii = pathArray.length;\n var segment;\n var seglen;\n var zCommandIndexes = [];\n for (var i = 0; i < ii; i += 1) {\n if (pathArray[i])\n pathCommand = pathArray[i][0];\n allPathCommands[i] = pathCommand;\n pathArray[i] = segmentToCubic(pathArray[i], params);\n fixArc(pathArray, allPathCommands, i);\n ii = pathArray.length; // solves curveArrays ending in Z\n // keep Z command account for lineJoin\n // @see https://github.com/antvis/util/issues/68\n if (pathCommand === 'Z') {\n zCommandIndexes.push(i);\n }\n segment = pathArray[i];\n seglen = segment.length;\n params.x1 = +segment[seglen - 2];\n params.y1 = +segment[seglen - 1];\n params.x2 = +(segment[seglen - 4]) || params.x1;\n params.y2 = +(segment[seglen - 3]) || params.y1;\n }\n if (needZCommandIndexes) {\n return [pathArray, zCommandIndexes];\n }\n else {\n return pathArray;\n }\n}\nfunction fixArc(pathArray, allPathCommands, i) {\n if (pathArray[i].length > 7) {\n pathArray[i].shift();\n var pi = pathArray[i];\n // const ni = i + 1;\n var ni = i;\n while (pi.length) {\n // if created multiple C:s, their original seg is saved\n allPathCommands[i] = 'A';\n // @ts-ignore\n pathArray.splice(ni += 1, 0, ['C'].concat(pi.splice(0, 6)));\n }\n pathArray.splice(i, 1);\n }\n}\n//# sourceMappingURL=path-2-curve.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/path-intersection.js\n\n\n\nvar base3 = function (t, p1, p2, p3, p4) {\n var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4;\n var t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;\n return t * t2 - 3 * p1 + 3 * p2;\n};\nvar bezlen = function (x1, y1, x2, y2, x3, y3, x4, y4, z) {\n if (z === null) {\n z = 1;\n }\n z = z > 1 ? 1 : z < 0 ? 0 : z;\n var z2 = z / 2;\n var n = 12;\n var Tvalues = [-0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816, 0.9816];\n var Cvalues = [0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472];\n var sum = 0;\n for (var i = 0; i < n; i++) {\n var ct = z2 * Tvalues[i] + z2;\n var xbase = base3(ct, x1, x2, x3, x4);\n var ybase = base3(ct, y1, y2, y3, y4);\n var comb = xbase * xbase + ybase * ybase;\n sum += Cvalues[i] * Math.sqrt(comb);\n }\n return z2 * sum;\n};\nvar curveDim = function (x0, y0, x1, y1, x2, y2, x3, y3) {\n var tvalues = [];\n var bounds = [\n [],\n [],\n ];\n var a;\n var b;\n var c;\n var t;\n for (var i = 0; i < 2; ++i) {\n if (i === 0) {\n b = 6 * x0 - 12 * x1 + 6 * x2;\n a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n c = 3 * x1 - 3 * x0;\n }\n else {\n b = 6 * y0 - 12 * y1 + 6 * y2;\n a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n c = 3 * y1 - 3 * y0;\n }\n if (Math.abs(a) < 1e-12) {\n if (Math.abs(b) < 1e-12) {\n continue;\n }\n t = -c / b;\n if (t > 0 && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n var b2ac = b * b - 4 * c * a;\n var sqrtb2ac = Math.sqrt(b2ac);\n if (b2ac < 0) {\n continue;\n }\n var t1 = (-b + sqrtb2ac) / (2 * a);\n if (t1 > 0 && t1 < 1) {\n tvalues.push(t1);\n }\n var t2 = (-b - sqrtb2ac) / (2 * a);\n if (t2 > 0 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n var j = tvalues.length;\n var jlen = j;\n var mt;\n while (j--) {\n t = tvalues[j];\n mt = 1 - t;\n bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n }\n bounds[0][jlen] = x0;\n bounds[1][jlen] = y0;\n bounds[0][jlen + 1] = x3;\n bounds[1][jlen + 1] = y3;\n bounds[0].length = bounds[1].length = jlen + 2;\n return {\n min: {\n x: Math.min.apply(0, bounds[0]),\n y: Math.min.apply(0, bounds[1]),\n },\n max: {\n x: Math.max.apply(0, bounds[0]),\n y: Math.max.apply(0, bounds[1]),\n },\n };\n};\nvar intersect = function (x1, y1, x2, y2, x3, y3, x4, y4) {\n if (Math.max(x1, x2) < Math.min(x3, x4) ||\n Math.min(x1, x2) > Math.max(x3, x4) ||\n Math.max(y1, y2) < Math.min(y3, y4) ||\n Math.min(y1, y2) > Math.max(y3, y4)) {\n return;\n }\n var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);\n var ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);\n var denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n if (!denominator) {\n return;\n }\n var px = nx / denominator;\n var py = ny / denominator;\n var px2 = +px.toFixed(2);\n var py2 = +py.toFixed(2);\n if (px2 < +Math.min(x1, x2).toFixed(2) ||\n px2 > +Math.max(x1, x2).toFixed(2) ||\n px2 < +Math.min(x3, x4).toFixed(2) ||\n px2 > +Math.max(x3, x4).toFixed(2) ||\n py2 < +Math.min(y1, y2).toFixed(2) ||\n py2 > +Math.max(y1, y2).toFixed(2) ||\n py2 < +Math.min(y3, y4).toFixed(2) ||\n py2 > +Math.max(y3, y4).toFixed(2)) {\n return;\n }\n return {\n x: px,\n y: py,\n };\n};\nvar isPointInsideBBox = function (bbox, x, y) {\n return x >= bbox.x &&\n x <= bbox.x + bbox.width &&\n y >= bbox.y &&\n y <= bbox.y + bbox.height;\n};\nvar box = function (x, y, width, height) {\n if (x === null) {\n x = y = width = height = 0;\n }\n if (y === null) {\n y = x.y;\n width = x.width;\n height = x.height;\n x = x.x;\n }\n return {\n x: x,\n y: y,\n width: width,\n w: width,\n height: height,\n h: height,\n x2: x + width,\n y2: y + height,\n cx: x + width / 2,\n cy: y + height / 2,\n r1: Math.min(width, height) / 2,\n r2: Math.max(width, height) / 2,\n r0: Math.sqrt(width * width + height * height) / 2,\n path: rectPath(x, y, width, height),\n vb: [x, y, width, height].join(' '),\n };\n};\nvar isBBoxIntersect = function (bbox1, bbox2) {\n // @ts-ignore\n bbox1 = box(bbox1);\n // @ts-ignore\n bbox2 = box(bbox2);\n return isPointInsideBBox(bbox2, bbox1.x, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);\n};\nvar bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n if (!Object(esm[\"isArray\"])(p1x)) {\n p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];\n }\n var bbox = curveDim.apply(null, p1x);\n return box(bbox.min.x, bbox.min.y, bbox.max.x - bbox.min.x, bbox.max.y - bbox.min.y);\n};\nvar findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n var t1 = 1 - t;\n var t13 = Math.pow(t1, 3);\n var t12 = Math.pow(t1, 2);\n var t2 = t * t;\n var t3 = t2 * t;\n var x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x;\n var y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y;\n var mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x);\n var my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y);\n var nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x);\n var ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y);\n var ax = t1 * p1x + t * c1x;\n var ay = t1 * p1y + t * c1y;\n var cx = t1 * c2x + t * p2x;\n var cy = t1 * c2y + t * p2y;\n var alpha = (90 - Math.atan2(mx - nx, my - ny) * 180 / Math.PI);\n // (mx > nx || my < ny) && (alpha += 180);\n return {\n x: x,\n y: y,\n m: {\n x: mx,\n y: my,\n },\n n: {\n x: nx,\n y: ny,\n },\n start: {\n x: ax,\n y: ay,\n },\n end: {\n x: cx,\n y: cy,\n },\n alpha: alpha,\n };\n};\nvar interHelper = function (bez1, bez2, justCount) {\n // @ts-ignore\n var bbox1 = bezierBBox(bez1);\n // @ts-ignore\n var bbox2 = bezierBBox(bez2);\n if (!isBBoxIntersect(bbox1, bbox2)) {\n return justCount ? 0 : [];\n }\n var l1 = bezlen.apply(0, bez1);\n var l2 = bezlen.apply(0, bez2);\n var n1 = ~~(l1 / 8);\n var n2 = ~~(l2 / 8);\n var dots1 = [];\n var dots2 = [];\n var xy = {};\n var res = justCount ? 0 : [];\n for (var i = 0; i < n1 + 1; i++) {\n var d = findDotsAtSegment.apply(0, bez1.concat(i / n1));\n dots1.push({\n x: d.x,\n y: d.y,\n t: i / n1,\n });\n }\n for (var i = 0; i < n2 + 1; i++) {\n var d = findDotsAtSegment.apply(0, bez2.concat(i / n2));\n dots2.push({\n x: d.x,\n y: d.y,\n t: i / n2,\n });\n }\n for (var i = 0; i < n1; i++) {\n for (var j = 0; j < n2; j++) {\n var di = dots1[i];\n var di1 = dots1[i + 1];\n var dj = dots2[j];\n var dj1 = dots2[j + 1];\n var ci = Math.abs(di1.x - di.x) < 0.001 ? 'y' : 'x';\n var cj = Math.abs(dj1.x - dj.x) < 0.001 ? 'y' : 'x';\n var is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);\n if (is) {\n if (xy[is.x.toFixed(4)] === is.y.toFixed(4)) {\n continue;\n }\n xy[is.x.toFixed(4)] = is.y.toFixed(4);\n var t1 = di.t + Math.abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t);\n var t2 = dj.t + Math.abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);\n if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {\n if (justCount) {\n // @ts-ignore\n res++;\n }\n else {\n // @ts-ignore\n res.push({\n x: is.x,\n y: is.y,\n t1: t1,\n t2: t2,\n });\n }\n }\n }\n }\n }\n return res;\n};\nvar interPathHelper = function (path1, path2, justCount) {\n // @ts-ignore\n path1 = pathToCurve(path1);\n // @ts-ignore\n path2 = pathToCurve(path2);\n var x1;\n var y1;\n var x2;\n var y2;\n var x1m;\n var y1m;\n var x2m;\n var y2m;\n var bez1;\n var bez2;\n var res = justCount ? 0 : [];\n for (var i = 0, ii = path1.length; i < ii; i++) {\n var pi = path1[i];\n if (pi[0] === 'M') {\n x1 = x1m = pi[1];\n y1 = y1m = pi[2];\n }\n else {\n if (pi[0] === 'C') {\n bez1 = [x1, y1].concat(pi.slice(1));\n x1 = bez1[6];\n y1 = bez1[7];\n }\n else {\n bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];\n x1 = x1m;\n y1 = y1m;\n }\n for (var j = 0, jj = path2.length; j < jj; j++) {\n var pj = path2[j];\n if (pj[0] === 'M') {\n x2 = x2m = pj[1];\n y2 = y2m = pj[2];\n }\n else {\n if (pj[0] === 'C') {\n bez2 = [x2, y2].concat(pj.slice(1));\n x2 = bez2[6];\n y2 = bez2[7];\n }\n else {\n bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];\n x2 = x2m;\n y2 = y2m;\n }\n var intr = interHelper(bez1, bez2, justCount);\n if (justCount) {\n // @ts-ignore\n res += intr;\n }\n else {\n // @ts-ignore\n for (var k = 0, kk = intr.length; k < kk; k++) {\n intr[k].segment1 = i;\n intr[k].segment2 = j;\n intr[k].bez1 = bez1;\n intr[k].bez2 = bez2;\n }\n // @ts-ignore\n res = res.concat(intr);\n }\n }\n }\n }\n }\n return res;\n};\nfunction pathIntersection(path1, path2) {\n // @ts-ignore\n return interPathHelper(path1, path2);\n}\n//# sourceMappingURL=path-intersection.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/parse-path-array.js\nvar p2s = /,?([a-z]),?/gi;\nfunction parsePathArray(path) {\n return path.join(',').replace(p2s, '$1');\n}\n//# sourceMappingURL=parse-path-array.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/get-arc-params.js\n\n// 向量长度\nfunction vMag(v) {\n return Math.sqrt(v[0] * v[0] + v[1] * v[1]);\n}\n// u.v/|u||v|,计算夹角的余弦值\nfunction vRatio(u, v) {\n // 当存在一个向量的长度为 0 时,夹角也为 0,即夹角的余弦值为 1\n return vMag(u) * vMag(v) ? (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)) : 1;\n}\n// 向量角度\nfunction vAngle(u, v) {\n return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) * Math.acos(vRatio(u, v));\n}\n/**\n * 判断两个点是否重合,点坐标的格式为 [x, y]\n * @param {Array} point1 第一个点\n * @param {Array} point2 第二个点\n */\nfunction isSamePoint(point1, point2) {\n return point1[0] === point2[0] && point1[1] === point2[1];\n}\n// A 0:rx 1:ry 2:x-axis-rotation 3:large-arc-flag 4:sweep-flag 5: x 6: y\nfunction getArcParams(startPoint, params) {\n var rx = params[1];\n var ry = params[2];\n var xRotation = Object(esm[\"mod\"])(Object(esm[\"toRadian\"])(params[3]), Math.PI * 2);\n var arcFlag = params[4];\n var sweepFlag = params[5];\n // 弧形起点坐标\n var x1 = startPoint[0];\n var y1 = startPoint[1];\n // 弧形终点坐标\n var x2 = params[6];\n var y2 = params[7];\n var xp = (Math.cos(xRotation) * (x1 - x2)) / 2.0 + (Math.sin(xRotation) * (y1 - y2)) / 2.0;\n var yp = (-1 * Math.sin(xRotation) * (x1 - x2)) / 2.0 + (Math.cos(xRotation) * (y1 - y2)) / 2.0;\n var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);\n if (lambda > 1) {\n rx *= Math.sqrt(lambda);\n ry *= Math.sqrt(lambda);\n }\n var diff = rx * rx * (yp * yp) + ry * ry * (xp * xp);\n var f = diff ? Math.sqrt((rx * rx * (ry * ry) - diff) / diff) : 1;\n if (arcFlag === sweepFlag) {\n f *= -1;\n }\n if (isNaN(f)) {\n f = 0;\n }\n // 旋转前的起点坐标,且当长半轴和短半轴的长度为 0 时,坐标按 (0, 0) 处理\n var cxp = ry ? (f * rx * yp) / ry : 0;\n var cyp = rx ? (f * -ry * xp) / rx : 0;\n // 椭圆圆心坐标\n var cx = (x1 + x2) / 2.0 + Math.cos(xRotation) * cxp - Math.sin(xRotation) * cyp;\n var cy = (y1 + y2) / 2.0 + Math.sin(xRotation) * cxp + Math.cos(xRotation) * cyp;\n // 起始点的单位向量\n var u = [(xp - cxp) / rx, (yp - cyp) / ry];\n // 终止点的单位向量\n var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry];\n // 计算起始点和圆心的连线,与 x 轴正方向的夹角\n var theta = vAngle([1, 0], u);\n // 计算圆弧起始点和终止点与椭圆圆心连线的夹角\n var dTheta = vAngle(u, v);\n if (vRatio(u, v) <= -1) {\n dTheta = Math.PI;\n }\n if (vRatio(u, v) >= 1) {\n dTheta = 0;\n }\n if (sweepFlag === 0 && dTheta > 0) {\n dTheta = dTheta - 2 * Math.PI;\n }\n if (sweepFlag === 1 && dTheta < 0) {\n dTheta = dTheta + 2 * Math.PI;\n }\n return {\n cx: cx,\n cy: cy,\n // 弧形的起点和终点相同时,长轴和短轴的长度按 0 处理\n rx: isSamePoint(startPoint, [x2, y2]) ? 0 : rx,\n ry: isSamePoint(startPoint, [x2, y2]) ? 0 : ry,\n startAngle: theta,\n endAngle: theta + dTheta,\n xRotation: xRotation,\n arcFlag: arcFlag,\n sweepFlag: sweepFlag,\n };\n}\n//# sourceMappingURL=get-arc-params.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/path-2-segments.js\n\n\n\n// 点对称\nfunction path_2_segments_toSymmetry(point, center) {\n return [center[0] + (center[0] - point[0]), center[1] + (center[1] - point[1])];\n}\nfunction getSegments(path) {\n path = parse_path(path);\n var segments = [];\n var currentPoint = null; // 当前图形\n var nextParams = null; // 下一节点的 path 参数\n var startMovePoint = null; // 开始 M 的点,可能会有多个\n var lastStartMovePointIndex = 0; // 最近一个开始点 M 的索引\n var count = path.length;\n for (var i = 0; i < count; i++) {\n var params = path[i];\n nextParams = path[i + 1];\n var command = params[0];\n // 数学定义上的参数,便于后面的计算\n var segment = {\n command: command,\n prePoint: currentPoint,\n params: params,\n startTangent: null,\n endTangent: null,\n };\n switch (command) {\n case 'M':\n startMovePoint = [params[1], params[2]];\n lastStartMovePointIndex = i;\n break;\n case 'A':\n var arcParams = getArcParams(currentPoint, params);\n segment['arcParams'] = arcParams;\n break;\n default:\n break;\n }\n if (command === 'Z') {\n // 有了 Z 后,当前节点从开始 M 的点开始\n currentPoint = startMovePoint;\n // 如果当前点的命令为 Z,相当于当前点为最近一个 M 点,则下一个点直接指向最近一个 M 点的下一个点\n nextParams = path[lastStartMovePointIndex + 1];\n }\n else {\n var len = params.length;\n currentPoint = [params[len - 2], params[len - 1]];\n }\n if (nextParams && nextParams[0] === 'Z') {\n // 如果下一个点的命令为 Z,则下一个点直接指向最近一个 M 点\n nextParams = path[lastStartMovePointIndex];\n if (segments[lastStartMovePointIndex]) {\n // 如果下一个点的命令为 Z,则最近一个 M 点的前一个点为当前点\n segments[lastStartMovePointIndex].prePoint = currentPoint;\n }\n }\n segment['currentPoint'] = currentPoint;\n // 如果当前点与最近一个 M 点相同,则最近一个 M 点的前一个点为当前点的前一个点\n if (segments[lastStartMovePointIndex] &&\n isSamePoint(currentPoint, segments[lastStartMovePointIndex].currentPoint)) {\n segments[lastStartMovePointIndex].prePoint = segment.prePoint;\n }\n var nextPoint = nextParams ? [nextParams[nextParams.length - 2], nextParams[nextParams.length - 1]] : null;\n segment['nextPoint'] = nextPoint;\n // Add startTangent and endTangent\n var prePoint = segment.prePoint;\n if (['L', 'H', 'V'].includes(command)) {\n segment.startTangent = [prePoint[0] - currentPoint[0], prePoint[1] - currentPoint[1]];\n segment.endTangent = [currentPoint[0] - prePoint[0], currentPoint[1] - prePoint[1]];\n }\n else if (command === 'Q') {\n // 二次贝塞尔曲线只有一个控制点\n var cp = [params[1], params[2]];\n // 二次贝塞尔曲线的终点为 currentPoint\n segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]];\n segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]];\n }\n else if (command === 'T') {\n var preSegment = segments[i - 1];\n var cp = path_2_segments_toSymmetry(preSegment.currentPoint, prePoint);\n if (preSegment.command === 'Q') {\n segment.command = 'Q';\n segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]];\n segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]];\n }\n else {\n segment.command = 'TL';\n segment.startTangent = [prePoint[0] - currentPoint[0], prePoint[1] - currentPoint[1]];\n segment.endTangent = [currentPoint[0] - prePoint[0], currentPoint[1] - prePoint[1]];\n }\n }\n else if (command === 'C') {\n // 三次贝塞尔曲线有两个控制点\n var cp1 = [params[1], params[2]];\n var cp2 = [params[3], params[4]];\n segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]];\n segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];\n // horizontal line, eg. ['C', 100, 100, 100, 100, 200, 200]\n if (segment.startTangent[0] === 0 && segment.startTangent[1] === 0) {\n segment.startTangent = [cp1[0] - cp2[0], cp1[1] - cp2[1]];\n }\n if (segment.endTangent[0] === 0 && segment.endTangent[1] === 0) {\n segment.endTangent = [cp2[0] - cp1[0], cp2[1] - cp1[1]];\n }\n }\n else if (command === 'S') {\n var preSegment = segments[i - 1];\n var cp1 = path_2_segments_toSymmetry(preSegment.currentPoint, prePoint);\n var cp2 = [params[1], params[2]];\n if (preSegment.command === 'C') {\n segment.command = 'C'; // 将 S 命令变换为 C 命令\n segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]];\n segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];\n }\n else {\n segment.command = 'SQ'; // 将 S 命令变换为 SQ 命令\n segment.startTangent = [prePoint[0] - cp2[0], prePoint[1] - cp2[1]];\n segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];\n }\n }\n else if (command === 'A') {\n var d = 0.001;\n var _a = segment['arcParams'] || {}, _b = _a.cx, cx = _b === void 0 ? 0 : _b, _c = _a.cy, cy = _c === void 0 ? 0 : _c, _d = _a.rx, rx = _d === void 0 ? 0 : _d, _e = _a.ry, ry = _e === void 0 ? 0 : _e, _f = _a.sweepFlag, sweepFlag = _f === void 0 ? 0 : _f, _g = _a.startAngle, startAngle = _g === void 0 ? 0 : _g, _h = _a.endAngle, endAngle = _h === void 0 ? 0 : _h;\n if (sweepFlag === 0) {\n d *= -1;\n }\n var dx1 = rx * Math.cos(startAngle - d) + cx;\n var dy1 = ry * Math.sin(startAngle - d) + cy;\n segment.startTangent = [dx1 - startMovePoint[0], dy1 - startMovePoint[1]];\n var dx2 = rx * Math.cos(startAngle + endAngle + d) + cx;\n var dy2 = ry * Math.sin(startAngle + endAngle - d) + cy;\n segment.endTangent = [prePoint[0] - dx2, prePoint[1] - dy2];\n }\n segments.push(segment);\n }\n return segments;\n}\n//# sourceMappingURL=path-2-segments.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/get-line-intersect.js\nvar isBetween = function (value, min, max) { return value >= min && value <= max; };\nfunction getLineIntersect(p0, p1, p2, p3) {\n var tolerance = 0.001;\n var E = {\n x: p2.x - p0.x,\n y: p2.y - p0.y,\n };\n var D0 = {\n x: p1.x - p0.x,\n y: p1.y - p0.y,\n };\n var D1 = {\n x: p3.x - p2.x,\n y: p3.y - p2.y,\n };\n var kross = D0.x * D1.y - D0.y * D1.x;\n var sqrKross = kross * kross;\n var sqrLen0 = D0.x * D0.x + D0.y * D0.y;\n var sqrLen1 = D1.x * D1.x + D1.y * D1.y;\n var point = null;\n if (sqrKross > tolerance * sqrLen0 * sqrLen1) {\n var s = (E.x * D1.y - E.y * D1.x) / kross;\n var t = (E.x * D0.y - E.y * D0.x) / kross;\n if (isBetween(s, 0, 1) && isBetween(t, 0, 1)) {\n point = {\n x: p0.x + s * D0.x,\n y: p0.y + s * D0.y,\n };\n }\n }\n return point;\n}\n;\n//# sourceMappingURL=get-line-intersect.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/point-in-polygon.js\n/**\n * @fileoverview 判断点是否在多边形内\n * @author dxq613@gmail.com\n */\n// 多边形的射线检测,参考:https://blog.csdn.net/WilliamSun0122/article/details/77994526\nvar tolerance = 1e-6;\n// 三态函数,判断两个double在eps精度下的大小关系\nfunction dcmp(x) {\n if (Math.abs(x) < tolerance) {\n return 0;\n }\n return x < 0 ? -1 : 1;\n}\n// 判断点Q是否在p1和p2的线段上\nfunction onSegment(p1, p2, q) {\n if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) &&\n Math.min(p1[0], p2[0]) <= q[0] &&\n q[0] <= Math.max(p1[0], p2[0]) &&\n Math.min(p1[1], p2[1]) <= q[1] &&\n q[1] <= Math.max(p1[1], p2[1])) {\n return true;\n }\n return false;\n}\n// 判断点P在多边形内-射线法\nfunction isInPolygon(points, x, y) {\n var isHit = false;\n var n = points.length;\n if (n <= 2) {\n // svg 中点小于 3 个时,不显示,也无法被拾取\n return false;\n }\n for (var i = 0; i < n; i++) {\n var p1 = points[i];\n var p2 = points[(i + 1) % n];\n if (onSegment(p1, p2, [x, y])) {\n // 点在多边形一条边上\n return true;\n }\n // 前一个判断min(p1[1],p2[1]) 0 !== dcmp(p2[1] - y) > 0 &&\n dcmp(x - ((y - p1[1]) * (p1[0] - p2[0])) / (p1[1] - p2[1]) - p1[0]) < 0) {\n isHit = !isHit;\n }\n }\n return isHit;\n}\n//# sourceMappingURL=point-in-polygon.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/is-polygons-intersect.js\n\n\n\nfunction parseToLines(points) {\n var lines = [];\n var count = points.length;\n for (var i = 0; i < count - 1; i++) {\n var point = points[i];\n var next = points[i + 1];\n lines.push({\n from: {\n x: point[0],\n y: point[1]\n },\n to: {\n x: next[0],\n y: next[1]\n }\n });\n }\n if (lines.length > 1) {\n var first = points[0];\n var last = points[count - 1];\n lines.push({\n from: {\n x: last[0],\n y: last[1]\n },\n to: {\n x: first[0],\n y: first[1]\n }\n });\n }\n return lines;\n}\nfunction lineIntersectPolygon(lines, line) {\n var isIntersect = false;\n Object(esm[\"each\"])(lines, function (l) {\n if (getLineIntersect(l.from, l.to, line.from, line.to)) {\n isIntersect = true;\n return false;\n }\n });\n return isIntersect;\n}\nfunction getBBox(points) {\n var xArr = points.map(function (p) { return p[0]; });\n var yArr = points.map(function (p) { return p[1]; });\n return {\n minX: Math.min.apply(null, xArr),\n maxX: Math.max.apply(null, xArr),\n minY: Math.min.apply(null, yArr),\n maxY: Math.max.apply(null, yArr)\n };\n}\nfunction intersectBBox(box1, box2) {\n return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY);\n}\nfunction isPolygonsIntersect(points1, points2) {\n // 空数组,或者一个点返回 false\n if (points1.length < 2 || points2.length < 2) {\n return false;\n }\n var bbox1 = getBBox(points1);\n var bbox2 = getBBox(points2);\n // 判定包围盒是否相交,比判定点是否在多边形内要快的多,可以筛选掉大多数情况\n if (!intersectBBox(bbox1, bbox2)) {\n return false;\n }\n var isIn = false;\n // 判定点是否在多边形内部,一旦有一个点在另一个多边形内,则返回\n Object(esm[\"each\"])(points2, function (point) {\n if (isInPolygon(points1, point[0], point[1])) {\n isIn = true;\n return false;\n }\n });\n if (isIn) {\n return true;\n }\n // 两个多边形都需要判定\n Object(esm[\"each\"])(points1, function (point) {\n if (isInPolygon(points2, point[0], point[1])) {\n isIn = true;\n return false;\n }\n });\n if (isIn) {\n return true;\n }\n var lines1 = parseToLines(points1);\n var lines2 = parseToLines(points2);\n var isIntersect = false;\n Object(esm[\"each\"])(lines2, function (line) {\n if (lineIntersectPolygon(lines1, line)) {\n isIntersect = true;\n return false;\n }\n });\n return isIntersect;\n}\n//# sourceMappingURL=is-polygons-intersect.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/path-util/esm/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvcGF0aC11dGlsL2VzbS9wYXJzZS1wYXRoLmpzP2ViMjEiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9ub2RlX21vZHVsZXMvQGFudHYvbWF0cml4LXV0aWwvZXNtL2V4dC5qcz8yZDUwIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvbm9kZV9tb2R1bGVzL0BhbnR2L21hdHJpeC11dGlsL2VzbS9pbmRleC5qcz9kNTQzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL2NhdG11bGwtcm9tLTItYmV6aWVyLmpzPzdhMTciLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vZmlsbC1wYXRoLmpzP2MzYjYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vZmlsbC1wYXRoLWJ5LWRpZmYuanM/ZTMxMyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvcGF0aC11dGlsL2VzbS9mb3JtYXQtcGF0aC5qcz82ODExIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL3JlY3QtcGF0aC5qcz8yMjBkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL3BhcnNlLXBhdGgtc3RyaW5nLmpzPzBiYzEiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vcGF0aC0yLWFic29sdXRlLmpzP2E0YTMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vcHJvY2Vzcy9hcmMtMi1jdWJpYy5qcz9hZjIwIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL3Byb2Nlc3MvcXVhZC0yLWN1YmljLmpzPzEwNGMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vcHJvY2Vzcy9saW5lLTItY3ViaWMuanM/NjViNCIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvcGF0aC11dGlsL2VzbS9wcm9jZXNzL3NlZ21lbnQtMi1jdWJpYy5qcz80OWZlIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL3BhdGgtMi1jdXJ2ZS5qcz81NmVlIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL3BhdGgtaW50ZXJzZWN0aW9uLmpzPzFlYjYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vcGFyc2UtcGF0aC1hcnJheS5qcz9iYzY2Iiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL2dldC1hcmMtcGFyYW1zLmpzP2E1OGYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vcGF0aC0yLXNlZ21lbnRzLmpzP2NmMmUiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vZ2V0LWxpbmUtaW50ZXJzZWN0LmpzPzk1NWIiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0BhbnR2L3BhdGgtdXRpbC9lc20vcG9pbnQtaW4tcG9seWdvbi5qcz8yMjJmIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL2lzLXBvbHlnb25zLWludGVyc2VjdC5qcz9hYmRkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9AYW50di9wYXRoLXV0aWwvZXNtL2luZGV4LmpzPzJlZjEiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFxRDtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFB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LG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxzQkFBTztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFD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cmluZyB9IGZyb20gJ0BhbnR2L3V0aWwnO1xudmFyIHJlZ2V4VGFncyA9IC9bTUxIVlFUQ1NBWl0oW15NTEhWUVRDU0FaXSopL2lnO1xudmFyIHJlZ2V4RG90ID0gL1teXFxzXFwsXSsvaWc7XG5mdW5jdGlvbiBwYXJzZVBhdGgocCkge1xuICAgIHZhciBwYXRoID0gcCB8fCBbXTtcbiAgICBpZiAoaXNBcnJheShwYXRoKSkge1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICB9XG4gICAgaWYgKGlzU3RyaW5nKHBhdGgpKSB7XG4gICAgICAgIHBhdGggPSBwYXRoLm1hdGNoKHJlZ2V4VGFncyk7XG4gICAgICAgIGVhY2gocGF0aCwgZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBpdGVtID0gaXRlbS5tYXRjaChyZWdleERvdCk7XG4gICAgICAgICAgICBpZiAoaXRlbVswXS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhZyA9IGl0ZW1bMF0uY2hhckF0KDApO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBpdGVtLnNwbGljZSgxLCAwLCBpdGVtWzBdLnN1YnN0cigxKSk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGl0ZW1bMF0gPSB0YWc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBlYWNoKGl0ZW0sIGZ1bmN0aW9uIChzdWIsIGkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzTmFOKHN1YikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICBpdGVtW2ldID0gK3N1YjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIHBhdGhbaW5kZXhdID0gaXRlbTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH1cbn1cbmV4cG9ydCBkZWZhdWx0IHBhcnNlUGF0aDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhcnNlLXBhdGguanMubWFwIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24g5omp5bGV5pa55rOV77yM5o+Q5L6bIGdsLW1hdHJpeCDkuLrmj5DkvpvnmoTmlrnms5VcbiAqICovXG5pbXBvcnQgeyBtYXQzLCB2ZWMyIH0gZnJvbSAnZ2wtbWF0cml4JztcbmV4cG9ydCBmdW5jdGlvbiBsZWZ0VHJhbnNsYXRlKG91dCwgYSwgdikge1xuICAgIHZhciB0cmFuc01hdCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgICBtYXQzLmZyb21UcmFuc2xhdGlvbih0cmFuc01hdCwgdik7XG4gICAgcmV0dXJuIG1hdDMubXVsdGlwbHkob3V0LCB0cmFuc01hdCwgYSk7XG59XG5leHBvcnQgZnVuY3Rpb24gbGVmdFJvdGF0ZShvdXQsIGEsIHJhZCkge1xuICAgIHZhciByb3RhdGVNYXQgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgbWF0My5mcm9tUm90YXRpb24ocm90YXRlTWF0LCByYWQpO1xuICAgIHJldHVybiBtYXQzLm11bHRpcGx5KG91dCwgcm90YXRlTWF0LCBhKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBsZWZ0U2NhbGUob3V0LCBhLCB2KSB7XG4gICAgdmFyIHNjYWxlTWF0ID0gWzAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDBdO1xuICAgIG1hdDMuZnJvbVNjYWxpbmcoc2NhbGVNYXQsIHYpO1xuICAgIHJldHVybiBtYXQzLm11bHRpcGx5KG91dCwgc2NhbGVNYXQsIGEpO1xufVxuZnVuY3Rpb24gbGVmdE11bHRpcGx5KG91dCwgYSwgYTEpIHtcbiAgICByZXR1cm4gbWF0My5tdWx0aXBseShvdXQsIGExLCBhKTtcbn1cbi8qKlxuICog5qC55o2uIGFjdGlvbnMg5p2l5YGaIHRyYW5zZm9ybVxuICogQHBhcmFtIG1cbiAqIEBwYXJhbSBhY3Rpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm0obSwgYWN0aW9ucykge1xuICAgIHZhciBtYXRyaXggPSBtID8gW10uY29uY2F0KG0pIDogWzEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDFdO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhY3Rpb25zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBhY3Rpb24gPSBhY3Rpb25zW2ldO1xuICAgICAgICBzd2l0Y2ggKGFjdGlvblswXSkge1xuICAgICAgICAgICAgY2FzZSAndCc6XG4gICAgICAgICAgICAgICAgbGVmdFRyYW5zbGF0ZShtYXRyaXgsIG1hdHJpeCwgW2FjdGlvblsxXSwgYWN0aW9uWzJdXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdzJzpcbiAgICAgICAgICAgICAgICBsZWZ0U2NhbGUobWF0cml4LCBtYXRyaXgsIFthY3Rpb25bMV0sIGFjdGlvblsyXV0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncic6XG4gICAgICAgICAgICAgICAgbGVmdFJvdGF0ZShtYXRyaXgsIG1hdHJpeCwgYWN0aW9uWzFdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ20nOlxuICAgICAgICAgICAgICAgIGxlZnRNdWx0aXBseShtYXRyaXgsIG1hdHJpeCwgYWN0aW9uWzFdKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hdHJpeDtcbn1cbi8qKlxuICog5ZCR6YePIHYxIOWIsCDlkJHph48gdjIg5aS56KeS55qE5pa55ZCRXG4gKiBAcGFyYW0gIHtBcnJheX0gdjEg5ZCR6YePXG4gKiBAcGFyYW0gIHtBcnJheX0gdjIg5ZCR6YePXG4gKiBAcmV0dXJuIHtCb29sZWFufSA+PSAwIOmhuuaXtumSiCA8IDAg6YCG5pe26ZKIXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXJlY3Rpb24odjEsIHYyKSB7XG4gICAgcmV0dXJuIHYxWzBdICogdjJbMV0gLSB2MlswXSAqIHYxWzFdO1xufVxuLyoqXG4gKiDkuoznu7TlkJHph48gdjEg5YiwIHYyIOeahOWkueinklxuICogQHBhcmFtIHYxXG4gKiBAcGFyYW0gdjJcbiAqIEBwYXJhbSBkaXJlY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuZ2xlVG8odjEsIHYyLCBkaXJlY3QpIHtcbiAgICB2YXIgYW5nID0gdmVjMi5hbmdsZSh2MSwgdjIpO1xuICAgIHZhciBhbmdsZUxhcmdlVGhhblBJID0gZGlyZWN0aW9uKHYxLCB2MikgPj0gMDtcbiAgICBpZiAoZGlyZWN0KSB7XG4gICAgICAgIGlmIChhbmdsZUxhcmdlVGhhblBJKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5QSSAqIDIgLSBhbmc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFuZztcbiAgICB9XG4gICAgaWYgKGFuZ2xlTGFyZ2VUaGFuUEkpIHtcbiAgICAgICAgcmV0dXJuIGFuZztcbiAgICB9XG4gICAgcmV0dXJuIE1hdGguUEkgKiAyIC0gYW5nO1xufVxuLyoqXG4gKiDorqHnrpfkuoznu7TlkJHph4/nmoTlnoLnm7TlkJHph49cbiAqIEBwYXJhbSBvdXRcbiAqIEBwYXJhbSB2XG4gKiBAcGFyYW0gZmxhZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVydGljYWwob3V0LCB2LCBmbGFnKSB7XG4gICAgaWYgKGZsYWcpIHtcbiAgICAgICAgb3V0WzBdID0gdlsxXTtcbiAgICAgICAgb3V0WzFdID0gLTEgKiB2WzBdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgb3V0WzBdID0gLTEgKiB2WzFdO1xuICAgICAgICBvdXRbMV0gPSB2WzBdO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXh0LmpzLm1hcCIsImltcG9ydCB7IG1hdDMsIHZlYzIsIHZlYzMgfSBmcm9tICdnbC1tYXRyaXgnO1xuaW1wb3J0ICogYXMgZXh0IGZyb20gJy4vZXh0JztcbmV4cG9ydCB7IG1hdDMsIHZlYzIsIHZlYzMsIGV4dCB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgdmVjMiB9IGZyb20gJ0BhbnR2L21hdHJpeC11dGlsJztcbmZ1bmN0aW9uIHNtb290aEJlemllcihwb2ludHMsIHNtb290aCwgaXNMb29wLCBjb25zdHJhaW50KSB7XG4gICAgdmFyIGNwcyA9IFtdO1xuICAgIHZhciBoYXNDb25zdHJhaW50ID0gISFjb25zdHJhaW50O1xuICAgIHZhciBwcmV2UG9pbnQ7XG4gICAgdmFyIG5leHRQb2ludDtcbiAgICB2YXIgbWluO1xuICAgIHZhciBtYXg7XG4gICAgdmFyIG5leHRDcDA7XG4gICAgdmFyIGNwMTtcbiAgICB2YXIgY3AwO1xuICAgIGlmIChoYXNDb25zdHJhaW50KSB7XG4gICAgICAgIG1pbiA9IGNvbnN0cmFpbnRbMF0sIG1heCA9IGNvbnN0cmFpbnRbMV07XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gcG9pbnRzLmxlbmd0aDsgaSA8IGw7IGkgKz0gMSkge1xuICAgICAgICAgICAgdmFyIHBvaW50ID0gcG9pbnRzW2ldO1xuICAgICAgICAgICAgbWluID0gdmVjMi5taW4oWzAsIDBdLCBtaW4sIHBvaW50KTtcbiAgICAgICAgICAgIG1heCA9IHZlYzIubWF4KFswLCAwXSwgbWF4LCBwb2ludCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICB2YXIgcG9pbnQgPSBwb2ludHNbaV07XG4gICAgICAgIGlmIChpID09PSAwICYmICFpc0xvb3ApIHtcbiAgICAgICAgICAgIGNwMCA9IHBvaW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGkgPT09IGxlbiAtIDEgJiYgIWlzTG9vcCkge1xuICAgICAgICAgICAgY3AxID0gcG9pbnQ7XG4gICAgICAgICAgICBjcHMucHVzaChjcDApO1xuICAgICAgICAgICAgY3BzLnB1c2goY3AxKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBwcmV2SWR4ID0gW2kgPyBpIC0gMSA6IGxlbiAtIDEsIGkgLSAxXVtpc0xvb3AgPyAwIDogMV07XG4gICAgICAgICAgICBwcmV2UG9pbnQgPSBwb2ludHNbcHJldklkeF07XG4gICAgICAgICAgICBuZXh0UG9pbnQgPSBwb2ludHNbaXNMb29wID8gKGkgKyAxKSAlIGxlbiA6IGkgKyAxXTtcbiAgICAgICAgICAgIHZhciB2ID0gWzAsIDBdO1xuICAgICAgICAgICAgdiA9IHZlYzIuc3ViKHYsIG5leHRQb2ludCwgcHJldlBvaW50KTtcbiAgICAgICAgICAgIHYgPSB2ZWMyLnNjYWxlKHYsIHYsIHNtb290aCk7XG4gICAgICAgICAgICB2YXIgZDAgPSB2ZWMyLmRpc3RhbmNlKHBvaW50LCBwcmV2UG9pbnQpO1xuICAgICAgICAgICAgdmFyIGQxID0gdmVjMi5kaXN0YW5jZShwb2ludCwgbmV4dFBvaW50KTtcbiAgICAgICAgICAgIHZhciBzdW0gPSBkMCArIGQxO1xuICAgICAgICAgICAgaWYgKHN1bSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGQwIC89IHN1bTtcbiAgICAgICAgICAgICAgICBkMSAvPSBzdW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdjEgPSB2ZWMyLnNjYWxlKFswLCAwXSwgdiwgLWQwKTtcbiAgICAgICAgICAgIHZhciB2MiA9IHZlYzIuc2NhbGUoWzAsIDBdLCB2LCBkMSk7XG4gICAgICAgICAgICBjcDEgPSB2ZWMyLmFkZChbMCwgMF0sIHBvaW50LCB2MSk7XG4gICAgICAgICAgICBuZXh0Q3AwID0gdmVjMi5hZGQoWzAsIDBdLCBwb2ludCwgdjIpO1xuICAgICAgICAgICAgLy8g5LiL5LiA5Liq5o6n5Yi254K55b+F6aG75Zyo6L+Z5Liq54K55ZKM5LiL5LiA5Liq54K55LmL6Ze0XG4gICAgICAgICAgICBuZXh0Q3AwID0gdmVjMi5taW4oWzAsIDBdLCBuZXh0Q3AwLCB2ZWMyLm1heChbMCwgMF0sIG5leHRQb2ludCwgcG9pbnQpKTtcbiAgICAgICAgICAgIG5leHRDcDAgPSB2ZWMyLm1heChbMCwgMF0sIG5leHRDcDAsIHZlYzIubWluKFswLCAwXSwgbmV4dFBvaW50LCBwb2ludCkpO1xuICAgICAgICAgICAgLy8g6YeN5paw6K6h566XIGNwMSDnmoTlgLxcbiAgICAgICAgICAgIHYxID0gdmVjMi5zdWIoWzAsIDBdLCBuZXh0Q3AwLCBwb2ludCk7XG4gICAgICAgICAgICB2MSA9IHZlYzIuc2NhbGUoWzAsIDBdLCB2MSwgLWQwIC8gZDEpO1xuICAgICAgICAgICAgY3AxID0gdmVjMi5hZGQoWzAsIDBdLCBwb2ludCwgdjEpO1xuICAgICAgICAgICAgLy8g5LiK5LiA5Liq5o6n5Yi254K55b+F6aG76KaB5Zyo5LiK5LiA5Liq54K55ZKM6L+Z5LiA5Liq54K55LmL6Ze0XG4gICAgICAgICAgICBjcDEgPSB2ZWMyLm1pbihbMCwgMF0sIGNwMSwgdmVjMi5tYXgoWzAsIDBdLCBwcmV2UG9pbnQsIHBvaW50KSk7XG4gICAgICAgICAgICBjcDEgPSB2ZWMyLm1heChbMCwgMF0sIGNwMSwgdmVjMi5taW4oWzAsIDBdLCBwcmV2UG9pbnQsIHBvaW50KSk7XG4gICAgICAgICAgICAvLyDph43mlrDorqHnrpcgbmV4dENwMCDnmoTlgLxcbiAgICAgICAgICAgIHYyID0gdmVjMi5zdWIoWzAsIDBdLCBwb2ludCwgY3AxKTtcbiAgICAgICAgICAgIHYyID0gdmVjMi5zY2FsZShbMCwgMF0sIHYyLCBkMSAvIGQwKTtcbiAgICAgICAgICAgIG5leHRDcDAgPSB2ZWMyLmFkZChbMCwgMF0sIHBvaW50LCB2Mik7XG4gICAgICAgICAgICBpZiAoaGFzQ29uc3RyYWludCkge1xuICAgICAgICAgICAgICAgIGNwMSA9IHZlYzIubWF4KFswLCAwXSwgY3AxLCBtaW4pO1xuICAgICAgICAgICAgICAgIGNwMSA9IHZlYzIubWluKFswLCAwXSwgY3AxLCBtYXgpO1xuICAgICAgICAgICAgICAgIG5leHRDcDAgPSB2ZWMyLm1heChbMCwgMF0sIG5leHRDcDAsIG1pbik7XG4gICAgICAgICAgICAgICAgbmV4dENwMCA9IHZlYzIubWluKFswLCAwXSwgbmV4dENwMCwgbWF4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNwcy5wdXNoKGNwMCk7XG4gICAgICAgICAgICBjcHMucHVzaChjcDEpO1xuICAgICAgICAgICAgY3AwID0gbmV4dENwMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNMb29wKSB7XG4gICAgICAgIGNwcy5wdXNoKGNwcy5zaGlmdCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNwcztcbn1cbi8qKlxuICogY3JlYXRlIGJlemllciBzcGxpbmUgZnJvbSBjYXRtdWxsIHJvbSBzcGxpbmVcbiAqIEBwYXJhbSB7QXJyYXl9IGNycCBDYXRtdWxsIFJvbSBQb2ludHNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0geiBTcGxpbmUgaXMgbG9vcFxuICogQHBhcmFtIHtBcnJheX0gY29uc3RyYWludCBDb25zdHJhaW50XG4gKi9cbmZ1bmN0aW9uIGNhdG11bGxSb20yQmV6aWVyKGNycCwgeiwgY29uc3RyYWludCkge1xuICAgIGlmICh6ID09PSB2b2lkIDApIHsgeiA9IGZhbHNlOyB9XG4gICAgaWYgKGNvbnN0cmFpbnQgPT09IHZvaWQgMCkgeyBjb25zdHJhaW50ID0gW1xuICAgICAgICBbMCwgMF0sXG4gICAgICAgIFsxLCAxXSxcbiAgICBdOyB9XG4gICAgdmFyIGlzTG9vcCA9ICEhejtcbiAgICB2YXIgcG9pbnRMaXN0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjcnAubGVuZ3RoOyBpIDwgbDsgaSArPSAyKSB7XG4gICAgICAgIHBvaW50TGlzdC5wdXNoKFtjcnBbaV0sIGNycFtpICsgMV1dKTtcbiAgICB9XG4gICAgdmFyIGNvbnRyb2xQb2ludExpc3QgPSBzbW9vdGhCZXppZXIocG9pbnRMaXN0LCAwLjQsIGlzTG9vcCwgY29uc3RyYWludCk7XG4gICAgdmFyIGxlbiA9IHBvaW50TGlzdC5sZW5ndGg7XG4gICAgdmFyIGQxID0gW107XG4gICAgdmFyIGNwMTtcbiAgICB2YXIgY3AyO1xuICAgIHZhciBwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuIC0gMTsgaSArPSAxKSB7XG4gICAgICAgIGNwMSA9IGNvbnRyb2xQb2ludExpc3RbaSAqIDJdO1xuICAgICAgICBjcDIgPSBjb250cm9sUG9pbnRMaXN0W2kgKiAyICsgMV07XG4gICAgICAgIHAgPSBwb2ludExpc3RbaSArIDFdO1xuICAgICAgICBkMS5wdXNoKFsnQycsIGNwMVswXSwgY3AxWzFdLCBjcDJbMF0sIGNwMlsxXSwgcFswXSwgcFsxXV0pO1xuICAgIH1cbiAgICBpZiAoaXNMb29wKSB7XG4gICAgICAgIGNwMSA9IGNvbnRyb2xQb2ludExpc3RbbGVuXTtcbiAgICAgICAgY3AyID0gY29udHJvbFBvaW50TGlzdFtsZW4gKyAxXTtcbiAgICAgICAgcCA9IHBvaW50TGlzdFswXTtcbiAgICAgICAgZDEucHVzaChbJ0MnLCBjcDFbMF0sIGNwMVsxXSwgY3AyWzBdLCBjcDJbMV0sIHBbMF0sIHBbMV1dKTtcbiAgICB9XG4gICAgcmV0dXJuIGQxO1xufVxuZXhwb3J0IGRlZmF1bHQgY2F0bXVsbFJvbTJCZXppZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jYXRtdWxsLXJvbS0yLWJlemllci5qcy5tYXAiLCJmdW5jdGlvbiBkZWNhc3RlbGphdShwb2ludHMsIHQpIHtcbiAgICB2YXIgbGVmdCA9IFtdO1xuICAgIHZhciByaWdodCA9IFtdO1xuICAgIGZ1bmN0aW9uIHJlY3Vyc2UocG9pbnRzLCB0KSB7XG4gICAgICAgIGlmIChwb2ludHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBsZWZ0LnB1c2gocG9pbnRzWzBdKTtcbiAgICAgICAgICAgIHJpZ2h0LnB1c2gocG9pbnRzWzBdKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBtaWRkbGVQb2ludHMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQucHVzaChwb2ludHNbMF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gcG9pbnRzLmxlbmd0aCAtIDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHQucHVzaChwb2ludHNbaSArIDFdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbWlkZGxlUG9pbnRzW2ldID0gWygxIC0gdCkgKiBwb2ludHNbaV1bMF0gKyB0ICogcG9pbnRzW2kgKyAxXVswXSwgKDEgLSB0KSAqIHBvaW50c1tpXVsxXSArIHQgKiBwb2ludHNbaSArIDFdWzFdXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlY3Vyc2UobWlkZGxlUG9pbnRzLCB0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAocG9pbnRzLmxlbmd0aCkge1xuICAgICAgICByZWN1cnNlKHBvaW50cywgdCk7XG4gICAgfVxuICAgIHJldHVybiB7IGxlZnQ6IGxlZnQsIHJpZ2h0OiByaWdodC5yZXZlcnNlKCkgfTtcbn1cbmZ1bmN0aW9uIHNwbGl0Q3VydmUoc3RhcnQsIGVuZCwgY291bnQpIHtcbiAgICB2YXIgcG9pbnRzID0gW1tzdGFydFsxXSwgc3RhcnRbMl1dXTtcbiAgICBjb3VudCA9IGNvdW50IHx8IDI7XG4gICAgdmFyIHNlZ21lbnRzID0gW107XG4gICAgaWYgKGVuZFswXSA9PT0gJ0EnKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKGVuZFs2XSk7XG4gICAgICAgIHBvaW50cy5wdXNoKGVuZFs3XSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGVuZFswXSA9PT0gJ0MnKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbMV0sIGVuZFsyXV0pO1xuICAgICAgICBwb2ludHMucHVzaChbZW5kWzNdLCBlbmRbNF1dKTtcbiAgICAgICAgcG9pbnRzLnB1c2goW2VuZFs1XSwgZW5kWzZdXSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGVuZFswXSA9PT0gJ1MnIHx8IGVuZFswXSA9PT0gJ1EnKSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbMV0sIGVuZFsyXV0pO1xuICAgICAgICBwb2ludHMucHVzaChbZW5kWzNdLCBlbmRbNF1dKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHBvaW50cy5wdXNoKFtlbmRbMV0sIGVuZFsyXV0pO1xuICAgIH1cbiAgICB2YXIgbGVmdFNlZ21lbnRzID0gcG9pbnRzO1xuICAgIHZhciB0ID0gMSAvIGNvdW50O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQgLSAxOyBpKyspIHtcbiAgICAgICAgdmFyIHJ0ID0gdCAvICgxIC0gdCAqIGkpO1xuICAgICAgICB2YXIgc3BsaXQgPSBkZWNhc3RlbGphdShsZWZ0U2VnbWVudHMsIHJ0KTtcbiAgICAgICAgc2VnbWVudHMucHVzaChzcGxpdC5sZWZ0KTtcbiAgICAgICAgbGVmdFNlZ21lbnRzID0gc3BsaXQucmlnaHQ7XG4gICAgfVxuICAgIHNlZ21lbnRzLnB1c2gobGVmdFNlZ21lbnRzKTtcbiAgICB2YXIgcmVzdWx0ID0gc2VnbWVudHMubWFwKGZ1bmN0aW9uIChzZWdtZW50KSB7XG4gICAgICAgIHZhciBjbWQgPSBbXTtcbiAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSA0KSB7XG4gICAgICAgICAgICBjbWQucHVzaCgnQycpO1xuICAgICAgICAgICAgY21kID0gY21kLmNvbmNhdChzZWdtZW50WzJdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICAgICAgY21kLnB1c2goJ1EnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNtZCA9IGNtZC5jb25jYXQoc2VnbWVudFsxXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjbWQucHVzaCgnTCcpO1xuICAgICAgICB9XG4gICAgICAgIGNtZCA9IGNtZC5jb25jYXQoc2VnbWVudFtzZWdtZW50Lmxlbmd0aCAtIDFdKTtcbiAgICAgICAgcmV0dXJuIGNtZDtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gc3BsaXRTZWdtZW50KHN0YXJ0LCBlbmQsIGNvdW50KSB7XG4gICAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgICAgIHJldHVybiBbW10uY29uY2F0KHN0YXJ0KV07XG4gICAgfVxuICAgIHZhciBzZWdtZW50cyA9IFtdO1xuICAgIGlmIChlbmRbMF0gPT09ICdMJyB8fCBlbmRbMF0gPT09ICdDJyB8fCBlbmRbMF0gPT09ICdRJykge1xuICAgICAgICBzZWdtZW50cyA9IHNlZ21lbnRzLmNvbmNhdChzcGxpdEN1cnZlKHN0YXJ0LCBlbmQsIGNvdW50KSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgdGVtcCA9IFtdLmNvbmNhdChzdGFydCk7XG4gICAgICAgIGlmICh0ZW1wWzBdID09PSAnTScpIHtcbiAgICAgICAgICAgIHRlbXBbMF0gPSAnTCc7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPD0gY291bnQgLSAxOyBpKyspIHtcbiAgICAgICAgICAgIHNlZ21lbnRzLnB1c2godGVtcCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNlZ21lbnRzO1xufVxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZmlsbFBhdGgoc291cmNlLCB0YXJnZXQpIHtcbiAgICBpZiAoc291cmNlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gc291cmNlO1xuICAgIH1cbiAgICB2YXIgc291cmNlTGVuID0gc291cmNlLmxlbmd0aCAtIDE7XG4gICAgdmFyIHRhcmdldExlbiA9IHRhcmdldC5sZW5ndGggLSAxO1xuICAgIHZhciByYXRpbyA9IHNvdXJjZUxlbiAvIHRhcmdldExlbjtcbiAgICB2YXIgc2VnbWVudHNUb0ZpbGwgPSBbXTtcbiAgICBpZiAoc291cmNlLmxlbmd0aCA9PT0gMSAmJiBzb3VyY2VbMF1bMF0gPT09ICdNJykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhcmdldExlbiAtIHNvdXJjZUxlbjsgaSsrKSB7XG4gICAgICAgICAgICBzb3VyY2UucHVzaChzb3VyY2VbMF0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFyZ2V0TGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGluZGV4ID0gTWF0aC5mbG9vcihyYXRpbyAqIGkpO1xuICAgICAgICBzZWdtZW50c1RvRmlsbFtpbmRleF0gPSAoc2VnbWVudHNUb0ZpbGxbaW5kZXhdIHx8IDApICsgMTtcbiAgICB9XG4gICAgdmFyIGZpbGxlZCA9IHNlZ21lbnRzVG9GaWxsLnJlZHVjZShmdW5jdGlvbiAoZmlsbGVkLCBjb3VudCwgaSkge1xuICAgICAgICBpZiAoaSA9PT0gc291cmNlTGVuKSB7XG4gICAgICAgICAgICByZXR1cm4gZmlsbGVkLmNvbmNhdChzb3VyY2Vbc291cmNlTGVuXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbGxlZC5jb25jYXQoc3BsaXRTZWdtZW50KHNvdXJjZVtpXSwgc291cmNlW2kgKyAxXSwgY291bnQpKTtcbiAgICB9LCBbXSk7XG4gICAgZmlsbGVkLnVuc2hpZnQoc291cmNlWzBdKTtcbiAgICBpZiAodGFyZ2V0W3RhcmdldExlbl0gPT09ICdaJyB8fCB0YXJnZXRbdGFyZ2V0TGVuXSA9PT0gJ3onKSB7XG4gICAgICAgIGZpbGxlZC5wdXNoKCdaJyk7XG4gICAgfVxuICAgIHJldHVybiBmaWxsZWQ7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maWxsLXBhdGguanMubWFwIiwiaW1wb3J0IHsgaXNFcXVhbCB9IGZyb20gJ0BhbnR2L3V0aWwnO1xuZnVuY3Rpb24gZ2V0TWluRGlmZihkZWwsIGFkZCwgbW9kaWZ5KSB7XG4gICAgdmFyIHR5cGUgPSBudWxsO1xuICAgIHZhciBtaW4gPSBtb2RpZnk7XG4gICAgaWYgKGFkZCA8IG1pbikge1xuICAgICAgICBtaW4gPSBhZGQ7XG4gICAgICAgIHR5cGUgPSAnYWRkJztcbiAgICB9XG4gICAgaWYgKGRlbCA8IG1pbikge1xuICAgICAgICBtaW4gPSBkZWw7XG4gICAgICAgIHR5cGUgPSAnZGVsJztcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgbWluOiBtaW4sXG4gICAgfTtcbn1cbi8qXG4gKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MZXZlbnNodGVpbl9kaXN0YW5jZVxuICog6K6h566X5Lik5p2hcGF0aOeahOe8lui+kei3neemu1xuICovXG52YXIgbGV2ZW5zaHRlaW5EaXN0YW5jZSA9IGZ1bmN0aW9uIChzb3VyY2UsIHRhcmdldCkge1xuICAgIHZhciBzb3VyY2VMZW4gPSBzb3VyY2UubGVuZ3RoO1xuICAgIHZhciB0YXJnZXRMZW4gPSB0YXJnZXQubGVuZ3RoO1xuICAgIHZhciBzb3VyY2VTZWdtZW50LCB0YXJnZXRTZWdtZW50O1xuICAgIHZhciB0ZW1wID0gMDtcbiAgICBpZiAoc291cmNlTGVuID09PSAwIHx8IHRhcmdldExlbiA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdmFyIGRpc3QgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8PSBzb3VyY2VMZW47IGkrKykge1xuICAgICAgICBkaXN0W2ldID0gW107XG4gICAgICAgIGRpc3RbaV1bMF0gPSB7IG1pbjogaSB9O1xuICAgIH1cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSB0YXJnZXRMZW47IGorKykge1xuICAgICAgICBkaXN0WzBdW2pdID0geyBtaW46IGogfTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gc291cmNlTGVuOyBpKyspIHtcbiAgICAgICAgc291cmNlU2VnbWVudCA9IHNvdXJjZVtpIC0gMV07XG4gICAgICAgIGZvciAodmFyIGogPSAxOyBqIDw9IHRhcmdldExlbjsgaisrKSB7XG4gICAgICAgICAgICB0YXJnZXRTZWdtZW50ID0gdGFyZ2V0W2ogLSAxXTtcbiAgICAgICAgICAgIGlmIChpc0VxdWFsKHNvdXJjZVNlZ21lbnQsIHRhcmdldFNlZ21lbnQpKSB7XG4gICAgICAgICAgICAgICAgdGVtcCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ZW1wID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkZWwgPSBkaXN0W2kgLSAxXVtqXS5taW4gKyAxO1xuICAgICAgICAgICAgdmFyIGFkZCA9IGRpc3RbaV1baiAtIDFdLm1pbiArIDE7XG4gICAgICAgICAgICB2YXIgbW9kaWZ5ID0gZGlzdFtpIC0gMV1baiAtIDFdLm1pbiArIHRlbXA7XG4gICAgICAgICAgICBkaXN0W2ldW2pdID0gZ2V0TWluRGlmZihkZWwsIGFkZCwgbW9kaWZ5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGlzdDtcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBmaWxsUGF0aEJ5RGlmZihzb3VyY2UsIHRhcmdldCkge1xuICAgIHZhciBkaWZmTWF0cml4ID0gbGV2ZW5zaHRlaW5EaXN0YW5jZShzb3VyY2UsIHRhcmdldCk7XG4gICAgdmFyIHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGg7XG4gICAgdmFyIHRhcmdldExlbiA9IHRhcmdldC5sZW5ndGg7XG4gICAgdmFyIGNoYW5nZXMgPSBbXTtcbiAgICB2YXIgaW5kZXggPSAxO1xuICAgIHZhciBtaW5Qb3MgPSAxO1xuICAgIC8vIOWmguaenHNvdXJjZeWSjHRhcmdldOS4jeaYr+WujOWFqOS4jeebuOetiVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBpZiAoZGlmZk1hdHJpeFtzb3VyY2VMZW5dW3RhcmdldExlbl0gIT09IHNvdXJjZUxlbikge1xuICAgICAgICAvLyDojrflj5bku45zb3VyY2XliLB0YXJnZXTmiYDpnIDmlLnliqhcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gc291cmNlTGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBtaW4gPSBkaWZmTWF0cml4W2ldW2ldLm1pbjtcbiAgICAgICAgICAgIG1pblBvcyA9IGk7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gaW5kZXg7IGogPD0gdGFyZ2V0TGVuOyBqKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoZGlmZk1hdHJpeFtpXVtqXS5taW4gPCBtaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgbWluID0gZGlmZk1hdHJpeFtpXVtqXS5taW47XG4gICAgICAgICAgICAgICAgICAgIG1pblBvcyA9IGo7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kZXggPSBtaW5Qb3M7XG4gICAgICAgICAgICBpZiAoZGlmZk1hdHJpeFtpXVtpbmRleF0udHlwZSkge1xuICAgICAgICAgICAgICAgIGNoYW5nZXMucHVzaCh7IGluZGV4OiBpIC0gMSwgdHlwZTogZGlmZk1hdHJpeFtpXVtpbmRleF0udHlwZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyDlr7lzb3VyY2Xov5vooYzlop7liKBwYXRoXG4gICAgICAgIGZvciAodmFyIGkgPSBjaGFuZ2VzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBpbmRleCA9IGNoYW5nZXNbaV0uaW5kZXg7XG4gICAgICAgICAgICBpZiAoY2hhbmdlc1tpXS50eXBlID09PSAnYWRkJykge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3BsaWNlKGluZGV4LCAwLCBbXS5jb25jYXQoc291cmNlW2luZGV4XSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIHNvdXJjZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHNvdXJjZeWwvumDqOihpem9kFxuICAgIHNvdXJjZUxlbiA9IHNvdXJjZS5sZW5ndGg7XG4gICAgaWYgKHNvdXJjZUxlbiA8IHRhcmdldExlbikge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8ICh0YXJnZXRMZW4gLSBzb3VyY2VMZW4pOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChzb3VyY2Vbc291cmNlTGVuIC0gMV1bMF0gPT09ICd6JyB8fCBzb3VyY2Vbc291cmNlTGVuIC0gMV1bMF0gPT09ICdaJykge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3BsaWNlKHNvdXJjZUxlbiAtIDIsIDAsIHNvdXJjZVtzb3VyY2VMZW4gLSAyXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgc291cmNlLnB1c2goc291cmNlW3NvdXJjZUxlbiAtIDFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc291cmNlO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsbC1wYXRoLWJ5LWRpZmYuanMubWFwIiwiLypcbiAqIOaKveWPlnBhdGhTZWdtZW505Lit55qE5YWz6ZSu54K5XG4gKiBNLEwsQSxRLEgsVuS4gOS4querr+eCuVxuICogUSwgU+aKveWPluS4gOS4querr+eCue+8jOS4gOS4quaOp+WItueCuVxuICogQ+aKveWPluS4gOS4querr+eCue+8jOS4pOS4quaOp+WItueCuVxuICovXG5mdW5jdGlvbiBfZ2V0U2VnbWVudFBvaW50cyhzZWdtZW50KSB7XG4gICAgdmFyIHBvaW50cyA9IFtdO1xuICAgIHN3aXRjaCAoc2VnbWVudFswXSkge1xuICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzFdLCBzZWdtZW50WzJdXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbNl0sIHNlZ21lbnRbN11dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdRJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzNdLCBzZWdtZW50WzRdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbMV0sIHNlZ21lbnRbMl1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdDJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzVdLCBzZWdtZW50WzZdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbM10sIHNlZ21lbnRbNF1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzNdLCBzZWdtZW50WzRdXSk7XG4gICAgICAgICAgICBwb2ludHMucHVzaChbc2VnbWVudFsxXSwgc2VnbWVudFsyXV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICAgICAgcG9pbnRzLnB1c2goW3NlZ21lbnRbMV0sIHNlZ21lbnRbMV1dKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgIHBvaW50cy5wdXNoKFtzZWdtZW50WzFdLCBzZWdtZW50WzFdXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50cztcbn1cbi8vIOWwhuS4pOS4queCueWdh+WIhuaIkGNvdW505Liq54K5XG5mdW5jdGlvbiBfc3BsaXRQb2ludHMocG9pbnRzLCBmb3JtZXIsIGNvdW50KSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdLmNvbmNhdChwb2ludHMpO1xuICAgIHZhciBpbmRleDtcbiAgICB2YXIgdCA9IDEgLyAoY291bnQgKyAxKTtcbiAgICB2YXIgZm9ybWVyRW5kID0gX2dldFNlZ21lbnRQb2ludHMoZm9ybWVyKVswXTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8PSBjb3VudDsgaSsrKSB7XG4gICAgICAgIHQgKj0gaTtcbiAgICAgICAgaW5kZXggPSBNYXRoLmZsb29yKHBvaW50cy5sZW5ndGggKiB0KTtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICByZXN1bHQudW5zaGlmdChbZm9ybWVyRW5kWzBdICogdCArIHBvaW50c1tpbmRleF1bMF0gKiAoMSAtIHQpLCBmb3JtZXJFbmRbMV0gKiB0ICsgcG9pbnRzW2luZGV4XVsxXSAqICgxIC0gdCldKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdC5zcGxpY2UoaW5kZXgsIDAsIFtmb3JtZXJFbmRbMF0gKiB0ICsgcG9pbnRzW2luZGV4XVswXSAqICgxIC0gdCksIGZvcm1lckVuZFsxXSAqIHQgKyBwb2ludHNbaW5kZXhdWzFdICogKDEgLSB0KV0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBmb3JtYXRQYXRoKGZyb21QYXRoLCB0b1BhdGgpIHtcbiAgICBpZiAoZnJvbVBhdGgubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgcmV0dXJuIGZyb21QYXRoO1xuICAgIH1cbiAgICB2YXIgcG9pbnRzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdG9QYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChmcm9tUGF0aFtpXVswXSAhPT0gdG9QYXRoW2ldWzBdKSB7XG4gICAgICAgICAgICAvLyDojrflj5Zmcm9tUGF0aOeahHBhdGhTZWdtZW5055qE56uv54K577yM5qC55o2udG9QYXRo55qE5oyH5Luk5a+55YW25pS56YCgXG4gICAgICAgICAgICBwb2ludHMgPSBfZ2V0U2VnbWVudFBvaW50cyhmcm9tUGF0aFtpXSk7XG4gICAgICAgICAgICBzd2l0Y2ggKHRvUGF0aFtpXVswXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ00nOlxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnTSddLmNvbmNhdChwb2ludHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdMJzpcbiAgICAgICAgICAgICAgICAgICAgZnJvbVBhdGhbaV0gPSBbJ0wnXS5jb25jYXQocG9pbnRzWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gW10uY29uY2F0KHRvUGF0aFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldWzZdID0gcG9pbnRzWzBdWzBdO1xuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXVs3XSA9IHBvaW50c1swXVsxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRzID0gX3NwbGl0UG9pbnRzKHBvaW50cywgZnJvbVBhdGhbaSAtIDFdLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gWydRJ10uY29uY2F0KHBvaW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFyciwgaSkgeyByZXR1cm4gYXJyLmNvbmNhdChpKTsgfSwgW10pKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnVCc6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gWydUJ10uY29uY2F0KHBvaW50c1swXSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ0MnOlxuICAgICAgICAgICAgICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyA9IF9zcGxpdFBvaW50cyhwb2ludHMsIGZyb21QYXRoW2kgLSAxXSwgMik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IHRvUGF0aFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnQyddLmNvbmNhdChwb2ludHMucmVkdWNlKGZ1bmN0aW9uIChhcnIsIGkpIHsgcmV0dXJuIGFyci5jb25jYXQoaSk7IH0sIFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1MnOlxuICAgICAgICAgICAgICAgICAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyA9IF9zcGxpdFBvaW50cyhwb2ludHMsIGZyb21QYXRoW2kgLSAxXSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IHRvUGF0aFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmcm9tUGF0aFtpXSA9IFsnUyddLmNvbmNhdChwb2ludHMucmVkdWNlKGZ1bmN0aW9uIChhcnIsIGkpIHsgcmV0dXJuIGFyci5jb25jYXQoaSk7IH0sIFtdKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGZyb21QYXRoW2ldID0gdG9QYXRoW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmcm9tUGF0aDtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZvcm1hdC1wYXRoLmpzLm1hcCIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHJlY3RQYXRoKHgsIHksIHcsIGgsIHIpIHtcbiAgICBpZiAocikge1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgWydNJywgK3ggKyAoK3IpLCB5XSxcbiAgICAgICAgICAgIFsnbCcsIHcgLSByICogMiwgMF0sXG4gICAgICAgICAgICBbJ2EnLCByLCByLCAwLCAwLCAxLCByLCByXSxcbiAgICAgICAgICAgIFsnbCcsIDAsIGggLSByICogMl0sXG4gICAgICAgICAgICBbJ2EnLCByLCByLCAwLCAwLCAxLCAtciwgcl0sXG4gICAgICAgICAgICBbJ2wnLCByICogMiAtIHcsIDBdLFxuICAgICAgICAgICAgWydhJywgciwgciwgMCwgMCwgMSwgLXIsIC1yXSxcbiAgICAgICAgICAgIFsnbCcsIDAsIHIgKiAyIC0gaF0sXG4gICAgICAgICAgICBbJ2EnLCByLCByLCAwLCAwLCAxLCByLCAtcl0sXG4gICAgICAgICAgICBbJ3onXSxcbiAgICAgICAgXTtcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgICAgWydNJywgeCwgeV0sXG4gICAgICAgIFsnbCcsIHcsIDBdLFxuICAgICAgICBbJ2wnLCAwLCBoXSxcbiAgICAgICAgWydsJywgLXcsIDBdLFxuICAgICAgICBbJ3onXSxcbiAgICBdO1xuICAgIC8vIHJlcy5wYXJzZVBhdGhBcnJheSA9IHBhcnNlUGF0aEFycmF5O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVjdC1wYXRoLmpzLm1hcCIsImltcG9ydCB7IGlzQXJyYXkgfSBmcm9tICdAYW50di91dGlsJztcbnZhciBTUEFDRVMgPSAnXFx4MDlcXHgwYVxceDBiXFx4MGNcXHgwZFxceDIwXFx4YTBcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MjAyOFxcdTIwMjknO1xudmFyIFBBVEhfQ09NTUFORCA9IG5ldyBSZWdFeHAoJyhbYS16XSlbJyArIFNQQUNFUyArICcsXSooKC0/XFxcXGQqXFxcXC4/XFxcXGQqKD86ZVtcXFxcLStdP1xcXFxkKyk/WycgKyBTUEFDRVMgKyAnXSosP1snICsgU1BBQ0VTICsgJ10qKSspJywgJ2lnJyk7XG52YXIgUEFUSF9WQUxVRVMgPSBuZXcgUmVnRXhwKCcoLT9cXFxcZCpcXFxcLj9cXFxcZCooPzplW1xcXFwtK10/XFxcXGQrKT8pWycgKyBTUEFDRVMgKyAnXSosP1snICsgU1BBQ0VTICsgJ10qJywgJ2lnJyk7XG4vLyBQYXJzZXMgZ2l2ZW4gcGF0aCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBhcnJheXMgb2YgcGF0aCBzZWdtZW50c1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcGFyc2VQYXRoU3RyaW5nKHBhdGhTdHJpbmcpIHtcbiAgICBpZiAoIXBhdGhTdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChpc0FycmF5KHBhdGhTdHJpbmcpKSB7XG4gICAgICAgIHJldHVybiBwYXRoU3RyaW5nO1xuICAgIH1cbiAgICB2YXIgcGFyYW1Db3VudHMgPSB7XG4gICAgICAgIGE6IDcsXG4gICAgICAgIGM6IDYsXG4gICAgICAgIG86IDIsXG4gICAgICAgIGg6IDEsXG4gICAgICAgIGw6IDIsXG4gICAgICAgIG06IDIsXG4gICAgICAgIHI6IDQsXG4gICAgICAgIHE6IDQsXG4gICAgICAgIHM6IDQsXG4gICAgICAgIHQ6IDIsXG4gICAgICAgIHY6IDEsXG4gICAgICAgIHU6IDMsXG4gICAgICAgIHo6IDAsXG4gICAgfTtcbiAgICB2YXIgZGF0YSA9IFtdO1xuICAgIFN0cmluZyhwYXRoU3RyaW5nKS5yZXBsYWNlKFBBVEhfQ09NTUFORCwgZnVuY3Rpb24gKGEsIGIsIGMpIHtcbiAgICAgICAgdmFyIHBhcmFtcyA9IFtdO1xuICAgICAgICB2YXIgbmFtZSA9IGIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgYy5yZXBsYWNlKFBBVEhfVkFMVUVTLCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgYiAmJiBwYXJhbXMucHVzaCgrYik7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAobmFtZSA9PT0gJ20nICYmIHBhcmFtcy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICBkYXRhLnB1c2goW2JdLmNvbmNhdChwYXJhbXMuc3BsaWNlKDAsIDIpKSk7XG4gICAgICAgICAgICBuYW1lID0gJ2wnO1xuICAgICAgICAgICAgYiA9IGIgPT09ICdtJyA/ICdsJyA6ICdMJztcbiAgICAgICAgfVxuICAgICAgICBpZiAobmFtZSA9PT0gJ28nICYmIHBhcmFtcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIGRhdGEucHVzaChbYiwgcGFyYW1zWzBdXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hbWUgPT09ICdyJykge1xuICAgICAgICAgICAgZGF0YS5wdXNoKFtiXS5jb25jYXQocGFyYW1zKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3aGlsZSAocGFyYW1zLmxlbmd0aCA+PSBwYXJhbUNvdW50c1tuYW1lXSkge1xuICAgICAgICAgICAgICAgIGRhdGEucHVzaChbYl0uY29uY2F0KHBhcmFtcy5zcGxpY2UoMCwgcGFyYW1Db3VudHNbbmFtZV0pKSk7XG4gICAgICAgICAgICAgICAgaWYgKCFwYXJhbUNvdW50c1tuYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH0pO1xuICAgIHJldHVybiBkYXRhO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFyc2UtcGF0aC1zdHJpbmcuanMubWFwIiwiaW1wb3J0IHBhcnNlUGF0aFN0cmluZyBmcm9tICcuL3BhcnNlLXBhdGgtc3RyaW5nJztcbnZhciBSRUdFWF9NRCA9IC9bYS16XS87XG5mdW5jdGlvbiB0b1N5bW1ldHJ5KHAsIGMpIHtcbiAgICByZXR1cm4gW1xuICAgICAgICBjWzBdICsgKGNbMF0gLSBwWzBdKSxcbiAgICAgICAgY1sxXSArIChjWzFdIC0gcFsxXSksXG4gICAgXTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHBhdGhUb0Fic29sdXRlKHBhdGhTdHJpbmcpIHtcbiAgICB2YXIgcGF0aEFycmF5ID0gcGFyc2VQYXRoU3RyaW5nKHBhdGhTdHJpbmcpO1xuICAgIGlmICghcGF0aEFycmF5IHx8ICFwYXRoQXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBbJ00nLCAwLCAwXSxcbiAgICAgICAgXTtcbiAgICB9XG4gICAgdmFyIG5lZWRQcm9jZXNzID0gZmFsc2U7IC8vIOWmguaenOWtmOWcqOWwj+WGmeeahOWRveS7pOaIluiAhSBWLEgsVCxTIOWImemcgOimgeWkhOeQhlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjbWQgPSBwYXRoQXJyYXlbaV1bMF07XG4gICAgICAgIC8vIOWmguaenOWtmOWcqOebuOWvueS9jee9rueahOWRveS7pO+8jOWImeS4reaWrei/lOWbnlxuICAgICAgICBpZiAoUkVHRVhfTUQudGVzdChjbWQpIHx8IFsnVicsICdIJywgJ1QnLCAnUyddLmluZGV4T2YoY21kKSA+PSAwKSB7XG4gICAgICAgICAgICBuZWVkUHJvY2VzcyA9IHRydWU7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyDlpoLmnpzkuI3lrZjlnKjnm7jlr7nlkb3ku6TvvIzliJnnm7TmjqXov5Tlm55cbiAgICAvLyDlpoLmnpzlnKjkuJrliqHkuIrpg73lhpnnu53lr7not6/lvoTvvIzov5nnp43mlrnlvI/mnIDlv6vvvIzku4XlgZrkuobkuIDmrKHmo4DmtYtcbiAgICBpZiAoIW5lZWRQcm9jZXNzKSB7XG4gICAgICAgIHJldHVybiBwYXRoQXJyYXk7XG4gICAgfVxuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgeCA9IDA7XG4gICAgdmFyIHkgPSAwO1xuICAgIHZhciBteCA9IDA7XG4gICAgdmFyIG15ID0gMDtcbiAgICB2YXIgc3RhcnQgPSAwO1xuICAgIHZhciBwYTA7XG4gICAgdmFyIGRvdHM7XG4gICAgdmFyIGZpcnN0ID0gcGF0aEFycmF5WzBdO1xuICAgIGlmIChmaXJzdFswXSA9PT0gJ00nIHx8IGZpcnN0WzBdID09PSAnbScpIHtcbiAgICAgICAgeCA9ICtmaXJzdFsxXTtcbiAgICAgICAgeSA9ICtmaXJzdFsyXTtcbiAgICAgICAgbXggPSB4O1xuICAgICAgICBteSA9IHk7XG4gICAgICAgIHN0YXJ0Kys7XG4gICAgICAgIHJlc1swXSA9IFsnTScsIHgsIHldO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gc3RhcnQsIGlpID0gcGF0aEFycmF5Lmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgdmFyIHBhID0gcGF0aEFycmF5W2ldO1xuICAgICAgICB2YXIgcHJlUGFyYW1zID0gcmVzW2kgLSAxXTsgLy8g5Y+W5YmN5LiA5Liq5bey57uP5aSE55CG5ZCO55qE6IqC54K577yM5ZCm5YiZ5Lya5Ye6546w6Zeu6aKYXG4gICAgICAgIHZhciByID0gW107XG4gICAgICAgIHZhciBjbWQgPSBwYVswXTtcbiAgICAgICAgdmFyIHVwQ21kID0gY21kLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgIGlmIChjbWQgIT09IHVwQ21kKSB7XG4gICAgICAgICAgICByWzBdID0gdXBDbWQ7XG4gICAgICAgICAgICBzd2l0Y2ggKHVwQ21kKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgICAgIHJbMV0gPSBwYVsxXTtcbiAgICAgICAgICAgICAgICAgICAgclsyXSA9IHBhWzJdO1xuICAgICAgICAgICAgICAgICAgICByWzNdID0gcGFbM107XG4gICAgICAgICAgICAgICAgICAgIHJbNF0gPSBwYVs0XTtcbiAgICAgICAgICAgICAgICAgICAgcls1XSA9IHBhWzVdO1xuICAgICAgICAgICAgICAgICAgICByWzZdID0gK3BhWzZdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgcls3XSA9ICtwYVs3XSArIHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ1YnOlxuICAgICAgICAgICAgICAgICAgICByWzFdID0gK3BhWzFdICsgeTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnSCc6XG4gICAgICAgICAgICAgICAgICAgIHJbMV0gPSArcGFbMV0gKyB4O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgICAgICAgICAgbXggPSArcGFbMV0gKyB4O1xuICAgICAgICAgICAgICAgICAgICBteSA9ICtwYVsyXSArIHk7XG4gICAgICAgICAgICAgICAgICAgIHJbMV0gPSBteDtcbiAgICAgICAgICAgICAgICAgICAgclsyXSA9IG15O1xuICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gZm9yIGxpbnRcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMSwgamogPSBwYS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gK3BhW2pdICsgKChqICUgMikgPyB4IDogeSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgLy8g5aaC5p6c5pys5p2l5bey57uP5aSn5YaZ77yM5YiZ5LiN5aSE55CGXG4gICAgICAgICAgICByID0gcGF0aEFycmF5W2ldO1xuICAgICAgICB9XG4gICAgICAgIC8vIOmcgOimgeWcqOWklumdoue7n+S4gOWBmu+8jOWQjOaXtuWkhOeQhiBWLEgsUyxUIOetieeJueauiuaMh+S7pFxuICAgICAgICBzd2l0Y2ggKHVwQ21kKSB7XG4gICAgICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgICAgICAgICB4ID0gK214O1xuICAgICAgICAgICAgICAgIHkgPSArbXk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdIJzpcbiAgICAgICAgICAgICAgICB4ID0gclsxXTtcbiAgICAgICAgICAgICAgICByID0gWydMJywgeCwgeV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdWJzpcbiAgICAgICAgICAgICAgICB5ID0gclsxXTtcbiAgICAgICAgICAgICAgICByID0gWydMJywgeCwgeV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdUJzpcbiAgICAgICAgICAgICAgICB4ID0gclsxXTtcbiAgICAgICAgICAgICAgICB5ID0gclsyXTtcbiAgICAgICAgICAgICAgICAvLyDku6UgeCwgeSDkuLrkuK3lv4PnmoTvvIzkuIrkuIDkuKrmjqfliLbngrnnmoTlr7nnp7DngrlcbiAgICAgICAgICAgICAgICAvLyDpnIDopoHlgYforr7kuIrkuIDkuKroioLngrnnmoTlkb3ku6TkuLogUVxuICAgICAgICAgICAgICAgIHZhciBzeW1ldHJpY1QgPSB0b1N5bW1ldHJ5KFtwcmVQYXJhbXNbMV0sIHByZVBhcmFtc1syXV0sIFtwcmVQYXJhbXNbM10sIHByZVBhcmFtc1s0XV0pO1xuICAgICAgICAgICAgICAgIHIgPSBbJ1EnLCBzeW1ldHJpY1RbMF0sIHN5bWV0cmljVFsxXSwgeCwgeV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICAgICAgICB4ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgIHkgPSByW3IubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgLy8g5LulIHgseSDkuLrkuK3lv4PvvIzlj5bkuIrkuIDkuKrmjqfliLbngrnvvIxcbiAgICAgICAgICAgICAgICAvLyDpnIDopoHlgYforr7kuIrkuIDkuKrnur/mrrXkuLogQyDmiJbogIUgU1xuICAgICAgICAgICAgICAgIHZhciBsZW5ndGhfMSA9IHByZVBhcmFtcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIHN5bWV0cmljUyA9IHRvU3ltbWV0cnkoW3ByZVBhcmFtc1tsZW5ndGhfMSAtIDRdLCBwcmVQYXJhbXNbbGVuZ3RoXzEgLSAzXV0sIFtwcmVQYXJhbXNbbGVuZ3RoXzEgLSAyXSwgcHJlUGFyYW1zW2xlbmd0aF8xIC0gMV1dKTtcbiAgICAgICAgICAgICAgICByID0gWydDJywgc3ltZXRyaWNTWzBdLCBzeW1ldHJpY1NbMV0sIHJbMV0sIHJbMl0sIHgsIHldO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgICAgICAgICAgbXggPSByW3IubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgICAgbXkgPSByW3IubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgYnJlYWs7IC8vIGZvciBsaW50XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHggPSByW3IubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICByZXMucHVzaChyKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhdGgtMi1hYnNvbHV0ZS5qcy5tYXAiLCJ2YXIgVEFVID0gTWF0aC5QSSAqIDI7XG52YXIgbWFwVG9FbGxpcHNlID0gZnVuY3Rpb24gKF9hLCByeCwgcnksIGNvc3BoaSwgc2lucGhpLCBjZW50ZXJ4LCBjZW50ZXJ5KSB7XG4gICAgdmFyIHggPSBfYS54LCB5ID0gX2EueTtcbiAgICB4ICo9IHJ4O1xuICAgIHkgKj0gcnk7XG4gICAgdmFyIHhwID0gY29zcGhpICogeCAtIHNpbnBoaSAqIHk7XG4gICAgdmFyIHlwID0gc2lucGhpICogeCArIGNvc3BoaSAqIHk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogeHAgKyBjZW50ZXJ4LFxuICAgICAgICB5OiB5cCArIGNlbnRlcnlcbiAgICB9O1xufTtcbnZhciBhcHByb3hVbml0QXJjID0gZnVuY3Rpb24gKGFuZzEsIGFuZzIpIHtcbiAgICAvLyBJZiA5MCBkZWdyZWUgY2lyY3VsYXIgYXJjLCB1c2UgYSBjb25zdGFudFxuICAgIC8vIGFzIGRlcml2ZWQgZnJvbSBodHRwOi8vc3BlbmNlcm1vcnRlbnNlbi5jb20vYXJ0aWNsZXMvYmV6aWVyLWNpcmNsZVxuICAgIHZhciBhID0gYW5nMiA9PT0gMS41NzA3OTYzMjY3OTQ4OTY2XG4gICAgICAgID8gMC41NTE5MTUwMjQ0OTRcbiAgICAgICAgOiBhbmcyID09PSAtMS41NzA3OTYzMjY3OTQ4OTY2XG4gICAgICAgICAgICA/IC0wLjU1MTkxNTAyNDQ5NFxuICAgICAgICAgICAgOiA0IC8gMyAqIE1hdGgudGFuKGFuZzIgLyA0KTtcbiAgICB2YXIgeDEgPSBNYXRoLmNvcyhhbmcxKTtcbiAgICB2YXIgeTEgPSBNYXRoLnNpbihhbmcxKTtcbiAgICB2YXIgeDIgPSBNYXRoLmNvcyhhbmcxICsgYW5nMik7XG4gICAgdmFyIHkyID0gTWF0aC5zaW4oYW5nMSArIGFuZzIpO1xuICAgIHJldHVybiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHg6IHgxIC0geTEgKiBhLFxuICAgICAgICAgICAgeTogeTEgKyB4MSAqIGFcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgeDogeDIgKyB5MiAqIGEsXG4gICAgICAgICAgICB5OiB5MiAtIHgyICogYVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICB4OiB4MixcbiAgICAgICAgICAgIHk6IHkyXG4gICAgICAgIH1cbiAgICBdO1xufTtcbnZhciB2ZWN0b3JBbmdsZSA9IGZ1bmN0aW9uICh1eCwgdXksIHZ4LCB2eSkge1xuICAgIHZhciBzaWduID0gKHV4ICogdnkgLSB1eSAqIHZ4IDwgMCkgPyAtMSA6IDE7XG4gICAgdmFyIGRvdCA9IHV4ICogdnggKyB1eSAqIHZ5O1xuICAgIGlmIChkb3QgPiAxKSB7XG4gICAgICAgIGRvdCA9IDE7XG4gICAgfVxuICAgIGlmIChkb3QgPCAtMSkge1xuICAgICAgICBkb3QgPSAtMTtcbiAgICB9XG4gICAgcmV0dXJuIHNpZ24gKiBNYXRoLmFjb3MoZG90KTtcbn07XG52YXIgZ2V0QXJjQ2VudGVyID0gZnVuY3Rpb24gKHB4LCBweSwgY3gsIGN5LCByeCwgcnksIGxhcmdlQXJjRmxhZywgc3dlZXBGbGFnLCBzaW5waGksIGNvc3BoaSwgcHhwLCBweXApIHtcbiAgICB2YXIgcnhzcSA9IE1hdGgucG93KHJ4LCAyKTtcbiAgICB2YXIgcnlzcSA9IE1hdGgucG93KHJ5LCAyKTtcbiAgICB2YXIgcHhwc3EgPSBNYXRoLnBvdyhweHAsIDIpO1xuICAgIHZhciBweXBzcSA9IE1hdGgucG93KHB5cCwgMik7XG4gICAgdmFyIHJhZGljYW50ID0gKHJ4c3EgKiByeXNxKSAtIChyeHNxICogcHlwc3EpIC0gKHJ5c3EgKiBweHBzcSk7XG4gICAgaWYgKHJhZGljYW50IDwgMCkge1xuICAgICAgICByYWRpY2FudCA9IDA7XG4gICAgfVxuICAgIHJhZGljYW50IC89IChyeHNxICogcHlwc3EpICsgKHJ5c3EgKiBweHBzcSk7XG4gICAgcmFkaWNhbnQgPSBNYXRoLnNxcnQocmFkaWNhbnQpICogKGxhcmdlQXJjRmxhZyA9PT0gc3dlZXBGbGFnID8gLTEgOiAxKTtcbiAgICB2YXIgY2VudGVyeHAgPSByYWRpY2FudCAqIHJ4IC8gcnkgKiBweXA7XG4gICAgdmFyIGNlbnRlcnlwID0gcmFkaWNhbnQgKiAtcnkgLyByeCAqIHB4cDtcbiAgICB2YXIgY2VudGVyeCA9IGNvc3BoaSAqIGNlbnRlcnhwIC0gc2lucGhpICogY2VudGVyeXAgKyAocHggKyBjeCkgLyAyO1xuICAgIHZhciBjZW50ZXJ5ID0gc2lucGhpICogY2VudGVyeHAgKyBjb3NwaGkgKiBjZW50ZXJ5cCArIChweSArIGN5KSAvIDI7XG4gICAgdmFyIHZ4MSA9IChweHAgLSBjZW50ZXJ4cCkgLyByeDtcbiAgICB2YXIgdnkxID0gKHB5cCAtIGNlbnRlcnlwKSAvIHJ5O1xuICAgIHZhciB2eDIgPSAoLXB4cCAtIGNlbnRlcnhwKSAvIHJ4O1xuICAgIHZhciB2eTIgPSAoLXB5cCAtIGNlbnRlcnlwKSAvIHJ5O1xuICAgIHZhciBhbmcxID0gdmVjdG9yQW5nbGUoMSwgMCwgdngxLCB2eTEpO1xuICAgIHZhciBhbmcyID0gdmVjdG9yQW5nbGUodngxLCB2eTEsIHZ4MiwgdnkyKTtcbiAgICBpZiAoc3dlZXBGbGFnID09PSAwICYmIGFuZzIgPiAwKSB7XG4gICAgICAgIGFuZzIgLT0gVEFVO1xuICAgIH1cbiAgICBpZiAoc3dlZXBGbGFnID09PSAxICYmIGFuZzIgPCAwKSB7XG4gICAgICAgIGFuZzIgKz0gVEFVO1xuICAgIH1cbiAgICByZXR1cm4gW2NlbnRlcngsIGNlbnRlcnksIGFuZzEsIGFuZzJdO1xufTtcbnZhciBhcmNUb0JlemllciA9IGZ1bmN0aW9uIChfYSkge1xuICAgIHZhciBweCA9IF9hLnB4LCBweSA9IF9hLnB5LCBjeCA9IF9hLmN4LCBjeSA9IF9hLmN5LCByeCA9IF9hLnJ4LCByeSA9IF9hLnJ5LCBfYiA9IF9hLnhBeGlzUm90YXRpb24sIHhBeGlzUm90YXRpb24gPSBfYiA9PT0gdm9pZCAwID8gMCA6IF9iLCBfYyA9IF9hLmxhcmdlQXJjRmxhZywgbGFyZ2VBcmNGbGFnID0gX2MgPT09IHZvaWQgMCA/IDAgOiBfYywgX2QgPSBfYS5zd2VlcEZsYWcsIHN3ZWVwRmxhZyA9IF9kID09PSB2b2lkIDAgPyAwIDogX2Q7XG4gICAgdmFyIGN1cnZlcyA9IFtdO1xuICAgIGlmIChyeCA9PT0gMCB8fCByeSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW3sgeDE6IDAsIHkxOiAwLCB4MjogMCwgeTI6IDAsIHg6IGN4LCB5OiBjeSB9XTtcbiAgICB9XG4gICAgdmFyIHNpbnBoaSA9IE1hdGguc2luKHhBeGlzUm90YXRpb24gKiBUQVUgLyAzNjApO1xuICAgIHZhciBjb3NwaGkgPSBNYXRoLmNvcyh4QXhpc1JvdGF0aW9uICogVEFVIC8gMzYwKTtcbiAgICB2YXIgcHhwID0gY29zcGhpICogKHB4IC0gY3gpIC8gMiArIHNpbnBoaSAqIChweSAtIGN5KSAvIDI7XG4gICAgdmFyIHB5cCA9IC1zaW5waGkgKiAocHggLSBjeCkgLyAyICsgY29zcGhpICogKHB5IC0gY3kpIC8gMjtcbiAgICBpZiAocHhwID09PSAwICYmIHB5cCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW3sgeDE6IDAsIHkxOiAwLCB4MjogMCwgeTI6IDAsIHg6IGN4LCB5OiBjeSB9XTtcbiAgICB9XG4gICAgcnggPSBNYXRoLmFicyhyeCk7XG4gICAgcnkgPSBNYXRoLmFicyhyeSk7XG4gICAgdmFyIGxhbWJkYSA9IE1hdGgucG93KHB4cCwgMikgLyBNYXRoLnBvdyhyeCwgMikgK1xuICAgICAgICBNYXRoLnBvdyhweXAsIDIpIC8gTWF0aC5wb3cocnksIDIpO1xuICAgIGlmIChsYW1iZGEgPiAxKSB7XG4gICAgICAgIHJ4ICo9IE1hdGguc3FydChsYW1iZGEpO1xuICAgICAgICByeSAqPSBNYXRoLnNxcnQobGFtYmRhKTtcbiAgICB9XG4gICAgdmFyIF9lID0gZ2V0QXJjQ2VudGVyKHB4LCBweSwgY3gsIGN5LCByeCwgcnksIGxhcmdlQXJjRmxhZywgc3dlZXBGbGFnLCBzaW5waGksIGNvc3BoaSwgcHhwLCBweXApLCBjZW50ZXJ4ID0gX2VbMF0sIGNlbnRlcnkgPSBfZVsxXSwgYW5nMSA9IF9lWzJdLCBhbmcyID0gX2VbM107XG4gICAgLy8gSWYgJ2FuZzInID09IDkwLjAwMDAwMDAwMDEsIHRoZW4gYHJhdGlvYCB3aWxsIGV2YWx1YXRlIHRvXG4gICAgLy8gMS4wMDAwMDAwMDAxLiBUaGlzIGNhdXNlcyBgc2VnbWVudHNgIHRvIGJlIGdyZWF0ZXIgdGhhbiBvbmUsIHdoaWNoIGlzIGFuXG4gICAgLy8gdW5lY2Vzc2FyeSBzcGxpdCwgYW5kIGFkZHMgZXh0cmEgcG9pbnRzIHRvIHRoZSBiZXppZXIgY3VydmUuIFRvIGFsbGV2aWF0ZVxuICAgIC8vIHRoaXMgaXNzdWUsIHdlIHJvdW5kIHRvIDEuMCB3aGVuIHRoZSByYXRpbyBpcyBjbG9zZSB0byAxLjAuXG4gICAgdmFyIHJhdGlvID0gTWF0aC5hYnMoYW5nMikgLyAoVEFVIC8gNCk7XG4gICAgaWYgKE1hdGguYWJzKDEuMCAtIHJhdGlvKSA8IDAuMDAwMDAwMSkge1xuICAgICAgICByYXRpbyA9IDEuMDtcbiAgICB9XG4gICAgdmFyIHNlZ21lbnRzID0gTWF0aC5tYXgoTWF0aC5jZWlsKHJhdGlvKSwgMSk7XG4gICAgYW5nMiAvPSBzZWdtZW50cztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlZ21lbnRzOyBpKyspIHtcbiAgICAgICAgY3VydmVzLnB1c2goYXBwcm94VW5pdEFyYyhhbmcxLCBhbmcyKSk7XG4gICAgICAgIGFuZzEgKz0gYW5nMjtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnZlcy5tYXAoZnVuY3Rpb24gKGN1cnZlKSB7XG4gICAgICAgIHZhciBfYSA9IG1hcFRvRWxsaXBzZShjdXJ2ZVswXSwgcngsIHJ5LCBjb3NwaGksIHNpbnBoaSwgY2VudGVyeCwgY2VudGVyeSksIHgxID0gX2EueCwgeTEgPSBfYS55O1xuICAgICAgICB2YXIgX2IgPSBtYXBUb0VsbGlwc2UoY3VydmVbMV0sIHJ4LCByeSwgY29zcGhpLCBzaW5waGksIGNlbnRlcngsIGNlbnRlcnkpLCB4MiA9IF9iLngsIHkyID0gX2IueTtcbiAgICAgICAgdmFyIF9jID0gbWFwVG9FbGxpcHNlKGN1cnZlWzJdLCByeCwgcnksIGNvc3BoaSwgc2lucGhpLCBjZW50ZXJ4LCBjZW50ZXJ5KSwgeCA9IF9jLngsIHkgPSBfYy55O1xuICAgICAgICByZXR1cm4geyB4MTogeDEsIHkxOiB5MSwgeDI6IHgyLCB5MjogeTIsIHg6IHgsIHk6IHkgfTtcbiAgICB9KTtcbn07XG5leHBvcnQgZnVuY3Rpb24gYXJjVG9DdWJpYyh4MSwgeTEsIHJ4LCByeSwgYW5nbGUsIExBRiwgU0YsIHgyLCB5Mikge1xuICAgIHZhciBjdXJ2ZXMgPSBhcmNUb0Jlemllcih7XG4gICAgICAgIHB4OiB4MSxcbiAgICAgICAgcHk6IHkxLFxuICAgICAgICBjeDogeDIsXG4gICAgICAgIGN5OiB5MixcbiAgICAgICAgcng6IHJ4LFxuICAgICAgICByeTogcnksXG4gICAgICAgIHhBeGlzUm90YXRpb246IGFuZ2xlLFxuICAgICAgICBsYXJnZUFyY0ZsYWc6IExBRixcbiAgICAgICAgc3dlZXBGbGFnOiBTRixcbiAgICB9KTtcbiAgICByZXR1cm4gY3VydmVzLnJlZHVjZShmdW5jdGlvbiAocHJldiwgY3VyKSB7XG4gICAgICAgIHZhciB4MSA9IGN1ci54MSwgeTEgPSBjdXIueTEsIHgyID0gY3VyLngyLCB5MiA9IGN1ci55MiwgeCA9IGN1ci54LCB5ID0gY3VyLnk7XG4gICAgICAgIHByZXYucHVzaCh4MSwgeTEsIHgyLCB5MiwgeCwgeSk7XG4gICAgICAgIHJldHVybiBwcmV2O1xuICAgIH0sIFtdKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFyYy0yLWN1YmljLmpzLm1hcCIsImV4cG9ydCBmdW5jdGlvbiBxdWFkVG9DdWJpYyh4MSwgeTEsIHF4LCBxeSwgeDIsIHkyKSB7XG4gICAgdmFyIHIxMyA9IDEgLyAzO1xuICAgIHZhciByMjMgPSAyIC8gMztcbiAgICByZXR1cm4gW1xuICAgICAgICByMTMgKiB4MSArIHIyMyAqIHF4LFxuICAgICAgICByMTMgKiB5MSArIHIyMyAqIHF5LFxuICAgICAgICByMTMgKiB4MiArIHIyMyAqIHF4LFxuICAgICAgICByMTMgKiB5MiArIHIyMyAqIHF5LFxuICAgICAgICB4MiwgeTIsIC8vIHgseVxuICAgIF07XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1xdWFkLTItY3ViaWMuanMubWFwIiwiLy8gZXhwb3J0IGZ1bmN0aW9uIGdldFBvaW50QXRTZWdMZW5ndGgocDF4OiBudW1iZXIsIHAxeTogbnVtYmVyLCBjMXg6IG51bWJlciwgYzF5OiBudW1iZXIsIGMyeDogbnVtYmVyLCBjMnk6IG51bWJlciwgcDJ4OiBudW1iZXIsIHAyeTogbnVtYmVyLCB0OiBudW1iZXIpIHtcbi8vICAgY29uc3QgdDEgPSAxIC0gdDtcbi8vICAgcmV0dXJuIHtcbi8vICAgICB4OiAodDEgKiogMykgKiBwMXhcbi8vICAgICAgICsgdDEgKiB0MSAqIDMgKiB0ICogYzF4XG4vLyAgICAgICArIHQxICogMyAqIHQgKiB0ICogYzJ4XG4vLyAgICAgICArICh0ICoqIDMpICogcDJ4LFxuLy8gICAgIHk6ICh0MSAqKiAzKSAqIHAxeVxuLy8gICAgICAgKyB0MSAqIHQxICogMyAqIHQgKiBjMXlcbi8vICAgICAgICsgdDEgKiAzICogdCAqIHQgKiBjMnlcbi8vICAgICAgICsgKHQgKiogMykgKiBwMnksXG4vLyAgIH07XG4vLyB9XG4vLyBleHBvcnQgZnVuY3Rpb24gbWlkUG9pbnQoYTogbnVtYmVyW10sIGI6IG51bWJlcltdLCB0OiBudW1iZXIpIHtcbi8vICAgY29uc3QgYXggPSBhWzBdO1xuLy8gICBjb25zdCBheSA9IGFbMV07XG4vLyAgIGNvbnN0IGJ4ID0gYlswXTtcbi8vICAgY29uc3QgYnkgPSBiWzFdO1xuLy8gICByZXR1cm4gW2F4ICsgKGJ4IC0gYXgpICogdCwgYXkgKyAoYnkgLSBheSkgKiB0XTtcbi8vIH1cbmV4cG9ydCBmdW5jdGlvbiBsaW5lVG9DdWJpYyh4MSwgeTEsIHgyLCB5Mikge1xuICAgIHJldHVybiBbeDEsIHkxLCB4MiwgeTIsIHgyLCB5Ml07XG4gICAgLy8gY29uc3QgdCA9IDAuNTtcbiAgICAvLyBjb25zdCBwMCA9IFt4MSwgeTFdO1xuICAgIC8vIGNvbnN0IHAxID0gW3gyLCB5Ml07XG4gICAgLy8gY29uc3QgcDIgPSBtaWRQb2ludChwMCwgcDEsIHQpO1xuICAgIC8vIGNvbnN0IHAzID0gbWlkUG9pbnQocDEsIHAyLCB0KTtcbiAgICAvLyBjb25zdCBwNCA9IG1pZFBvaW50KHAyLCBwMywgdCk7XG4gICAgLy8gY29uc3QgcDUgPSBtaWRQb2ludChwMywgcDQsIHQpO1xuICAgIC8vIGNvbnN0IHA2ID0gbWlkUG9pbnQocDQsIHA1LCB0KTtcbiAgICAvLyBjb25zdCBjcDEgPSBnZXRQb2ludEF0U2VnTGVuZ3RoLmFwcGx5KDAsIHAwLmNvbmNhdChwMiwgcDQsIHA2LCB0KSk7XG4gICAgLy8gY29uc3QgY3AyID0gZ2V0UG9pbnRBdFNlZ0xlbmd0aC5hcHBseSgwLCBwNi5jb25jYXQocDUsIHAzLCBwMSwgMCkpO1xuICAgIC8vIHJldHVybiBbY3AxLngsIGNwMS55LCBjcDIueCwgY3AyLnksIHgyLCB5Ml07XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1saW5lLTItY3ViaWMuanMubWFwIiwiaW1wb3J0IHsgYXJjVG9DdWJpYyB9IGZyb20gJy4vYXJjLTItY3ViaWMnO1xuaW1wb3J0IHsgcXVhZFRvQ3ViaWMgfSBmcm9tICcuL3F1YWQtMi1jdWJpYyc7XG5pbXBvcnQgeyBsaW5lVG9DdWJpYyB9IGZyb20gJy4vbGluZS0yLWN1YmljJztcbmV4cG9ydCBmdW5jdGlvbiBzZWdtZW50VG9DdWJpYyhzZWdtZW50LCBwYXJhbXMpIHtcbiAgICBpZiAoJ1RRJy5pbmRleE9mKHNlZ21lbnRbMF0pIDwgMCkge1xuICAgICAgICBwYXJhbXMucXggPSBudWxsO1xuICAgICAgICBwYXJhbXMucXkgPSBudWxsO1xuICAgIH1cbiAgICB2YXIgX2EgPSBzZWdtZW50LnNsaWNlKDEpLCBzMSA9IF9hWzBdLCBzMiA9IF9hWzFdO1xuICAgIHN3aXRjaCAoc2VnbWVudFswXSkge1xuICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgIHBhcmFtcy54ID0gczE7XG4gICAgICAgICAgICBwYXJhbXMueSA9IHMyO1xuICAgICAgICAgICAgcmV0dXJuIHNlZ21lbnQ7XG4gICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgICAgcmV0dXJuIFsnQyddLmNvbmNhdChhcmNUb0N1YmljLmFwcGx5KDAsIFtwYXJhbXMueDEsIHBhcmFtcy55MV0uY29uY2F0KHNlZ21lbnQuc2xpY2UoMSkpKSk7XG4gICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgICAgcGFyYW1zLnF4ID0gczE7XG4gICAgICAgICAgICBwYXJhbXMucXkgPSBzMjtcbiAgICAgICAgICAgIHJldHVybiBbJ0MnXS5jb25jYXQocXVhZFRvQ3ViaWMuYXBwbHkoMCwgW3BhcmFtcy54MSwgcGFyYW1zLnkxXS5jb25jYXQoc2VnbWVudC5zbGljZSgxKSkpKTtcbiAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICByZXR1cm4gWydDJ10uY29uY2F0KGxpbmVUb0N1YmljKHBhcmFtcy54MSwgcGFyYW1zLnkxLCBzZWdtZW50WzFdLCBzZWdtZW50WzJdKSk7XG4gICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcmV0dXJuIFsnQyddLmNvbmNhdChsaW5lVG9DdWJpYyhwYXJhbXMueDEsIHBhcmFtcy55MSwgc2VnbWVudFsxXSwgcGFyYW1zLnkxKSk7XG4gICAgICAgIGNhc2UgJ1YnOlxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcmV0dXJuIFsnQyddLmNvbmNhdChsaW5lVG9DdWJpYyhwYXJhbXMueDEsIHBhcmFtcy55MSwgcGFyYW1zLngxLCBzZWdtZW50WzFdKSk7XG4gICAgICAgIGNhc2UgJ1onOlxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcmV0dXJuIFsnQyddLmNvbmNhdChsaW5lVG9DdWJpYyhwYXJhbXMueDEsIHBhcmFtcy55MSwgcGFyYW1zLngsIHBhcmFtcy55KSk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgfVxuICAgIHJldHVybiBzZWdtZW50O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VnbWVudC0yLWN1YmljLmpzLm1hcCIsImltcG9ydCBwYXRoMkFic29sdXRlIGZyb20gJy4vcGF0aC0yLWFic29sdXRlJztcbmltcG9ydCB7IHNlZ21lbnRUb0N1YmljIH0gZnJvbSAnLi9wcm9jZXNzL3NlZ21lbnQtMi1jdWJpYyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYXRoVG9DdXJ2ZShwYXRoLCBuZWVkWkNvbW1hbmRJbmRleGVzKSB7XG4gICAgaWYgKG5lZWRaQ29tbWFuZEluZGV4ZXMgPT09IHZvaWQgMCkgeyBuZWVkWkNvbW1hbmRJbmRleGVzID0gZmFsc2U7IH1cbiAgICB2YXIgcGF0aEFycmF5ID0gcGF0aDJBYnNvbHV0ZShwYXRoKTtcbiAgICB2YXIgcGFyYW1zID0ge1xuICAgICAgICB4MTogMCwgeTE6IDAsIHgyOiAwLCB5MjogMCwgeDogMCwgeTogMCwgcXg6IG51bGwsIHF5OiBudWxsLFxuICAgIH07XG4gICAgdmFyIGFsbFBhdGhDb21tYW5kcyA9IFtdO1xuICAgIHZhciBwYXRoQ29tbWFuZCA9ICcnO1xuICAgIHZhciBpaSA9IHBhdGhBcnJheS5sZW5ndGg7XG4gICAgdmFyIHNlZ21lbnQ7XG4gICAgdmFyIHNlZ2xlbjtcbiAgICB2YXIgekNvbW1hbmRJbmRleGVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpaTsgaSArPSAxKSB7XG4gICAgICAgIGlmIChwYXRoQXJyYXlbaV0pXG4gICAgICAgICAgICBwYXRoQ29tbWFuZCA9IHBhdGhBcnJheVtpXVswXTtcbiAgICAgICAgYWxsUGF0aENvbW1hbmRzW2ldID0gcGF0aENvbW1hbmQ7XG4gICAgICAgIHBhdGhBcnJheVtpXSA9IHNlZ21lbnRUb0N1YmljKHBhdGhBcnJheVtpXSwgcGFyYW1zKTtcbiAgICAgICAgZml4QXJjKHBhdGhBcnJheSwgYWxsUGF0aENvbW1hbmRzLCBpKTtcbiAgICAgICAgaWkgPSBwYXRoQXJyYXkubGVuZ3RoOyAvLyBzb2x2ZXMgY3VydmVBcnJheXMgZW5kaW5nIGluIFpcbiAgICAgICAgLy8ga2VlcCBaIGNvbW1hbmQgYWNjb3VudCBmb3IgbGluZUpvaW5cbiAgICAgICAgLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vYW50dmlzL3V0aWwvaXNzdWVzLzY4XG4gICAgICAgIGlmIChwYXRoQ29tbWFuZCA9PT0gJ1onKSB7XG4gICAgICAgICAgICB6Q29tbWFuZEluZGV4ZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgICBzZWdtZW50ID0gcGF0aEFycmF5W2ldO1xuICAgICAgICBzZWdsZW4gPSBzZWdtZW50Lmxlbmd0aDtcbiAgICAgICAgcGFyYW1zLngxID0gK3NlZ21lbnRbc2VnbGVuIC0gMl07XG4gICAgICAgIHBhcmFtcy55MSA9ICtzZWdtZW50W3NlZ2xlbiAtIDFdO1xuICAgICAgICBwYXJhbXMueDIgPSArKHNlZ21lbnRbc2VnbGVuIC0gNF0pIHx8IHBhcmFtcy54MTtcbiAgICAgICAgcGFyYW1zLnkyID0gKyhzZWdtZW50W3NlZ2xlbiAtIDNdKSB8fCBwYXJhbXMueTE7XG4gICAgfVxuICAgIGlmIChuZWVkWkNvbW1hbmRJbmRleGVzKSB7XG4gICAgICAgIHJldHVybiBbcGF0aEFycmF5LCB6Q29tbWFuZEluZGV4ZXNdO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHBhdGhBcnJheTtcbiAgICB9XG59XG5mdW5jdGlvbiBmaXhBcmMocGF0aEFycmF5LCBhbGxQYXRoQ29tbWFuZHMsIGkpIHtcbiAgICBpZiAocGF0aEFycmF5W2ldLmxlbmd0aCA+IDcpIHtcbiAgICAgICAgcGF0aEFycmF5W2ldLnNoaWZ0KCk7XG4gICAgICAgIHZhciBwaSA9IHBhdGhBcnJheVtpXTtcbiAgICAgICAgLy8gY29uc3QgbmkgPSBpICsgMTtcbiAgICAgICAgdmFyIG5pID0gaTtcbiAgICAgICAgd2hpbGUgKHBpLmxlbmd0aCkge1xuICAgICAgICAgICAgLy8gaWYgY3JlYXRlZCBtdWx0aXBsZSBDOnMsIHRoZWlyIG9yaWdpbmFsIHNlZyBpcyBzYXZlZFxuICAgICAgICAgICAgYWxsUGF0aENvbW1hbmRzW2ldID0gJ0EnO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgcGF0aEFycmF5LnNwbGljZShuaSArPSAxLCAwLCBbJ0MnXS5jb25jYXQocGkuc3BsaWNlKDAsIDYpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcGF0aEFycmF5LnNwbGljZShpLCAxKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXRoLTItY3VydmUuanMubWFwIiwiaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gJ0BhbnR2L3V0aWwnO1xuaW1wb3J0IHJlY3RQYXRoIGZyb20gJy4vcmVjdC1wYXRoJztcbmltcG9ydCBwYXRoMkN1cnZlIGZyb20gJy4vcGF0aC0yLWN1cnZlJztcbnZhciBiYXNlMyA9IGZ1bmN0aW9uICh0LCBwMSwgcDIsIHAzLCBwNCkge1xuICAgIHZhciB0MSA9IC0zICogcDEgKyA5ICogcDIgLSA5ICogcDMgKyAzICogcDQ7XG4gICAgdmFyIHQyID0gdCAqIHQxICsgNiAqIHAxIC0gMTIgKiBwMiArIDYgKiBwMztcbiAgICByZXR1cm4gdCAqIHQyIC0gMyAqIHAxICsgMyAqIHAyO1xufTtcbnZhciBiZXpsZW4gPSBmdW5jdGlvbiAoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB6KSB7XG4gICAgaWYgKHogPT09IG51bGwpIHtcbiAgICAgICAgeiA9IDE7XG4gICAgfVxuICAgIHogPSB6ID4gMSA/IDEgOiB6IDwgMCA/IDAgOiB6O1xuICAgIHZhciB6MiA9IHogLyAyO1xuICAgIHZhciBuID0gMTI7XG4gICAgdmFyIFR2YWx1ZXMgPSBbLTAuMTI1MiwgMC4xMjUyLCAtMC4zNjc4LCAwLjM2NzgsIC0wLjU4NzMsIDAuNTg3MywgLTAuNzY5OSwgMC43Njk5LCAtMC45MDQxLCAwLjkwNDEsIC0wLjk4MTYsIDAuOTgxNl07XG4gICAgdmFyIEN2YWx1ZXMgPSBbMC4yNDkxLCAwLjI0OTEsIDAuMjMzNSwgMC4yMzM1LCAwLjIwMzIsIDAuMjAzMiwgMC4xNjAxLCAwLjE2MDEsIDAuMTA2OSwgMC4xMDY5LCAwLjA0NzIsIDAuMDQ3Ml07XG4gICAgdmFyIHN1bSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIGN0ID0gejIgKiBUdmFsdWVzW2ldICsgejI7XG4gICAgICAgIHZhciB4YmFzZSA9IGJhc2UzKGN0LCB4MSwgeDIsIHgzLCB4NCk7XG4gICAgICAgIHZhciB5YmFzZSA9IGJhc2UzKGN0LCB5MSwgeTIsIHkzLCB5NCk7XG4gICAgICAgIHZhciBjb21iID0geGJhc2UgKiB4YmFzZSArIHliYXNlICogeWJhc2U7XG4gICAgICAgIHN1bSArPSBDdmFsdWVzW2ldICogTWF0aC5zcXJ0KGNvbWIpO1xuICAgIH1cbiAgICByZXR1cm4gejIgKiBzdW07XG59O1xudmFyIGN1cnZlRGltID0gZnVuY3Rpb24gKHgwLCB5MCwgeDEsIHkxLCB4MiwgeTIsIHgzLCB5Mykge1xuICAgIHZhciB0dmFsdWVzID0gW107XG4gICAgdmFyIGJvdW5kcyA9IFtcbiAgICAgICAgW10sXG4gICAgICAgIFtdLFxuICAgIF07XG4gICAgdmFyIGE7XG4gICAgdmFyIGI7XG4gICAgdmFyIGM7XG4gICAgdmFyIHQ7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyOyArK2kpIHtcbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICAgIGIgPSA2ICogeDAgLSAxMiAqIHgxICsgNiAqIHgyO1xuICAgICAgICAgICAgYSA9IC0zICogeDAgKyA5ICogeDEgLSA5ICogeDIgKyAzICogeDM7XG4gICAgICAgICAgICBjID0gMyAqIHgxIC0gMyAqIHgwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYiA9IDYgKiB5MCAtIDEyICogeTEgKyA2ICogeTI7XG4gICAgICAgICAgICBhID0gLTMgKiB5MCArIDkgKiB5MSAtIDkgKiB5MiArIDMgKiB5MztcbiAgICAgICAgICAgIGMgPSAzICogeTEgLSAzICogeTA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKE1hdGguYWJzKGEpIDwgMWUtMTIpIHtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhiKSA8IDFlLTEyKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ID0gLWMgLyBiO1xuICAgICAgICAgICAgaWYgKHQgPiAwICYmIHQgPCAxKSB7XG4gICAgICAgICAgICAgICAgdHZhbHVlcy5wdXNoKHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGIyYWMgPSBiICogYiAtIDQgKiBjICogYTtcbiAgICAgICAgdmFyIHNxcnRiMmFjID0gTWF0aC5zcXJ0KGIyYWMpO1xuICAgICAgICBpZiAoYjJhYyA8IDApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0MSA9ICgtYiArIHNxcnRiMmFjKSAvICgyICogYSk7XG4gICAgICAgIGlmICh0MSA+IDAgJiYgdDEgPCAxKSB7XG4gICAgICAgICAgICB0dmFsdWVzLnB1c2godDEpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0MiA9ICgtYiAtIHNxcnRiMmFjKSAvICgyICogYSk7XG4gICAgICAgIGlmICh0MiA+IDAgJiYgdDIgPCAxKSB7XG4gICAgICAgICAgICB0dmFsdWVzLnB1c2godDIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZhciBqID0gdHZhbHVlcy5sZW5ndGg7XG4gICAgdmFyIGpsZW4gPSBqO1xuICAgIHZhciBtdDtcbiAgICB3aGlsZSAoai0tKSB7XG4gICAgICAgIHQgPSB0dmFsdWVzW2pdO1xuICAgICAgICBtdCA9IDEgLSB0O1xuICAgICAgICBib3VuZHNbMF1bal0gPSAobXQgKiBtdCAqIG10ICogeDApICsgKDMgKiBtdCAqIG10ICogdCAqIHgxKSArICgzICogbXQgKiB0ICogdCAqIHgyKSArICh0ICogdCAqIHQgKiB4Myk7XG4gICAgICAgIGJvdW5kc1sxXVtqXSA9IChtdCAqIG10ICogbXQgKiB5MCkgKyAoMyAqIG10ICogbXQgKiB0ICogeTEpICsgKDMgKiBtdCAqIHQgKiB0ICogeTIpICsgKHQgKiB0ICogdCAqIHkzKTtcbiAgICB9XG4gICAgYm91bmRzWzBdW2psZW5dID0geDA7XG4gICAgYm91bmRzWzFdW2psZW5dID0geTA7XG4gICAgYm91bmRzWzBdW2psZW4gKyAxXSA9IHgzO1xuICAgIGJvdW5kc1sxXVtqbGVuICsgMV0gPSB5MztcbiAgICBib3VuZHNbMF0ubGVuZ3RoID0gYm91bmRzWzFdLmxlbmd0aCA9IGpsZW4gKyAyO1xuICAgIHJldHVybiB7XG4gICAgICAgIG1pbjoge1xuICAgICAgICAgICAgeDogTWF0aC5taW4uYXBwbHkoMCwgYm91bmRzWzBdKSxcbiAgICAgICAgICAgIHk6IE1hdGgubWluLmFwcGx5KDAsIGJvdW5kc1sxXSksXG4gICAgICAgIH0sXG4gICAgICAgIG1heDoge1xuICAgICAgICAgICAgeDogTWF0aC5tYXguYXBwbHkoMCwgYm91bmRzWzBdKSxcbiAgICAgICAgICAgIHk6IE1hdGgubWF4LmFwcGx5KDAsIGJvdW5kc1sxXSksXG4gICAgICAgIH0sXG4gICAgfTtcbn07XG52YXIgaW50ZXJzZWN0ID0gZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCkge1xuICAgIGlmIChNYXRoLm1heCh4MSwgeDIpIDwgTWF0aC5taW4oeDMsIHg0KSB8fFxuICAgICAgICBNYXRoLm1pbih4MSwgeDIpID4gTWF0aC5tYXgoeDMsIHg0KSB8fFxuICAgICAgICBNYXRoLm1heCh5MSwgeTIpIDwgTWF0aC5taW4oeTMsIHk0KSB8fFxuICAgICAgICBNYXRoLm1pbih5MSwgeTIpID4gTWF0aC5tYXgoeTMsIHk0KSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBueCA9ICh4MSAqIHkyIC0geTEgKiB4MikgKiAoeDMgLSB4NCkgLSAoeDEgLSB4MikgKiAoeDMgKiB5NCAtIHkzICogeDQpO1xuICAgIHZhciBueSA9ICh4MSAqIHkyIC0geTEgKiB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgKiB5NCAtIHkzICogeDQpO1xuICAgIHZhciBkZW5vbWluYXRvciA9ICh4MSAtIHgyKSAqICh5MyAtIHk0KSAtICh5MSAtIHkyKSAqICh4MyAtIHg0KTtcbiAgICBpZiAoIWRlbm9taW5hdG9yKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHB4ID0gbnggLyBkZW5vbWluYXRvcjtcbiAgICB2YXIgcHkgPSBueSAvIGRlbm9taW5hdG9yO1xuICAgIHZhciBweDIgPSArcHgudG9GaXhlZCgyKTtcbiAgICB2YXIgcHkyID0gK3B5LnRvRml4ZWQoMik7XG4gICAgaWYgKHB4MiA8ICtNYXRoLm1pbih4MSwgeDIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHgyID4gK01hdGgubWF4KHgxLCB4MikudG9GaXhlZCgyKSB8fFxuICAgICAgICBweDIgPCArTWF0aC5taW4oeDMsIHg0KS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB4MiA+ICtNYXRoLm1heCh4MywgeDQpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHkyIDwgK01hdGgubWluKHkxLCB5MikudG9GaXhlZCgyKSB8fFxuICAgICAgICBweTIgPiArTWF0aC5tYXgoeTEsIHkyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgIHB5MiA8ICtNYXRoLm1pbih5MywgeTQpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgcHkyID4gK01hdGgubWF4KHkzLCB5NCkudG9GaXhlZCgyKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHB4LFxuICAgICAgICB5OiBweSxcbiAgICB9O1xufTtcbnZhciBpc1BvaW50SW5zaWRlQkJveCA9IGZ1bmN0aW9uIChiYm94LCB4LCB5KSB7XG4gICAgcmV0dXJuIHggPj0gYmJveC54ICYmXG4gICAgICAgIHggPD0gYmJveC54ICsgYmJveC53aWR0aCAmJlxuICAgICAgICB5ID49IGJib3gueSAmJlxuICAgICAgICB5IDw9IGJib3gueSArIGJib3guaGVpZ2h0O1xufTtcbnZhciBib3ggPSBmdW5jdGlvbiAoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuICAgIGlmICh4ID09PSBudWxsKSB7XG4gICAgICAgIHggPSB5ID0gd2lkdGggPSBoZWlnaHQgPSAwO1xuICAgIH1cbiAgICBpZiAoeSA9PT0gbnVsbCkge1xuICAgICAgICB5ID0geC55O1xuICAgICAgICB3aWR0aCA9IHgud2lkdGg7XG4gICAgICAgIGhlaWdodCA9IHguaGVpZ2h0O1xuICAgICAgICB4ID0geC54O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB4LFxuICAgICAgICB5OiB5LFxuICAgICAgICB3aWR0aDogd2lkdGgsXG4gICAgICAgIHc6IHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgaDogaGVpZ2h0LFxuICAgICAgICB4MjogeCArIHdpZHRoLFxuICAgICAgICB5MjogeSArIGhlaWdodCxcbiAgICAgICAgY3g6IHggKyB3aWR0aCAvIDIsXG4gICAgICAgIGN5OiB5ICsgaGVpZ2h0IC8gMixcbiAgICAgICAgcjE6IE1hdGgubWluKHdpZHRoLCBoZWlnaHQpIC8gMixcbiAgICAgICAgcjI6IE1hdGgubWF4KHdpZHRoLCBoZWlnaHQpIC8gMixcbiAgICAgICAgcjA6IE1hdGguc3FydCh3aWR0aCAqIHdpZHRoICsgaGVpZ2h0ICogaGVpZ2h0KSAvIDIsXG4gICAgICAgIHBhdGg6IHJlY3RQYXRoKHgsIHksIHdpZHRoLCBoZWlnaHQpLFxuICAgICAgICB2YjogW3gsIHksIHdpZHRoLCBoZWlnaHRdLmpvaW4oJyAnKSxcbiAgICB9O1xufTtcbnZhciBpc0JCb3hJbnRlcnNlY3QgPSBmdW5jdGlvbiAoYmJveDEsIGJib3gyKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGJib3gxID0gYm94KGJib3gxKTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgYmJveDIgPSBib3goYmJveDIpO1xuICAgIHJldHVybiBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueSkgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDIsIGJib3gxLngyLCBiYm94MS55KSB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueTIpIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55KSB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MSwgYmJveDIueDIsIGJib3gyLnkpIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55MikgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngyLCBiYm94Mi55MikgfHwgKGJib3gxLnggPCBiYm94Mi54MiAmJiBiYm94MS54ID4gYmJveDIueCB8fCBiYm94Mi54IDwgYmJveDEueDIgJiYgYmJveDIueCA+IGJib3gxLngpICYmIChiYm94MS55IDwgYmJveDIueTIgJiYgYmJveDEueSA+IGJib3gyLnkgfHwgYmJveDIueSA8IGJib3gxLnkyICYmIGJib3gyLnkgPiBiYm94MS55KTtcbn07XG52YXIgYmV6aWVyQkJveCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSkge1xuICAgIGlmICghaXNBcnJheShwMXgpKSB7XG4gICAgICAgIHAxeCA9IFtwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeV07XG4gICAgfVxuICAgIHZhciBiYm94ID0gY3VydmVEaW0uYXBwbHkobnVsbCwgcDF4KTtcbiAgICByZXR1cm4gYm94KGJib3gubWluLngsIGJib3gubWluLnksIGJib3gubWF4LnggLSBiYm94Lm1pbi54LCBiYm94Lm1heC55IC0gYmJveC5taW4ueSk7XG59O1xudmFyIGZpbmREb3RzQXRTZWdtZW50ID0gZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0KSB7XG4gICAgdmFyIHQxID0gMSAtIHQ7XG4gICAgdmFyIHQxMyA9IE1hdGgucG93KHQxLCAzKTtcbiAgICB2YXIgdDEyID0gTWF0aC5wb3codDEsIDIpO1xuICAgIHZhciB0MiA9IHQgKiB0O1xuICAgIHZhciB0MyA9IHQyICogdDtcbiAgICB2YXIgeCA9IHQxMyAqIHAxeCArIHQxMiAqIDMgKiB0ICogYzF4ICsgdDEgKiAzICogdCAqIHQgKiBjMnggKyB0MyAqIHAyeDtcbiAgICB2YXIgeSA9IHQxMyAqIHAxeSArIHQxMiAqIDMgKiB0ICogYzF5ICsgdDEgKiAzICogdCAqIHQgKiBjMnkgKyB0MyAqIHAyeTtcbiAgICB2YXIgbXggPSBwMXggKyAyICogdCAqIChjMXggLSBwMXgpICsgdDIgKiAoYzJ4IC0gMiAqIGMxeCArIHAxeCk7XG4gICAgdmFyIG15ID0gcDF5ICsgMiAqIHQgKiAoYzF5IC0gcDF5KSArIHQyICogKGMyeSAtIDIgKiBjMXkgKyBwMXkpO1xuICAgIHZhciBueCA9IGMxeCArIDIgKiB0ICogKGMyeCAtIGMxeCkgKyB0MiAqIChwMnggLSAyICogYzJ4ICsgYzF4KTtcbiAgICB2YXIgbnkgPSBjMXkgKyAyICogdCAqIChjMnkgLSBjMXkpICsgdDIgKiAocDJ5IC0gMiAqIGMyeSArIGMxeSk7XG4gICAgdmFyIGF4ID0gdDEgKiBwMXggKyB0ICogYzF4O1xuICAgIHZhciBheSA9IHQxICogcDF5ICsgdCAqIGMxeTtcbiAgICB2YXIgY3ggPSB0MSAqIGMyeCArIHQgKiBwMng7XG4gICAgdmFyIGN5ID0gdDEgKiBjMnkgKyB0ICogcDJ5O1xuICAgIHZhciBhbHBoYSA9ICg5MCAtIE1hdGguYXRhbjIobXggLSBueCwgbXkgLSBueSkgKiAxODAgLyBNYXRoLlBJKTtcbiAgICAvLyAobXggPiBueCB8fCBteSA8IG55KSAmJiAoYWxwaGEgKz0gMTgwKTtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB4LFxuICAgICAgICB5OiB5LFxuICAgICAgICBtOiB7XG4gICAgICAgICAgICB4OiBteCxcbiAgICAgICAgICAgIHk6IG15LFxuICAgICAgICB9LFxuICAgICAgICBuOiB7XG4gICAgICAgICAgICB4OiBueCxcbiAgICAgICAgICAgIHk6IG55LFxuICAgICAgICB9LFxuICAgICAgICBzdGFydDoge1xuICAgICAgICAgICAgeDogYXgsXG4gICAgICAgICAgICB5OiBheSxcbiAgICAgICAgfSxcbiAgICAgICAgZW5kOiB7XG4gICAgICAgICAgICB4OiBjeCxcbiAgICAgICAgICAgIHk6IGN5LFxuICAgICAgICB9LFxuICAgICAgICBhbHBoYTogYWxwaGEsXG4gICAgfTtcbn07XG52YXIgaW50ZXJIZWxwZXIgPSBmdW5jdGlvbiAoYmV6MSwgYmV6MiwganVzdENvdW50KSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHZhciBiYm94MSA9IGJlemllckJCb3goYmV6MSk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHZhciBiYm94MiA9IGJlemllckJCb3goYmV6Mik7XG4gICAgaWYgKCFpc0JCb3hJbnRlcnNlY3QoYmJveDEsIGJib3gyKSkge1xuICAgICAgICByZXR1cm4ganVzdENvdW50ID8gMCA6IFtdO1xuICAgIH1cbiAgICB2YXIgbDEgPSBiZXpsZW4uYXBwbHkoMCwgYmV6MSk7XG4gICAgdmFyIGwyID0gYmV6bGVuLmFwcGx5KDAsIGJlejIpO1xuICAgIHZhciBuMSA9IH5+KGwxIC8gOCk7XG4gICAgdmFyIG4yID0gfn4obDIgLyA4KTtcbiAgICB2YXIgZG90czEgPSBbXTtcbiAgICB2YXIgZG90czIgPSBbXTtcbiAgICB2YXIgeHkgPSB7fTtcbiAgICB2YXIgcmVzID0ganVzdENvdW50ID8gMCA6IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjEgKyAxOyBpKyspIHtcbiAgICAgICAgdmFyIGQgPSBmaW5kRG90c0F0U2VnbWVudC5hcHBseSgwLCBiZXoxLmNvbmNhdChpIC8gbjEpKTtcbiAgICAgICAgZG90czEucHVzaCh7XG4gICAgICAgICAgICB4OiBkLngsXG4gICAgICAgICAgICB5OiBkLnksXG4gICAgICAgICAgICB0OiBpIC8gbjEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4yICsgMTsgaSsrKSB7XG4gICAgICAgIHZhciBkID0gZmluZERvdHNBdFNlZ21lbnQuYXBwbHkoMCwgYmV6Mi5jb25jYXQoaSAvIG4yKSk7XG4gICAgICAgIGRvdHMyLnB1c2goe1xuICAgICAgICAgICAgeDogZC54LFxuICAgICAgICAgICAgeTogZC55LFxuICAgICAgICAgICAgdDogaSAvIG4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuMTsgaSsrKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbjI7IGorKykge1xuICAgICAgICAgICAgdmFyIGRpID0gZG90czFbaV07XG4gICAgICAgICAgICB2YXIgZGkxID0gZG90czFbaSArIDFdO1xuICAgICAgICAgICAgdmFyIGRqID0gZG90czJbal07XG4gICAgICAgICAgICB2YXIgZGoxID0gZG90czJbaiArIDFdO1xuICAgICAgICAgICAgdmFyIGNpID0gTWF0aC5hYnMoZGkxLnggLSBkaS54KSA8IDAuMDAxID8gJ3knIDogJ3gnO1xuICAgICAgICAgICAgdmFyIGNqID0gTWF0aC5hYnMoZGoxLnggLSBkai54KSA8IDAuMDAxID8gJ3knIDogJ3gnO1xuICAgICAgICAgICAgdmFyIGlzID0gaW50ZXJzZWN0KGRpLngsIGRpLnksIGRpMS54LCBkaTEueSwgZGoueCwgZGoueSwgZGoxLngsIGRqMS55KTtcbiAgICAgICAgICAgIGlmIChpcykge1xuICAgICAgICAgICAgICAgIGlmICh4eVtpcy54LnRvRml4ZWQoNCldID09PSBpcy55LnRvRml4ZWQoNCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHh5W2lzLngudG9GaXhlZCg0KV0gPSBpcy55LnRvRml4ZWQoNCk7XG4gICAgICAgICAgICAgICAgdmFyIHQxID0gZGkudCArIE1hdGguYWJzKChpc1tjaV0gLSBkaVtjaV0pIC8gKGRpMVtjaV0gLSBkaVtjaV0pKSAqIChkaTEudCAtIGRpLnQpO1xuICAgICAgICAgICAgICAgIHZhciB0MiA9IGRqLnQgKyBNYXRoLmFicygoaXNbY2pdIC0gZGpbY2pdKSAvIChkajFbY2pdIC0gZGpbY2pdKSkgKiAoZGoxLnQgLSBkai50KTtcbiAgICAgICAgICAgICAgICBpZiAodDEgPj0gMCAmJiB0MSA8PSAxICYmIHQyID49IDAgJiYgdDIgPD0gMSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoanVzdENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMrKztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpcy54LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGlzLnksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdDE6IHQxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQyOiB0MixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59O1xudmFyIGludGVyUGF0aEhlbHBlciA9IGZ1bmN0aW9uIChwYXRoMSwgcGF0aDIsIGp1c3RDb3VudCkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBwYXRoMSA9IHBhdGgyQ3VydmUocGF0aDEpO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBwYXRoMiA9IHBhdGgyQ3VydmUocGF0aDIpO1xuICAgIHZhciB4MTtcbiAgICB2YXIgeTE7XG4gICAgdmFyIHgyO1xuICAgIHZhciB5MjtcbiAgICB2YXIgeDFtO1xuICAgIHZhciB5MW07XG4gICAgdmFyIHgybTtcbiAgICB2YXIgeTJtO1xuICAgIHZhciBiZXoxO1xuICAgIHZhciBiZXoyO1xuICAgIHZhciByZXMgPSBqdXN0Q291bnQgPyAwIDogW107XG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcGF0aDEubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICB2YXIgcGkgPSBwYXRoMVtpXTtcbiAgICAgICAgaWYgKHBpWzBdID09PSAnTScpIHtcbiAgICAgICAgICAgIHgxID0geDFtID0gcGlbMV07XG4gICAgICAgICAgICB5MSA9IHkxbSA9IHBpWzJdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHBpWzBdID09PSAnQycpIHtcbiAgICAgICAgICAgICAgICBiZXoxID0gW3gxLCB5MV0uY29uY2F0KHBpLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICB4MSA9IGJlejFbNl07XG4gICAgICAgICAgICAgICAgeTEgPSBiZXoxWzddO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYmV6MSA9IFt4MSwgeTEsIHgxLCB5MSwgeDFtLCB5MW0sIHgxbSwgeTFtXTtcbiAgICAgICAgICAgICAgICB4MSA9IHgxbTtcbiAgICAgICAgICAgICAgICB5MSA9IHkxbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IHBhdGgyLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgcGogPSBwYXRoMltqXTtcbiAgICAgICAgICAgICAgICBpZiAocGpbMF0gPT09ICdNJykge1xuICAgICAgICAgICAgICAgICAgICB4MiA9IHgybSA9IHBqWzFdO1xuICAgICAgICAgICAgICAgICAgICB5MiA9IHkybSA9IHBqWzJdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBqWzBdID09PSAnQycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyXS5jb25jYXQocGouc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSBiZXoyWzZdO1xuICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSBiZXoyWzddO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYmV6MiA9IFt4MiwgeTIsIHgyLCB5MiwgeDJtLCB5Mm0sIHgybSwgeTJtXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHgyID0geDJtO1xuICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSB5Mm07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIGludHIgPSBpbnRlckhlbHBlcihiZXoxLCBiZXoyLCBqdXN0Q291bnQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoanVzdENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgKz0gaW50cjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IGludHIubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uc2VnbWVudDEgPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uc2VnbWVudDIgPSBqO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uYmV6MSA9IGJlejE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cltrXS5iZXoyID0gYmV6MjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoaW50cik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwYXRoSW50ZXJzZWN0aW9uKHBhdGgxLCBwYXRoMikge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gaW50ZXJQYXRoSGVscGVyKHBhdGgxLCBwYXRoMik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXRoLWludGVyc2VjdGlvbi5qcy5tYXAiLCJ2YXIgcDJzID0gLyw/KFthLXpdKSw/L2dpO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcGFyc2VQYXRoQXJyYXkocGF0aCkge1xuICAgIHJldHVybiBwYXRoLmpvaW4oJywnKS5yZXBsYWNlKHAycywgJyQxJyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXJzZS1wYXRoLWFycmF5LmpzLm1hcCIsImltcG9ydCB7IG1vZCwgdG9SYWRpYW4gfSBmcm9tICdAYW50di91dGlsJztcbi8vIOWQkemHj+mVv+W6plxuZnVuY3Rpb24gdk1hZyh2KSB7XG4gICAgcmV0dXJuIE1hdGguc3FydCh2WzBdICogdlswXSArIHZbMV0gKiB2WzFdKTtcbn1cbi8vIHUudi98dXx8dnzvvIzorqHnrpflpLnop5LnmoTkvZnlvKblgLxcbmZ1bmN0aW9uIHZSYXRpbyh1LCB2KSB7XG4gICAgLy8g5b2T5a2Y5Zyo5LiA5Liq5ZCR6YeP55qE6ZW/5bqm5Li6IDAg5pe277yM5aS56KeS5Lmf5Li6IDDvvIzljbPlpLnop5LnmoTkvZnlvKblgLzkuLogMVxuICAgIHJldHVybiB2TWFnKHUpICogdk1hZyh2KSA/ICh1WzBdICogdlswXSArIHVbMV0gKiB2WzFdKSAvICh2TWFnKHUpICogdk1hZyh2KSkgOiAxO1xufVxuLy8g5ZCR6YeP6KeS5bqmXG5mdW5jdGlvbiB2QW5nbGUodSwgdikge1xuICAgIHJldHVybiAodVswXSAqIHZbMV0gPCB1WzFdICogdlswXSA/IC0xIDogMSkgKiBNYXRoLmFjb3ModlJhdGlvKHUsIHYpKTtcbn1cbi8qKlxuICog5Yik5pat5Lik5Liq54K55piv5ZCm6YeN5ZCI77yM54K55Z2Q5qCH55qE5qC85byP5Li6IFt4LCB5XVxuICogQHBhcmFtIHtBcnJheX0gcG9pbnQxIOesrOS4gOS4queCuVxuICogQHBhcmFtIHtBcnJheX0gcG9pbnQyIOesrOS6jOS4queCuVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTYW1lUG9pbnQocG9pbnQxLCBwb2ludDIpIHtcbiAgICByZXR1cm4gcG9pbnQxWzBdID09PSBwb2ludDJbMF0gJiYgcG9pbnQxWzFdID09PSBwb2ludDJbMV07XG59XG4vLyBBIDA6cnggMTpyeSAyOngtYXhpcy1yb3RhdGlvbiAzOmxhcmdlLWFyYy1mbGFnIDQ6c3dlZXAtZmxhZyA1OiB4IDY6IHlcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFyY1BhcmFtcyhzdGFydFBvaW50LCBwYXJhbXMpIHtcbiAgICB2YXIgcnggPSBwYXJhbXNbMV07XG4gICAgdmFyIHJ5ID0gcGFyYW1zWzJdO1xuICAgIHZhciB4Um90YXRpb24gPSBtb2QodG9SYWRpYW4ocGFyYW1zWzNdKSwgTWF0aC5QSSAqIDIpO1xuICAgIHZhciBhcmNGbGFnID0gcGFyYW1zWzRdO1xuICAgIHZhciBzd2VlcEZsYWcgPSBwYXJhbXNbNV07XG4gICAgLy8g5byn5b2i6LW354K55Z2Q5qCHXG4gICAgdmFyIHgxID0gc3RhcnRQb2ludFswXTtcbiAgICB2YXIgeTEgPSBzdGFydFBvaW50WzFdO1xuICAgIC8vIOW8p+W9oue7iOeCueWdkOagh1xuICAgIHZhciB4MiA9IHBhcmFtc1s2XTtcbiAgICB2YXIgeTIgPSBwYXJhbXNbN107XG4gICAgdmFyIHhwID0gKE1hdGguY29zKHhSb3RhdGlvbikgKiAoeDEgLSB4MikpIC8gMi4wICsgKE1hdGguc2luKHhSb3RhdGlvbikgKiAoeTEgLSB5MikpIC8gMi4wO1xuICAgIHZhciB5cCA9ICgtMSAqIE1hdGguc2luKHhSb3RhdGlvbikgKiAoeDEgLSB4MikpIC8gMi4wICsgKE1hdGguY29zKHhSb3RhdGlvbikgKiAoeTEgLSB5MikpIC8gMi4wO1xuICAgIHZhciBsYW1iZGEgPSAoeHAgKiB4cCkgLyAocnggKiByeCkgKyAoeXAgKiB5cCkgLyAocnkgKiByeSk7XG4gICAgaWYgKGxhbWJkYSA+IDEpIHtcbiAgICAgICAgcnggKj0gTWF0aC5zcXJ0KGxhbWJkYSk7XG4gICAgICAgIHJ5ICo9IE1hdGguc3FydChsYW1iZGEpO1xuICAgIH1cbiAgICB2YXIgZGlmZiA9IHJ4ICogcnggKiAoeXAgKiB5cCkgKyByeSAqIHJ5ICogKHhwICogeHApO1xuICAgIHZhciBmID0gZGlmZiA/IE1hdGguc3FydCgocnggKiByeCAqIChyeSAqIHJ5KSAtIGRpZmYpIC8gZGlmZikgOiAxO1xuICAgIGlmIChhcmNGbGFnID09PSBzd2VlcEZsYWcpIHtcbiAgICAgICAgZiAqPSAtMTtcbiAgICB9XG4gICAgaWYgKGlzTmFOKGYpKSB7XG4gICAgICAgIGYgPSAwO1xuICAgIH1cbiAgICAvLyDml4vovazliY3nmoTotbfngrnlnZDmoIfvvIzkuJTlvZPplb/ljYrovbTlkoznn63ljYrovbTnmoTplb/luqbkuLogMCDml7bvvIzlnZDmoIfmjIkgKDAsIDApIOWkhOeQhlxuICAgIHZhciBjeHAgPSByeSA/IChmICogcnggKiB5cCkgLyByeSA6IDA7XG4gICAgdmFyIGN5cCA9IHJ4ID8gKGYgKiAtcnkgKiB4cCkgLyByeCA6IDA7XG4gICAgLy8g5qSt5ZyG5ZyG5b+D5Z2Q5qCHXG4gICAgdmFyIGN4ID0gKHgxICsgeDIpIC8gMi4wICsgTWF0aC5jb3MoeFJvdGF0aW9uKSAqIGN4cCAtIE1hdGguc2luKHhSb3RhdGlvbikgKiBjeXA7XG4gICAgdmFyIGN5ID0gKHkxICsgeTIpIC8gMi4wICsgTWF0aC5zaW4oeFJvdGF0aW9uKSAqIGN4cCArIE1hdGguY29zKHhSb3RhdGlvbikgKiBjeXA7XG4gICAgLy8g6LW35aeL54K555qE5Y2V5L2N5ZCR6YePXG4gICAgdmFyIHUgPSBbKHhwIC0gY3hwKSAvIHJ4LCAoeXAgLSBjeXApIC8gcnldO1xuICAgIC8vIOe7iOatoueCueeahOWNleS9jeWQkemHj1xuICAgIHZhciB2ID0gWygtMSAqIHhwIC0gY3hwKSAvIHJ4LCAoLTEgKiB5cCAtIGN5cCkgLyByeV07XG4gICAgLy8g6K6h566X6LW35aeL54K55ZKM5ZyG5b+D55qE6L+e57q/77yM5LiOIHgg6L205q2j5pa55ZCR55qE5aS56KeSXG4gICAgdmFyIHRoZXRhID0gdkFuZ2xlKFsxLCAwXSwgdSk7XG4gICAgLy8g6K6h566X5ZyG5byn6LW35aeL54K55ZKM57uI5q2i54K55LiO5qSt5ZyG5ZyG5b+D6L+e57q/55qE5aS56KeSXG4gICAgdmFyIGRUaGV0YSA9IHZBbmdsZSh1LCB2KTtcbiAgICBpZiAodlJhdGlvKHUsIHYpIDw9IC0xKSB7XG4gICAgICAgIGRUaGV0YSA9IE1hdGguUEk7XG4gICAgfVxuICAgIGlmICh2UmF0aW8odSwgdikgPj0gMSkge1xuICAgICAgICBkVGhldGEgPSAwO1xuICAgIH1cbiAgICBpZiAoc3dlZXBGbGFnID09PSAwICYmIGRUaGV0YSA+IDApIHtcbiAgICAgICAgZFRoZXRhID0gZFRoZXRhIC0gMiAqIE1hdGguUEk7XG4gICAgfVxuICAgIGlmIChzd2VlcEZsYWcgPT09IDEgJiYgZFRoZXRhIDwgMCkge1xuICAgICAgICBkVGhldGEgPSBkVGhldGEgKyAyICogTWF0aC5QSTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY3g6IGN4LFxuICAgICAgICBjeTogY3ksXG4gICAgICAgIC8vIOW8p+W9oueahOi1t+eCueWSjOe7iOeCueebuOWQjOaXtu+8jOmVv+i9tOWSjOefrei9tOeahOmVv+W6puaMiSAwIOWkhOeQhlxuICAgICAgICByeDogaXNTYW1lUG9pbnQoc3RhcnRQb2ludCwgW3gyLCB5Ml0pID8gMCA6IHJ4LFxuICAgICAgICByeTogaXNTYW1lUG9pbnQoc3RhcnRQb2ludCwgW3gyLCB5Ml0pID8gMCA6IHJ5LFxuICAgICAgICBzdGFydEFuZ2xlOiB0aGV0YSxcbiAgICAgICAgZW5kQW5nbGU6IHRoZXRhICsgZFRoZXRhLFxuICAgICAgICB4Um90YXRpb246IHhSb3RhdGlvbixcbiAgICAgICAgYXJjRmxhZzogYXJjRmxhZyxcbiAgICAgICAgc3dlZXBGbGFnOiBzd2VlcEZsYWcsXG4gICAgfTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hcmMtcGFyYW1zLmpzLm1hcCIsImltcG9ydCBnZXRBcmNQYXJhbXMgZnJvbSAnLi9nZXQtYXJjLXBhcmFtcyc7XG5pbXBvcnQgeyBpc1NhbWVQb2ludCB9IGZyb20gJy4vZ2V0LWFyYy1wYXJhbXMnO1xuaW1wb3J0IHBhcnNlUGF0aCBmcm9tICcuL3BhcnNlLXBhdGgnO1xuLy8g54K55a+556ewXG5mdW5jdGlvbiB0b1N5bW1ldHJ5KHBvaW50LCBjZW50ZXIpIHtcbiAgICByZXR1cm4gW2NlbnRlclswXSArIChjZW50ZXJbMF0gLSBwb2ludFswXSksIGNlbnRlclsxXSArIChjZW50ZXJbMV0gLSBwb2ludFsxXSldO1xufVxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0U2VnbWVudHMocGF0aCkge1xuICAgIHBhdGggPSBwYXJzZVBhdGgocGF0aCk7XG4gICAgdmFyIHNlZ21lbnRzID0gW107XG4gICAgdmFyIGN1cnJlbnRQb2ludCA9IG51bGw7IC8vIOW9k+WJjeWbvuW9olxuICAgIHZhciBuZXh0UGFyYW1zID0gbnVsbDsgLy8g5LiL5LiA6IqC54K555qEIHBhdGgg5Y+C5pWwXG4gICAgdmFyIHN0YXJ0TW92ZVBvaW50ID0gbnVsbDsgLy8g5byA5aeLIE0g55qE54K577yM5Y+v6IO95Lya5pyJ5aSa5LiqXG4gICAgdmFyIGxhc3RTdGFydE1vdmVQb2ludEluZGV4ID0gMDsgLy8g5pyA6L+R5LiA5Liq5byA5aeL54K5IE0g55qE57Si5byVXG4gICAgdmFyIGNvdW50ID0gcGF0aC5sZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgIHZhciBwYXJhbXMgPSBwYXRoW2ldO1xuICAgICAgICBuZXh0UGFyYW1zID0gcGF0aFtpICsgMV07XG4gICAgICAgIHZhciBjb21tYW5kID0gcGFyYW1zWzBdO1xuICAgICAgICAvLyDmlbDlrablrprkuYnkuIrnmoTlj4LmlbDvvIzkvr/kuo7lkI7pnaLnmoTorqHnrpdcbiAgICAgICAgdmFyIHNlZ21lbnQgPSB7XG4gICAgICAgICAgICBjb21tYW5kOiBjb21tYW5kLFxuICAgICAgICAgICAgcHJlUG9pbnQ6IGN1cnJlbnRQb2ludCxcbiAgICAgICAgICAgIHBhcmFtczogcGFyYW1zLFxuICAgICAgICAgICAgc3RhcnRUYW5nZW50OiBudWxsLFxuICAgICAgICAgICAgZW5kVGFuZ2VudDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgc3dpdGNoIChjb21tYW5kKSB7XG4gICAgICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICAgICAgICBzdGFydE1vdmVQb2ludCA9IFtwYXJhbXNbMV0sIHBhcmFtc1syXV07XG4gICAgICAgICAgICAgICAgbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXggPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICAgICAgdmFyIGFyY1BhcmFtcyA9IGdldEFyY1BhcmFtcyhjdXJyZW50UG9pbnQsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgc2VnbWVudFsnYXJjUGFyYW1zJ10gPSBhcmNQYXJhbXM7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb21tYW5kID09PSAnWicpIHtcbiAgICAgICAgICAgIC8vIOacieS6hiBaIOWQju+8jOW9k+WJjeiKgueCueS7juW8gOWniyBNIOeahOeCueW8gOWni1xuICAgICAgICAgICAgY3VycmVudFBvaW50ID0gc3RhcnRNb3ZlUG9pbnQ7XG4gICAgICAgICAgICAvLyDlpoLmnpzlvZPliY3ngrnnmoTlkb3ku6TkuLogWu+8jOebuOW9k+S6juW9k+WJjeeCueS4uuacgOi/keS4gOS4qiBNIOeCue+8jOWImeS4i+S4gOS4queCueebtOaOpeaMh+WQkeacgOi/keS4gOS4qiBNIOeCueeahOS4i+S4gOS4queCuVxuICAgICAgICAgICAgbmV4dFBhcmFtcyA9IHBhdGhbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXggKyAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBsZW4gPSBwYXJhbXMubGVuZ3RoO1xuICAgICAgICAgICAgY3VycmVudFBvaW50ID0gW3BhcmFtc1tsZW4gLSAyXSwgcGFyYW1zW2xlbiAtIDFdXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV4dFBhcmFtcyAmJiBuZXh0UGFyYW1zWzBdID09PSAnWicpIHtcbiAgICAgICAgICAgIC8vIOWmguaenOS4i+S4gOS4queCueeahOWRveS7pOS4uiBa77yM5YiZ5LiL5LiA5Liq54K555u05o6l5oyH5ZCR5pyA6L+R5LiA5LiqIE0g54K5XG4gICAgICAgICAgICBuZXh0UGFyYW1zID0gcGF0aFtsYXN0U3RhcnRNb3ZlUG9pbnRJbmRleF07XG4gICAgICAgICAgICBpZiAoc2VnbWVudHNbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgLy8g5aaC5p6c5LiL5LiA5Liq54K555qE5ZG95Luk5Li6IFrvvIzliJnmnIDov5HkuIDkuKogTSDngrnnmoTliY3kuIDkuKrngrnkuLrlvZPliY3ngrlcbiAgICAgICAgICAgICAgICBzZWdtZW50c1tsYXN0U3RhcnRNb3ZlUG9pbnRJbmRleF0ucHJlUG9pbnQgPSBjdXJyZW50UG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2VnbWVudFsnY3VycmVudFBvaW50J10gPSBjdXJyZW50UG9pbnQ7XG4gICAgICAgIC8vIOWmguaenOW9k+WJjeeCueS4juacgOi/keS4gOS4qiBNIOeCueebuOWQjO+8jOWImeacgOi/keS4gOS4qiBNIOeCueeahOWJjeS4gOS4queCueS4uuW9k+WJjeeCueeahOWJjeS4gOS4queCuVxuICAgICAgICBpZiAoc2VnbWVudHNbbGFzdFN0YXJ0TW92ZVBvaW50SW5kZXhdICYmXG4gICAgICAgICAgICBpc1NhbWVQb2ludChjdXJyZW50UG9pbnQsIHNlZ21lbnRzW2xhc3RTdGFydE1vdmVQb2ludEluZGV4XS5jdXJyZW50UG9pbnQpKSB7XG4gICAgICAgICAgICBzZWdtZW50c1tsYXN0U3RhcnRNb3ZlUG9pbnRJbmRleF0ucHJlUG9pbnQgPSBzZWdtZW50LnByZVBvaW50O1xuICAgICAgICB9XG4gICAgICAgIHZhciBuZXh0UG9pbnQgPSBuZXh0UGFyYW1zID8gW25leHRQYXJhbXNbbmV4dFBhcmFtcy5sZW5ndGggLSAyXSwgbmV4dFBhcmFtc1tuZXh0UGFyYW1zLmxlbmd0aCAtIDFdXSA6IG51bGw7XG4gICAgICAgIHNlZ21lbnRbJ25leHRQb2ludCddID0gbmV4dFBvaW50O1xuICAgICAgICAvLyBBZGQgc3RhcnRUYW5nZW50IGFuZCBlbmRUYW5nZW50XG4gICAgICAgIHZhciBwcmVQb2ludCA9IHNlZ21lbnQucHJlUG9pbnQ7XG4gICAgICAgIGlmIChbJ0wnLCAnSCcsICdWJ10uaW5jbHVkZXMoY29tbWFuZCkpIHtcbiAgICAgICAgICAgIHNlZ21lbnQuc3RhcnRUYW5nZW50ID0gW3ByZVBvaW50WzBdIC0gY3VycmVudFBvaW50WzBdLCBwcmVQb2ludFsxXSAtIGN1cnJlbnRQb2ludFsxXV07XG4gICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gcHJlUG9pbnRbMF0sIGN1cnJlbnRQb2ludFsxXSAtIHByZVBvaW50WzFdXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb21tYW5kID09PSAnUScpIHtcbiAgICAgICAgICAgIC8vIOS6jOasoei0neWhnuWwlOabsue6v+WPquacieS4gOS4quaOp+WItueCuVxuICAgICAgICAgICAgdmFyIGNwID0gW3BhcmFtc1sxXSwgcGFyYW1zWzJdXTtcbiAgICAgICAgICAgIC8vIOS6jOasoei0neWhnuWwlOabsue6v+eahOe7iOeCueS4uiBjdXJyZW50UG9pbnRcbiAgICAgICAgICAgIHNlZ21lbnQuc3RhcnRUYW5nZW50ID0gW3ByZVBvaW50WzBdIC0gY3BbMF0sIHByZVBvaW50WzFdIC0gY3BbMV1dO1xuICAgICAgICAgICAgc2VnbWVudC5lbmRUYW5nZW50ID0gW2N1cnJlbnRQb2ludFswXSAtIGNwWzBdLCBjdXJyZW50UG9pbnRbMV0gLSBjcFsxXV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29tbWFuZCA9PT0gJ1QnKSB7XG4gICAgICAgICAgICB2YXIgcHJlU2VnbWVudCA9IHNlZ21lbnRzW2kgLSAxXTtcbiAgICAgICAgICAgIHZhciBjcCA9IHRvU3ltbWV0cnkocHJlU2VnbWVudC5jdXJyZW50UG9pbnQsIHByZVBvaW50KTtcbiAgICAgICAgICAgIGlmIChwcmVTZWdtZW50LmNvbW1hbmQgPT09ICdRJykge1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuY29tbWFuZCA9ICdRJztcbiAgICAgICAgICAgICAgICBzZWdtZW50LnN0YXJ0VGFuZ2VudCA9IFtwcmVQb2ludFswXSAtIGNwWzBdLCBwcmVQb2ludFsxXSAtIGNwWzFdXTtcbiAgICAgICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gY3BbMF0sIGN1cnJlbnRQb2ludFsxXSAtIGNwWzFdXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuY29tbWFuZCA9ICdUTCc7XG4gICAgICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBjdXJyZW50UG9pbnRbMF0sIHByZVBvaW50WzFdIC0gY3VycmVudFBvaW50WzFdXTtcbiAgICAgICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gcHJlUG9pbnRbMF0sIGN1cnJlbnRQb2ludFsxXSAtIHByZVBvaW50WzFdXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb21tYW5kID09PSAnQycpIHtcbiAgICAgICAgICAgIC8vIOS4ieasoei0neWhnuWwlOabsue6v+acieS4pOS4quaOp+WItueCuVxuICAgICAgICAgICAgdmFyIGNwMSA9IFtwYXJhbXNbMV0sIHBhcmFtc1syXV07XG4gICAgICAgICAgICB2YXIgY3AyID0gW3BhcmFtc1szXSwgcGFyYW1zWzRdXTtcbiAgICAgICAgICAgIHNlZ21lbnQuc3RhcnRUYW5nZW50ID0gW3ByZVBvaW50WzBdIC0gY3AxWzBdLCBwcmVQb2ludFsxXSAtIGNwMVsxXV07XG4gICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gY3AyWzBdLCBjdXJyZW50UG9pbnRbMV0gLSBjcDJbMV1dO1xuICAgICAgICAgICAgLy8gaG9yaXpvbnRhbCBsaW5lLCBlZy4gWydDJywgMTAwLCAxMDAsIDEwMCwgMTAwLCAyMDAsIDIwMF1cbiAgICAgICAgICAgIGlmIChzZWdtZW50LnN0YXJ0VGFuZ2VudFswXSA9PT0gMCAmJiBzZWdtZW50LnN0YXJ0VGFuZ2VudFsxXSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuc3RhcnRUYW5nZW50ID0gW2NwMVswXSAtIGNwMlswXSwgY3AxWzFdIC0gY3AyWzFdXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZWdtZW50LmVuZFRhbmdlbnRbMF0gPT09IDAgJiYgc2VnbWVudC5lbmRUYW5nZW50WzFdID09PSAwKSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudC5lbmRUYW5nZW50ID0gW2NwMlswXSAtIGNwMVswXSwgY3AyWzFdIC0gY3AxWzFdXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjb21tYW5kID09PSAnUycpIHtcbiAgICAgICAgICAgIHZhciBwcmVTZWdtZW50ID0gc2VnbWVudHNbaSAtIDFdO1xuICAgICAgICAgICAgdmFyIGNwMSA9IHRvU3ltbWV0cnkocHJlU2VnbWVudC5jdXJyZW50UG9pbnQsIHByZVBvaW50KTtcbiAgICAgICAgICAgIHZhciBjcDIgPSBbcGFyYW1zWzFdLCBwYXJhbXNbMl1dO1xuICAgICAgICAgICAgaWYgKHByZVNlZ21lbnQuY29tbWFuZCA9PT0gJ0MnKSB7XG4gICAgICAgICAgICAgICAgc2VnbWVudC5jb21tYW5kID0gJ0MnOyAvLyDlsIYgUyDlkb3ku6Tlj5jmjaLkuLogQyDlkb3ku6RcbiAgICAgICAgICAgICAgICBzZWdtZW50LnN0YXJ0VGFuZ2VudCA9IFtwcmVQb2ludFswXSAtIGNwMVswXSwgcHJlUG9pbnRbMV0gLSBjcDFbMV1dO1xuICAgICAgICAgICAgICAgIHNlZ21lbnQuZW5kVGFuZ2VudCA9IFtjdXJyZW50UG9pbnRbMF0gLSBjcDJbMF0sIGN1cnJlbnRQb2ludFsxXSAtIGNwMlsxXV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZWdtZW50LmNvbW1hbmQgPSAnU1EnOyAvLyDlsIYgUyDlkb3ku6Tlj5jmjaLkuLogU1Eg5ZG95LukXG4gICAgICAgICAgICAgICAgc2VnbWVudC5zdGFydFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBjcDJbMF0sIHByZVBvaW50WzFdIC0gY3AyWzFdXTtcbiAgICAgICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbY3VycmVudFBvaW50WzBdIC0gY3AyWzBdLCBjdXJyZW50UG9pbnRbMV0gLSBjcDJbMV1dO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbW1hbmQgPT09ICdBJykge1xuICAgICAgICAgICAgdmFyIGQgPSAwLjAwMTtcbiAgICAgICAgICAgIHZhciBfYSA9IHNlZ21lbnRbJ2FyY1BhcmFtcyddIHx8IHt9LCBfYiA9IF9hLmN4LCBjeCA9IF9iID09PSB2b2lkIDAgPyAwIDogX2IsIF9jID0gX2EuY3ksIGN5ID0gX2MgPT09IHZvaWQgMCA/IDAgOiBfYywgX2QgPSBfYS5yeCwgcnggPSBfZCA9PT0gdm9pZCAwID8gMCA6IF9kLCBfZSA9IF9hLnJ5LCByeSA9IF9lID09PSB2b2lkIDAgPyAwIDogX2UsIF9mID0gX2Euc3dlZXBGbGFnLCBzd2VlcEZsYWcgPSBfZiA9PT0gdm9pZCAwID8gMCA6IF9mLCBfZyA9IF9hLnN0YXJ0QW5nbGUsIHN0YXJ0QW5nbGUgPSBfZyA9PT0gdm9pZCAwID8gMCA6IF9nLCBfaCA9IF9hLmVuZEFuZ2xlLCBlbmRBbmdsZSA9IF9oID09PSB2b2lkIDAgPyAwIDogX2g7XG4gICAgICAgICAgICBpZiAoc3dlZXBGbGFnID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZCAqPSAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBkeDEgPSByeCAqIE1hdGguY29zKHN0YXJ0QW5nbGUgLSBkKSArIGN4O1xuICAgICAgICAgICAgdmFyIGR5MSA9IHJ5ICogTWF0aC5zaW4oc3RhcnRBbmdsZSAtIGQpICsgY3k7XG4gICAgICAgICAgICBzZWdtZW50LnN0YXJ0VGFuZ2VudCA9IFtkeDEgLSBzdGFydE1vdmVQb2ludFswXSwgZHkxIC0gc3RhcnRNb3ZlUG9pbnRbMV1dO1xuICAgICAgICAgICAgdmFyIGR4MiA9IHJ4ICogTWF0aC5jb3Moc3RhcnRBbmdsZSArIGVuZEFuZ2xlICsgZCkgKyBjeDtcbiAgICAgICAgICAgIHZhciBkeTIgPSByeSAqIE1hdGguc2luKHN0YXJ0QW5nbGUgKyBlbmRBbmdsZSAtIGQpICsgY3k7XG4gICAgICAgICAgICBzZWdtZW50LmVuZFRhbmdlbnQgPSBbcHJlUG9pbnRbMF0gLSBkeDIsIHByZVBvaW50WzFdIC0gZHkyXTtcbiAgICAgICAgfVxuICAgICAgICBzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gc2VnbWVudHM7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYXRoLTItc2VnbWVudHMuanMubWFwIiwidmFyIGlzQmV0d2VlbiA9IGZ1bmN0aW9uICh2YWx1ZSwgbWluLCBtYXgpIHsgcmV0dXJuIHZhbHVlID49IG1pbiAmJiB2YWx1ZSA8PSBtYXg7IH07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRMaW5lSW50ZXJzZWN0KHAwLCBwMSwgcDIsIHAzKSB7XG4gICAgdmFyIHRvbGVyYW5jZSA9IDAuMDAxO1xuICAgIHZhciBFID0ge1xuICAgICAgICB4OiBwMi54IC0gcDAueCxcbiAgICAgICAgeTogcDIueSAtIHAwLnksXG4gICAgfTtcbiAgICB2YXIgRDAgPSB7XG4gICAgICAgIHg6IHAxLnggLSBwMC54LFxuICAgICAgICB5OiBwMS55IC0gcDAueSxcbiAgICB9O1xuICAgIHZhciBEMSA9IHtcbiAgICAgICAgeDogcDMueCAtIHAyLngsXG4gICAgICAgIHk6IHAzLnkgLSBwMi55LFxuICAgIH07XG4gICAgdmFyIGtyb3NzID0gRDAueCAqIEQxLnkgLSBEMC55ICogRDEueDtcbiAgICB2YXIgc3FyS3Jvc3MgPSBrcm9zcyAqIGtyb3NzO1xuICAgIHZhciBzcXJMZW4wID0gRDAueCAqIEQwLnggKyBEMC55ICogRDAueTtcbiAgICB2YXIgc3FyTGVuMSA9IEQxLnggKiBEMS54ICsgRDEueSAqIEQxLnk7XG4gICAgdmFyIHBvaW50ID0gbnVsbDtcbiAgICBpZiAoc3FyS3Jvc3MgPiB0b2xlcmFuY2UgKiBzcXJMZW4wICogc3FyTGVuMSkge1xuICAgICAgICB2YXIgcyA9IChFLnggKiBEMS55IC0gRS55ICogRDEueCkgLyBrcm9zcztcbiAgICAgICAgdmFyIHQgPSAoRS54ICogRDAueSAtIEUueSAqIEQwLngpIC8ga3Jvc3M7XG4gICAgICAgIGlmIChpc0JldHdlZW4ocywgMCwgMSkgJiYgaXNCZXR3ZWVuKHQsIDAsIDEpKSB7XG4gICAgICAgICAgICBwb2ludCA9IHtcbiAgICAgICAgICAgICAgICB4OiBwMC54ICsgcyAqIEQwLngsXG4gICAgICAgICAgICAgICAgeTogcDAueSArIHMgKiBEMC55LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcG9pbnQ7XG59XG47XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbGluZS1pbnRlcnNlY3QuanMubWFwIiwiLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IOWIpOaWreeCueaYr+WQpuWcqOWkmui+ueW9ouWGhVxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbi8vIOWkmui+ueW9oueahOWwhOe6v+ajgOa1i++8jOWPguiAg++8mmh0dHBzOi8vYmxvZy5jc2RuLm5ldC9XaWxsaWFtU3VuMDEyMi9hcnRpY2xlL2RldGFpbHMvNzc5OTQ1MjZcbnZhciB0b2xlcmFuY2UgPSAxZS02O1xuLy8g5LiJ5oCB5Ye95pWw77yM5Yik5pat5Lik5LiqZG91Ymxl5ZyoZXBz57K+5bqm5LiL55qE5aSn5bCP5YWz57O7XG5mdW5jdGlvbiBkY21wKHgpIHtcbiAgICBpZiAoTWF0aC5hYnMoeCkgPCB0b2xlcmFuY2UpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiB4IDwgMCA/IC0xIDogMTtcbn1cbi8vIOWIpOaWreeCuVHmmK/lkKblnKhwMeWSjHAy55qE57q/5q615LiKXG5mdW5jdGlvbiBvblNlZ21lbnQocDEsIHAyLCBxKSB7XG4gICAgaWYgKChxWzBdIC0gcDFbMF0pICogKHAyWzFdIC0gcDFbMV0pID09PSAocDJbMF0gLSBwMVswXSkgKiAocVsxXSAtIHAxWzFdKSAmJlxuICAgICAgICBNYXRoLm1pbihwMVswXSwgcDJbMF0pIDw9IHFbMF0gJiZcbiAgICAgICAgcVswXSA8PSBNYXRoLm1heChwMVswXSwgcDJbMF0pICYmXG4gICAgICAgIE1hdGgubWluKHAxWzFdLCBwMlsxXSkgPD0gcVsxXSAmJlxuICAgICAgICBxWzFdIDw9IE1hdGgubWF4KHAxWzFdLCBwMlsxXSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8vIOWIpOaWreeCuVDlnKjlpJrovrnlvaLlhoUt5bCE57q/5rOVXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0luUG9seWdvbihwb2ludHMsIHgsIHkpIHtcbiAgICB2YXIgaXNIaXQgPSBmYWxzZTtcbiAgICB2YXIgbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgaWYgKG4gPD0gMikge1xuICAgICAgICAvLyBzdmcg5Lit54K55bCP5LqOIDMg5Liq5pe277yM5LiN5pi+56S677yM5Lmf5peg5rOV6KKr5ou+5Y+WXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgdmFyIHAxID0gcG9pbnRzW2ldO1xuICAgICAgICB2YXIgcDIgPSBwb2ludHNbKGkgKyAxKSAlIG5dO1xuICAgICAgICBpZiAob25TZWdtZW50KHAxLCBwMiwgW3gsIHldKSkge1xuICAgICAgICAgICAgLy8g54K55Zyo5aSa6L655b2i5LiA5p2h6L655LiKXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyDliY3kuIDkuKrliKTmlq1taW4ocDFbMV0scDJbMV0pPFAueTw9bWF4KHAxWzFdLHAyWzFdKVxuICAgICAgICAvLyDlkI7kuIDkuKrliKTmlq3ooqvmtYvngrkg5ZyoIOWwhOe6v+S4jui+ueS6pOeCuSDnmoTlt6bovrlcbiAgICAgICAgaWYgKGRjbXAocDFbMV0gLSB5KSA+IDAgIT09IGRjbXAocDJbMV0gLSB5KSA+IDAgJiZcbiAgICAgICAgICAgIGRjbXAoeCAtICgoeSAtIHAxWzFdKSAqIChwMVswXSAtIHAyWzBdKSkgLyAocDFbMV0gLSBwMlsxXSkgLSBwMVswXSkgPCAwKSB7XG4gICAgICAgICAgICBpc0hpdCA9ICFpc0hpdDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNIaXQ7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wb2ludC1pbi1wb2x5Z29uLmpzLm1hcCIsImltcG9ydCBpc1BvaW50SW5Qb2x5Z29uIGZyb20gJy4vcG9pbnQtaW4tcG9seWdvbic7XG5pbXBvcnQgZ2V0TGluZUludGVyc2VjdCBmcm9tICcuL2dldC1saW5lLWludGVyc2VjdCc7XG5pbXBvcnQgeyBlYWNoIH0gZnJvbSAnQGFudHYvdXRpbCc7XG5mdW5jdGlvbiBwYXJzZVRvTGluZXMocG9pbnRzKSB7XG4gICAgdmFyIGxpbmVzID0gW107XG4gICAgdmFyIGNvdW50ID0gcG9pbnRzLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50IC0gMTsgaSsrKSB7XG4gICAgICAgIHZhciBwb2ludCA9IHBvaW50c1tpXTtcbiAgICAgICAgdmFyIG5leHQgPSBwb2ludHNbaSArIDFdO1xuICAgICAgICBsaW5lcy5wdXNoKHtcbiAgICAgICAgICAgIGZyb206IHtcbiAgICAgICAgICAgICAgICB4OiBwb2ludFswXSxcbiAgICAgICAgICAgICAgICB5OiBwb2ludFsxXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRvOiB7XG4gICAgICAgICAgICAgICAgeDogbmV4dFswXSxcbiAgICAgICAgICAgICAgICB5OiBuZXh0WzFdXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAobGluZXMubGVuZ3RoID4gMSkge1xuICAgICAgICB2YXIgZmlyc3QgPSBwb2ludHNbMF07XG4gICAgICAgIHZhciBsYXN0ID0gcG9pbnRzW2NvdW50IC0gMV07XG4gICAgICAgIGxpbmVzLnB1c2goe1xuICAgICAgICAgICAgZnJvbToge1xuICAgICAgICAgICAgICAgIHg6IGxhc3RbMF0sXG4gICAgICAgICAgICAgICAgeTogbGFzdFsxXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRvOiB7XG4gICAgICAgICAgICAgICAgeDogZmlyc3RbMF0sXG4gICAgICAgICAgICAgICAgeTogZmlyc3RbMV1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBsaW5lcztcbn1cbmZ1bmN0aW9uIGxpbmVJbnRlcnNlY3RQb2x5Z29uKGxpbmVzLCBsaW5lKSB7XG4gICAgdmFyIGlzSW50ZXJzZWN0ID0gZmFsc2U7XG4gICAgZWFjaChsaW5lcywgZnVuY3Rpb24gKGwpIHtcbiAgICAgICAgaWYgKGdldExpbmVJbnRlcnNlY3QobC5mcm9tLCBsLnRvLCBsaW5lLmZyb20sIGxpbmUudG8pKSB7XG4gICAgICAgICAgICBpc0ludGVyc2VjdCA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaXNJbnRlcnNlY3Q7XG59XG5mdW5jdGlvbiBnZXRCQm94KHBvaW50cykge1xuICAgIHZhciB4QXJyID0gcG9pbnRzLm1hcChmdW5jdGlvbiAocCkgeyByZXR1cm4gcFswXTsgfSk7XG4gICAgdmFyIHlBcnIgPSBwb2ludHMubWFwKGZ1bmN0aW9uIChwKSB7IHJldHVybiBwWzFdOyB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtaW5YOiBNYXRoLm1pbi5hcHBseShudWxsLCB4QXJyKSxcbiAgICAgICAgbWF4WDogTWF0aC5tYXguYXBwbHkobnVsbCwgeEFyciksXG4gICAgICAgIG1pblk6IE1hdGgubWluLmFwcGx5KG51bGwsIHlBcnIpLFxuICAgICAgICBtYXhZOiBNYXRoLm1heC5hcHBseShudWxsLCB5QXJyKVxuICAgIH07XG59XG5mdW5jdGlvbiBpbnRlcnNlY3RCQm94KGJveDEsIGJveDIpIHtcbiAgICByZXR1cm4gIShib3gyLm1pblggPiBib3gxLm1heFggfHwgYm94Mi5tYXhYIDwgYm94MS5taW5YIHx8IGJveDIubWluWSA+IGJveDEubWF4WSB8fCBib3gyLm1heFkgPCBib3gxLm1pblkpO1xufVxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaXNQb2x5Z29uc0ludGVyc2VjdChwb2ludHMxLCBwb2ludHMyKSB7XG4gICAgLy8g56m65pWw57uE77yM5oiW6ICF5LiA5Liq54K56L+U5ZueIGZhbHNlXG4gICAgaWYgKHBvaW50czEubGVuZ3RoIDwgMiB8fCBwb2ludHMyLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgYmJveDEgPSBnZXRCQm94KHBvaW50czEpO1xuICAgIHZhciBiYm94MiA9IGdldEJCb3gocG9pbnRzMik7XG4gICAgLy8g5Yik5a6a5YyF5Zu055uS5piv5ZCm55u45Lqk77yM5q+U5Yik5a6a54K55piv5ZCm5Zyo5aSa6L655b2i5YaF6KaB5b+r55qE5aSa77yM5Y+v5Lul562b6YCJ5o6J5aSn5aSa5pWw5oOF5Ya1XG4gICAgaWYgKCFpbnRlcnNlY3RCQm94KGJib3gxLCBiYm94MikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgaXNJbiA9IGZhbHNlO1xuICAgIC8vIOWIpOWumueCueaYr+WQpuWcqOWkmui+ueW9ouWGhemDqO+8jOS4gOaXpuacieS4gOS4queCueWcqOWPpuS4gOS4quWkmui+ueW9ouWGhe+8jOWImei/lOWbnlxuICAgIGVhY2gocG9pbnRzMiwgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIGlmIChpc1BvaW50SW5Qb2x5Z29uKHBvaW50czEsIHBvaW50WzBdLCBwb2ludFsxXSkpIHtcbiAgICAgICAgICAgIGlzSW4gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGlzSW4pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIOS4pOS4quWkmui+ueW9oumDvemcgOimgeWIpOWumlxuICAgIGVhY2gocG9pbnRzMSwgZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgIGlmIChpc1BvaW50SW5Qb2x5Z29uKHBvaW50czIsIHBvaW50WzBdLCBwb2ludFsxXSkpIHtcbiAgICAgICAgICAgIGlzSW4gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGlzSW4pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHZhciBsaW5lczEgPSBwYXJzZVRvTGluZXMocG9pbnRzMSk7XG4gICAgdmFyIGxpbmVzMiA9IHBhcnNlVG9MaW5lcyhwb2ludHMyKTtcbiAgICB2YXIgaXNJbnRlcnNlY3QgPSBmYWxzZTtcbiAgICBlYWNoKGxpbmVzMiwgZnVuY3Rpb24gKGxpbmUpIHtcbiAgICAgICAgaWYgKGxpbmVJbnRlcnNlY3RQb2x5Z29uKGxpbmVzMSwgbGluZSkpIHtcbiAgICAgICAgICAgIGlzSW50ZXJzZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBpc0ludGVyc2VjdDtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBvbHlnb25zLWludGVyc2VjdC5qcy5tYXAiLCJleHBvcnQgeyBkZWZhdWx0IGFzIHBhcnNlUGF0aCB9IGZyb20gJy4vcGFyc2UtcGF0aCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGNhdG11bGxSb20yQmV6aWVyIH0gZnJvbSAnLi9jYXRtdWxsLXJvbS0yLWJlemllcic7XG5leHBvcnQgeyBkZWZhdWx0IGFzIGZpbGxQYXRoIH0gZnJvbSAnLi9maWxsLXBhdGgnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmaWxsUGF0aEJ5RGlmZiB9IGZyb20gJy4vZmlsbC1wYXRoLWJ5LWRpZmYnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBmb3JtYXRQYXRoIH0gZnJvbSAnLi9mb3JtYXQtcGF0aCc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIHBhdGhJbnRlcnNlY3Rpb24gfSBmcm9tICcuL3BhdGgtaW50ZXJzZWN0aW9uJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcGFyc2VQYXRoQXJyYXkgfSBmcm9tICcuL3BhcnNlLXBhdGgtYXJyYXknO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBwYXJzZVBhdGhTdHJpbmcgfSBmcm9tICcuL3BhcnNlLXBhdGgtc3RyaW5nJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcGF0aDJDdXJ2ZSB9IGZyb20gJy4vcGF0aC0yLWN1cnZlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcGF0aDJBYnNvbHV0ZSB9IGZyb20gJy4vcGF0aC0yLWFic29sdXRlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcmVhY3RQYXRoIH0gZnJvbSAnLi9yZWN0LXBhdGgnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBnZXRBcmNQYXJhbXMgfSBmcm9tICcuL2dldC1hcmMtcGFyYW1zJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgcGF0aDJTZWdtZW50cyB9IGZyb20gJy4vcGF0aC0yLXNlZ21lbnRzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZ2V0TGluZUludGVyc2VjdCB9IGZyb20gJy4vZ2V0LWxpbmUtaW50ZXJzZWN0JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNQb2x5Z29uc0ludGVyc2VjdCB9IGZyb20gJy4vaXMtcG9seWdvbnMtaW50ZXJzZWN0JztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgaXNQb2ludEluUG9seWdvbiB9IGZyb20gJy4vcG9pbnQtaW4tcG9seWdvbic7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///37\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return multiplyMatrix; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return multiplyVec2; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return invert; });\n/**\n * @fileoverview 矩阵运算,本来是要引入 gl-matrix, 但是考虑到 g-mobile 对大小有限制,同时 g-webgl 使用的 matrix 不一致\n * 所以,这里仅实现 2D 几个运算,上层自己引入 gl-matrix\n * @author dxq613@gmail.com\n */\n/**\n * 3阶矩阵相乘\n * @param {number[]} a 矩阵1\n * @param {number[]} b 矩阵2\n */\nfunction multiplyMatrix(a, b) {\n var out = [];\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a10 = a[3];\n var a11 = a[4];\n var a12 = a[5];\n var a20 = a[6];\n var a21 = a[7];\n var a22 = a[8];\n var b00 = b[0];\n var b01 = b[1];\n var b02 = b[2];\n var b10 = b[3];\n var b11 = b[4];\n var b12 = b[5];\n var b20 = b[6];\n var b21 = b[7];\n var b22 = b[8];\n out[0] = b00 * a00 + b01 * a10 + b02 * a20;\n out[1] = b00 * a01 + b01 * a11 + b02 * a21;\n out[2] = b00 * a02 + b01 * a12 + b02 * a22;\n out[3] = b10 * a00 + b11 * a10 + b12 * a20;\n out[4] = b10 * a01 + b11 * a11 + b12 * a21;\n out[5] = b10 * a02 + b11 * a12 + b12 * a22;\n out[6] = b20 * a00 + b21 * a10 + b22 * a20;\n out[7] = b20 * a01 + b21 * a11 + b22 * a21;\n out[8] = b20 * a02 + b21 * a12 + b22 * a22;\n return out;\n}\n/**\n * 3阶矩阵同2阶向量相乘\n * @param {number[]} m 矩阵\n * @param {number[]} v 二阶向量\n */\nfunction multiplyVec2(m, v) {\n var out = [];\n var x = v[0];\n var y = v[1];\n out[0] = m[0] * x + m[3] * y + m[6];\n out[1] = m[1] * x + m[4] * y + m[7];\n return out;\n}\n/**\n * 矩阵的逆\n * @param {number[]} a 矩阵\n */\nfunction invert(a) {\n var out = [];\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a10 = a[3];\n var a11 = a[4];\n var a12 = a[5];\n var a20 = a[6];\n var a21 = a[7];\n var a22 = a[8];\n var b01 = a22 * a11 - a12 * a21;\n var b11 = -a22 * a10 + a12 * a20;\n var b21 = a21 * a10 - a11 * a20;\n // Calculate the determinant\n var det = a00 * b01 + a01 * b11 + a02 * b21;\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n out[0] = b01 * det;\n out[1] = (-a22 * a01 + a02 * a21) * det;\n out[2] = (a12 * a01 - a02 * a11) * det;\n out[3] = b11 * det;\n out[4] = (a22 * a00 - a02 * a20) * det;\n out[5] = (-a12 * a00 + a02 * a10) * det;\n out[6] = b21 * det;\n out[7] = (-a21 * a00 + a01 * a20) * det;\n out[8] = (a11 * a00 - a01 * a10) * det;\n return out;\n}\n//# sourceMappingURL=matrix.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1iYXNlL2VzbS91dGlsL21hdHJpeC5qcz82OTI4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCLFdBQVcsU0FBUztBQUNwQjtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQixXQUFXLFNBQVM7QUFDcEI7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQjtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiMzguanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlb3ZlcnZpZXcg55+p6Zi16L+Q566X77yM5pys5p2l5piv6KaB5byV5YWlIGdsLW1hdHJpeCwg5L2G5piv6ICD6JmR5YiwIGctbW9iaWxlIOWvueWkp+Wwj+aciemZkOWItu+8jOWQjOaXtiBnLXdlYmdsIOS9v+eUqOeahCBtYXRyaXgg5LiN5LiA6Ie0XG4gKiDmiYDku6XvvIzov5nph4zku4Xlrp7njrAgMkQg5Yeg5Liq6L+Q566X77yM5LiK5bGC6Ieq5bex5byV5YWlIGdsLW1hdHJpeFxuICogQGF1dGhvciBkeHE2MTNAZ21haWwuY29tXG4gKi9cbi8qKlxuICogM+mYtuefqemYteebuOS5mFxuICogQHBhcmFtIHtudW1iZXJbXX0gYSDnn6npmLUxXG4gKiBAcGFyYW0ge251bWJlcltdfSBiIOefqemYtTJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5TWF0cml4KGEsIGIpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIGEwMCA9IGFbMF07XG4gICAgdmFyIGEwMSA9IGFbMV07XG4gICAgdmFyIGEwMiA9IGFbMl07XG4gICAgdmFyIGExMCA9IGFbM107XG4gICAgdmFyIGExMSA9IGFbNF07XG4gICAgdmFyIGExMiA9IGFbNV07XG4gICAgdmFyIGEyMCA9IGFbNl07XG4gICAgdmFyIGEyMSA9IGFbN107XG4gICAgdmFyIGEyMiA9IGFbOF07XG4gICAgdmFyIGIwMCA9IGJbMF07XG4gICAgdmFyIGIwMSA9IGJbMV07XG4gICAgdmFyIGIwMiA9IGJbMl07XG4gICAgdmFyIGIxMCA9IGJbM107XG4gICAgdmFyIGIxMSA9IGJbNF07XG4gICAgdmFyIGIxMiA9IGJbNV07XG4gICAgdmFyIGIyMCA9IGJbNl07XG4gICAgdmFyIGIyMSA9IGJbN107XG4gICAgdmFyIGIyMiA9IGJbOF07XG4gICAgb3V0WzBdID0gYjAwICogYTAwICsgYjAxICogYTEwICsgYjAyICogYTIwO1xuICAgIG91dFsxXSA9IGIwMCAqIGEwMSArIGIwMSAqIGExMSArIGIwMiAqIGEyMTtcbiAgICBvdXRbMl0gPSBiMDAgKiBhMDIgKyBiMDEgKiBhMTIgKyBiMDIgKiBhMjI7XG4gICAgb3V0WzNdID0gYjEwICogYTAwICsgYjExICogYTEwICsgYjEyICogYTIwO1xuICAgIG91dFs0XSA9IGIxMCAqIGEwMSArIGIxMSAqIGExMSArIGIxMiAqIGEyMTtcbiAgICBvdXRbNV0gPSBiMTAgKiBhMDIgKyBiMTEgKiBhMTIgKyBiMTIgKiBhMjI7XG4gICAgb3V0WzZdID0gYjIwICogYTAwICsgYjIxICogYTEwICsgYjIyICogYTIwO1xuICAgIG91dFs3XSA9IGIyMCAqIGEwMSArIGIyMSAqIGExMSArIGIyMiAqIGEyMTtcbiAgICBvdXRbOF0gPSBiMjAgKiBhMDIgKyBiMjEgKiBhMTIgKyBiMjIgKiBhMjI7XG4gICAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogM+mYtuefqemYteWQjDLpmLblkJHph4/nm7jkuZhcbiAqIEBwYXJhbSB7bnVtYmVyW119IG0g55+p6Zi1XG4gKiBAcGFyYW0ge251bWJlcltdfSB2IOS6jOmYtuWQkemHj1xuICovXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHlWZWMyKG0sIHYpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIHggPSB2WzBdO1xuICAgIHZhciB5ID0gdlsxXTtcbiAgICBvdXRbMF0gPSBtWzBdICogeCArIG1bM10gKiB5ICsgbVs2XTtcbiAgICBvdXRbMV0gPSBtWzFdICogeCArIG1bNF0gKiB5ICsgbVs3XTtcbiAgICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiDnn6npmLXnmoTpgIZcbiAqIEBwYXJhbSB7bnVtYmVyW119IGEg55+p6Zi1XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnZlcnQoYSkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgYTAwID0gYVswXTtcbiAgICB2YXIgYTAxID0gYVsxXTtcbiAgICB2YXIgYTAyID0gYVsyXTtcbiAgICB2YXIgYTEwID0gYVszXTtcbiAgICB2YXIgYTExID0gYVs0XTtcbiAgICB2YXIgYTEyID0gYVs1XTtcbiAgICB2YXIgYTIwID0gYVs2XTtcbiAgICB2YXIgYTIxID0gYVs3XTtcbiAgICB2YXIgYTIyID0gYVs4XTtcbiAgICB2YXIgYjAxID0gYTIyICogYTExIC0gYTEyICogYTIxO1xuICAgIHZhciBiMTEgPSAtYTIyICogYTEwICsgYTEyICogYTIwO1xuICAgIHZhciBiMjEgPSBhMjEgKiBhMTAgLSBhMTEgKiBhMjA7XG4gICAgLy8gQ2FsY3VsYXRlIHRoZSBkZXRlcm1pbmFudFxuICAgIHZhciBkZXQgPSBhMDAgKiBiMDEgKyBhMDEgKiBiMTEgKyBhMDIgKiBiMjE7XG4gICAgaWYgKCFkZXQpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGRldCA9IDEuMCAvIGRldDtcbiAgICBvdXRbMF0gPSBiMDEgKiBkZXQ7XG4gICAgb3V0WzFdID0gKC1hMjIgKiBhMDEgKyBhMDIgKiBhMjEpICogZGV0O1xuICAgIG91dFsyXSA9IChhMTIgKiBhMDEgLSBhMDIgKiBhMTEpICogZGV0O1xuICAgIG91dFszXSA9IGIxMSAqIGRldDtcbiAgICBvdXRbNF0gPSAoYTIyICogYTAwIC0gYTAyICogYTIwKSAqIGRldDtcbiAgICBvdXRbNV0gPSAoLWExMiAqIGEwMCArIGEwMiAqIGExMCkgKiBkZXQ7XG4gICAgb3V0WzZdID0gYjIxICogZGV0O1xuICAgIG91dFs3XSA9ICgtYTIxICogYTAwICsgYTAxICogYTIwKSAqIGRldDtcbiAgICBvdXRbOF0gPSAoYTExICogYTAwIC0gYTAxICogYTEwKSAqIGRldDtcbiAgICByZXR1cm4gb3V0O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWF0cml4LmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///38\n')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "create", function() { return create; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clone", function() { return clone; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "length", function() { return length; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fromValues", function() { return fromValues; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copy", function() { return copy; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "set", function() { return set; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "add", function() { return add; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subtract", function() { return subtract; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multiply", function() { return multiply; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "divide", function() { return divide; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ceil", function() { return ceil; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "floor", function() { return floor; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "round", function() { return round; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scale", function() { return scale; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scaleAndAdd", function() { return scaleAndAdd; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distance", function() { return distance; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "squaredDistance", function() { return squaredDistance; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "squaredLength", function() { return squaredLength; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "negate", function() { return negate; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "inverse", function() { return inverse; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalize", function() { return normalize; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dot", function() { return dot; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cross", function() { return cross; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lerp", function() { return lerp; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hermite", function() { return hermite; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bezier", function() { return bezier; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "random", function() { return random; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transformMat4", function() { return transformMat4; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transformMat3", function() { return transformMat3; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transformQuat", function() { return transformQuat; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rotateX", function() { return rotateX; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rotateY", function() { return rotateY; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rotateZ", function() { return rotateZ; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "angle", function() { return angle; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zero", function() { return zero; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "str", function() { return str; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exactEquals", function() { return exactEquals; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "equals", function() { return equals; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sub", function() { return sub; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mul", function() { return mul; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "div", function() { return div; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dist", function() { return dist; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sqrDist", function() { return sqrDist; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "len", function() { return len; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sqrLen", function() { return sqrLen; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "forEach", function() { return forEach; });\n/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12);\n\n/**\n * 3 Dimensional Vector\n * @module vec3\n */\n\n/**\n * Creates a new, empty vec3\n *\n * @returns {vec3} a new 3D vector\n */\n\nfunction create() {\n var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__[/* ARRAY_TYPE */ "a"](3);\n\n if (_common_js__WEBPACK_IMPORTED_MODULE_0__[/* ARRAY_TYPE */ "a"] != Float32Array) {\n out[0] = 0;\n out[1] = 0;\n out[2] = 0;\n }\n\n return out;\n}\n/**\n * Creates a new vec3 initialized with values from an existing vector\n *\n * @param {ReadonlyVec3} a vector to clone\n * @returns {vec3} a new 3D vector\n */\n\nfunction clone(a) {\n var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__[/* ARRAY_TYPE */ "a"](3);\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n return out;\n}\n/**\n * Calculates the length of a vec3\n *\n * @param {ReadonlyVec3} a vector to calculate length of\n * @returns {Number} length of a\n */\n\nfunction length(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n return Math.hypot(x, y, z);\n}\n/**\n * Creates a new vec3 initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} a new 3D vector\n */\n\nfunction fromValues(x, y, z) {\n var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__[/* ARRAY_TYPE */ "a"](3);\n out[0] = x;\n out[1] = y;\n out[2] = z;\n return out;\n}\n/**\n * Copy the values from one vec3 to another\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the source vector\n * @returns {vec3} out\n */\n\nfunction copy(out, a) {\n out[0] = a[0];\n out[1] = a[1];\n out[2] = a[2];\n return out;\n}\n/**\n * Set the components of a vec3 to the given values\n *\n * @param {vec3} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} out\n */\n\nfunction set(out, x, y, z) {\n out[0] = x;\n out[1] = y;\n out[2] = z;\n return out;\n}\n/**\n * Adds two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction add(out, a, b) {\n out[0] = a[0] + b[0];\n out[1] = a[1] + b[1];\n out[2] = a[2] + b[2];\n return out;\n}\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction subtract(out, a, b) {\n out[0] = a[0] - b[0];\n out[1] = a[1] - b[1];\n out[2] = a[2] - b[2];\n return out;\n}\n/**\n * Multiplies two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction multiply(out, a, b) {\n out[0] = a[0] * b[0];\n out[1] = a[1] * b[1];\n out[2] = a[2] * b[2];\n return out;\n}\n/**\n * Divides two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction divide(out, a, b) {\n out[0] = a[0] / b[0];\n out[1] = a[1] / b[1];\n out[2] = a[2] / b[2];\n return out;\n}\n/**\n * Math.ceil the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to ceil\n * @returns {vec3} out\n */\n\nfunction ceil(out, a) {\n out[0] = Math.ceil(a[0]);\n out[1] = Math.ceil(a[1]);\n out[2] = Math.ceil(a[2]);\n return out;\n}\n/**\n * Math.floor the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to floor\n * @returns {vec3} out\n */\n\nfunction floor(out, a) {\n out[0] = Math.floor(a[0]);\n out[1] = Math.floor(a[1]);\n out[2] = Math.floor(a[2]);\n return out;\n}\n/**\n * Returns the minimum of two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction min(out, a, b) {\n out[0] = Math.min(a[0], b[0]);\n out[1] = Math.min(a[1], b[1]);\n out[2] = Math.min(a[2], b[2]);\n return out;\n}\n/**\n * Returns the maximum of two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction max(out, a, b) {\n out[0] = Math.max(a[0], b[0]);\n out[1] = Math.max(a[1], b[1]);\n out[2] = Math.max(a[2], b[2]);\n return out;\n}\n/**\n * Math.round the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to round\n * @returns {vec3} out\n */\n\nfunction round(out, a) {\n out[0] = Math.round(a[0]);\n out[1] = Math.round(a[1]);\n out[2] = Math.round(a[2]);\n return out;\n}\n/**\n * Scales a vec3 by a scalar number\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec3} out\n */\n\nfunction scale(out, a, b) {\n out[0] = a[0] * b;\n out[1] = a[1] * b;\n out[2] = a[2] * b;\n return out;\n}\n/**\n * Adds two vec3\'s after scaling the second operand by a scalar value\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} scale the amount to scale b by before adding\n * @returns {vec3} out\n */\n\nfunction scaleAndAdd(out, a, b, scale) {\n out[0] = a[0] + b[0] * scale;\n out[1] = a[1] + b[1] * scale;\n out[2] = a[2] + b[2] * scale;\n return out;\n}\n/**\n * Calculates the euclidian distance between two vec3\'s\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} distance between a and b\n */\n\nfunction distance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n return Math.hypot(x, y, z);\n}\n/**\n * Calculates the squared euclidian distance between two vec3\'s\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} squared distance between a and b\n */\n\nfunction squaredDistance(a, b) {\n var x = b[0] - a[0];\n var y = b[1] - a[1];\n var z = b[2] - a[2];\n return x * x + y * y + z * z;\n}\n/**\n * Calculates the squared length of a vec3\n *\n * @param {ReadonlyVec3} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\n\nfunction squaredLength(a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n return x * x + y * y + z * z;\n}\n/**\n * Negates the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to negate\n * @returns {vec3} out\n */\n\nfunction negate(out, a) {\n out[0] = -a[0];\n out[1] = -a[1];\n out[2] = -a[2];\n return out;\n}\n/**\n * Returns the inverse of the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to invert\n * @returns {vec3} out\n */\n\nfunction inverse(out, a) {\n out[0] = 1.0 / a[0];\n out[1] = 1.0 / a[1];\n out[2] = 1.0 / a[2];\n return out;\n}\n/**\n * Normalize a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to normalize\n * @returns {vec3} out\n */\n\nfunction normalize(out, a) {\n var x = a[0];\n var y = a[1];\n var z = a[2];\n var len = x * x + y * y + z * z;\n\n if (len > 0) {\n //TODO: evaluate use of glm_invsqrt here?\n len = 1 / Math.sqrt(len);\n }\n\n out[0] = a[0] * len;\n out[1] = a[1] * len;\n out[2] = a[2] * len;\n return out;\n}\n/**\n * Calculates the dot product of two vec3\'s\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} dot product of a and b\n */\n\nfunction dot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n/**\n * Computes the cross product of two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\n\nfunction cross(out, a, b) {\n var ax = a[0],\n ay = a[1],\n az = a[2];\n var bx = b[0],\n by = b[1],\n bz = b[2];\n out[0] = ay * bz - az * by;\n out[1] = az * bx - ax * bz;\n out[2] = ax * by - ay * bx;\n return out;\n}\n/**\n * Performs a linear interpolation between two vec3\'s\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\n\nfunction lerp(out, a, b, t) {\n var ax = a[0];\n var ay = a[1];\n var az = a[2];\n out[0] = ax + t * (b[0] - ax);\n out[1] = ay + t * (b[1] - ay);\n out[2] = az + t * (b[2] - az);\n return out;\n}\n/**\n * Performs a hermite interpolation with two control points\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {ReadonlyVec3} c the third operand\n * @param {ReadonlyVec3} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\n\nfunction hermite(out, a, b, c, d, t) {\n var factorTimes2 = t * t;\n var factor1 = factorTimes2 * (2 * t - 3) + 1;\n var factor2 = factorTimes2 * (t - 2) + t;\n var factor3 = factorTimes2 * (t - 1);\n var factor4 = factorTimes2 * (3 - 2 * t);\n out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;\n out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;\n out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;\n return out;\n}\n/**\n * Performs a bezier interpolation with two control points\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {ReadonlyVec3} c the third operand\n * @param {ReadonlyVec3} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\n\nfunction bezier(out, a, b, c, d, t) {\n var inverseFactor = 1 - t;\n var inverseFactorTimesTwo = inverseFactor * inverseFactor;\n var factorTimes2 = t * t;\n var factor1 = inverseFactorTimesTwo * inverseFactor;\n var factor2 = 3 * t * inverseFactorTimesTwo;\n var factor3 = 3 * factorTimes2 * inverseFactor;\n var factor4 = factorTimes2 * t;\n out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;\n out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;\n out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;\n return out;\n}\n/**\n * Generates a random vector with the given scale\n *\n * @param {vec3} out the receiving vector\n * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned\n * @returns {vec3} out\n */\n\nfunction random(out, scale) {\n scale = scale || 1.0;\n var r = _common_js__WEBPACK_IMPORTED_MODULE_0__[/* RANDOM */ "c"]() * 2.0 * Math.PI;\n var z = _common_js__WEBPACK_IMPORTED_MODULE_0__[/* RANDOM */ "c"]() * 2.0 - 1.0;\n var zScale = Math.sqrt(1.0 - z * z) * scale;\n out[0] = Math.cos(r) * zScale;\n out[1] = Math.sin(r) * zScale;\n out[2] = z * scale;\n return out;\n}\n/**\n * Transforms the vec3 with a mat4.\n * 4th vector component is implicitly \'1\'\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec3} out\n */\n\nfunction transformMat4(out, a, m) {\n var x = a[0],\n y = a[1],\n z = a[2];\n var w = m[3] * x + m[7] * y + m[11] * z + m[15];\n w = w || 1.0;\n out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;\n out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;\n out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;\n return out;\n}\n/**\n * Transforms the vec3 with a mat3.\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat3} m the 3x3 matrix to transform with\n * @returns {vec3} out\n */\n\nfunction transformMat3(out, a, m) {\n var x = a[0],\n y = a[1],\n z = a[2];\n out[0] = x * m[0] + y * m[3] + z * m[6];\n out[1] = x * m[1] + y * m[4] + z * m[7];\n out[2] = x * m[2] + y * m[5] + z * m[8];\n return out;\n}\n/**\n * Transforms the vec3 with a quat\n * Can also be used for dual quaternions. (Multiply it with the real part)\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyQuat} q quaternion to transform with\n * @returns {vec3} out\n */\n\nfunction transformQuat(out, a, q) {\n // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed\n var qx = q[0],\n qy = q[1],\n qz = q[2],\n qw = q[3];\n var x = a[0],\n y = a[1],\n z = a[2]; // var qvec = [qx, qy, qz];\n // var uv = vec3.cross([], qvec, a);\n\n var uvx = qy * z - qz * y,\n uvy = qz * x - qx * z,\n uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv);\n\n var uuvx = qy * uvz - qz * uvy,\n uuvy = qz * uvx - qx * uvz,\n uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w);\n\n var w2 = qw * 2;\n uvx *= w2;\n uvy *= w2;\n uvz *= w2; // vec3.scale(uuv, uuv, 2);\n\n uuvx *= 2;\n uuvy *= 2;\n uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv));\n\n out[0] = x + uvx + uuvx;\n out[1] = y + uvy + uuvy;\n out[2] = z + uvz + uuvz;\n return out;\n}\n/**\n * Rotate a 3D vector around the x-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\n\nfunction rotateX(out, a, b, rad) {\n var p = [],\n r = []; //Translate point to the origin\n\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2]; //perform rotation\n\n r[0] = p[0];\n r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);\n r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position\n\n out[0] = r[0] + b[0];\n out[1] = r[1] + b[1];\n out[2] = r[2] + b[2];\n return out;\n}\n/**\n * Rotate a 3D vector around the y-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\n\nfunction rotateY(out, a, b, rad) {\n var p = [],\n r = []; //Translate point to the origin\n\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2]; //perform rotation\n\n r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);\n r[1] = p[1];\n r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position\n\n out[0] = r[0] + b[0];\n out[1] = r[1] + b[1];\n out[2] = r[2] + b[2];\n return out;\n}\n/**\n * Rotate a 3D vector around the z-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\n\nfunction rotateZ(out, a, b, rad) {\n var p = [],\n r = []; //Translate point to the origin\n\n p[0] = a[0] - b[0];\n p[1] = a[1] - b[1];\n p[2] = a[2] - b[2]; //perform rotation\n\n r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);\n r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);\n r[2] = p[2]; //translate to correct position\n\n out[0] = r[0] + b[0];\n out[1] = r[1] + b[1];\n out[2] = r[2] + b[2];\n return out;\n}\n/**\n * Get the angle between two 3D vectors\n * @param {ReadonlyVec3} a The first operand\n * @param {ReadonlyVec3} b The second operand\n * @returns {Number} The angle in radians\n */\n\nfunction angle(a, b) {\n var ax = a[0],\n ay = a[1],\n az = a[2],\n bx = b[0],\n by = b[1],\n bz = b[2],\n mag1 = Math.sqrt(ax * ax + ay * ay + az * az),\n mag2 = Math.sqrt(bx * bx + by * by + bz * bz),\n mag = mag1 * mag2,\n cosine = mag && dot(a, b) / mag;\n return Math.acos(Math.min(Math.max(cosine, -1), 1));\n}\n/**\n * Set the components of a vec3 to zero\n *\n * @param {vec3} out the receiving vector\n * @returns {vec3} out\n */\n\nfunction zero(out) {\n out[0] = 0.0;\n out[1] = 0.0;\n out[2] = 0.0;\n return out;\n}\n/**\n * Returns a string representation of a vector\n *\n * @param {ReadonlyVec3} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\n\nfunction str(a) {\n return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")";\n}\n/**\n * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyVec3} a The first vector.\n * @param {ReadonlyVec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\n\nfunction exactEquals(a, b) {\n return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\n}\n/**\n * Returns whether or not the vectors have approximately the same elements in the same position.\n *\n * @param {ReadonlyVec3} a The first vector.\n * @param {ReadonlyVec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\n\nfunction equals(a, b) {\n var a0 = a[0],\n a1 = a[1],\n a2 = a[2];\n var b0 = b[0],\n b1 = b[1],\n b2 = b[2];\n return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__[/* EPSILON */ "b"] * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__[/* EPSILON */ "b"] * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__[/* EPSILON */ "b"] * Math.max(1.0, Math.abs(a2), Math.abs(b2));\n}\n/**\n * Alias for {@link vec3.subtract}\n * @function\n */\n\nvar sub = subtract;\n/**\n * Alias for {@link vec3.multiply}\n * @function\n */\n\nvar mul = multiply;\n/**\n * Alias for {@link vec3.divide}\n * @function\n */\n\nvar div = divide;\n/**\n * Alias for {@link vec3.distance}\n * @function\n */\n\nvar dist = distance;\n/**\n * Alias for {@link vec3.squaredDistance}\n * @function\n */\n\nvar sqrDist = squaredDistance;\n/**\n * Alias for {@link vec3.length}\n * @function\n */\n\nvar len = length;\n/**\n * Alias for {@link vec3.squaredLength}\n * @function\n */\n\nvar sqrLen = squaredLength;\n/**\n * Perform some operation over an array of vec3s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\n\nvar forEach = function () {\n var vec = create();\n return function (a, stride, offset, count, fn, arg) {\n var i, l;\n\n if (!stride) {\n stride = 3;\n }\n\n if (!offset) {\n offset = 0;\n }\n\n if (count) {\n l = Math.min(count * stride + offset, a.length);\n } else {\n l = a.length;\n }\n\n for (i = offset; i < l; i += stride) {\n vec[0] = a[i];\n vec[1] = a[i + 1];\n vec[2] = a[i + 2];\n fn(vec, vec, arg);\n a[i] = vec[0];\n a[i + 1] = vec[1];\n a[i + 2] = vec[2];\n }\n\n return a;\n };\n}();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZ2wtbWF0cml4L2VzbS92ZWMzLmpzPzlmZTciXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLEtBQUs7QUFDbEI7O0FBRU87QUFDUCxnQkFBZ0IsNkRBQW1COztBQUVuQyxNQUFNLDZEQUFtQjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxhQUFhO0FBQ3hCLGFBQWEsS0FBSztBQUNsQjs7QUFFTztBQUNQLGdCQUFnQiw2REFBbUI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsYUFBYTtBQUN4QixhQUFhLE9BQU87QUFDcEI7O0FBRU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsYUFBYSxLQUFLO0FBQ2xCOztBQUVPO0FBQ1AsZ0JBQWdCLDZEQUFtQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxLQUFLO0FBQ2hCLFdBQVcsYUFBYTtBQUN4QixhQUFhLEtBQUs7QUFDbEI7O0FBRU87QUFDUDtBQUNBO0FB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cUUsMERBQWdCLHFFQUFxRSwwREFBZ0I7QUFDeE47QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVPO0FBQ1A7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFTztBQUNQO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRU87QUFDUDtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVPO0FBQ1A7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFTztBQUNQO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRU87QUFDUDtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsU0FBUztBQUNwQixXQUFXLE9BQU87QUFDbEIsYUFBYSxNQUFNO0FBQ25CO0FBQ0E7O0FBRU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQyIsImZpbGUiOiIzOS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdsTWF0cml4IGZyb20gXCIuL2NvbW1vbi5qc1wiO1xuLyoqXG4gKiAzIERpbWVuc2lvbmFsIFZlY3RvclxuICogQG1vZHVsZSB2ZWMzXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3LCBlbXB0eSB2ZWMzXG4gKlxuICogQHJldHVybnMge3ZlYzN9IGEgbmV3IDNEIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcblxuICBpZiAoZ2xNYXRyaXguQVJSQVlfVFlQRSAhPSBGbG9hdDMyQXJyYXkpIHtcbiAgICBvdXRbMF0gPSAwO1xuICAgIG91dFsxXSA9IDA7XG4gICAgb3V0WzJdID0gMDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgdmVjMyBpbml0aWFsaXplZCB3aXRoIHZhbHVlcyBmcm9tIGFuIGV4aXN0aW5nIHZlY3RvclxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBjbG9uZVxuICogQHJldHVybnMge3ZlYzN9IGEgbmV3IDNEIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShhKSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcbiAgb3V0WzBdID0gYVswXTtcbiAgb3V0WzFdID0gYVsxXTtcbiAgb3V0WzJdID0gYVsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjM1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBjYWxjdWxhdGUgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBsZW5ndGggb2YgYVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsZW5ndGgoYSkge1xuICB2YXIgeCA9IGFbMF07XG4gIHZhciB5ID0gYVsxXTtcbiAgdmFyIHogPSBhWzJdO1xuICByZXR1cm4gTWF0aC5oeXBvdCh4LCB5LCB6KTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyB2ZWMzIGluaXRpYWxpemVkIHdpdGggdGhlIGdpdmVuIHZhbHVlc1xuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSB4IFggY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geSBZIGNvbXBvbmVudFxuICogQHBhcmFtIHtOdW1iZXJ9IHogWiBjb21wb25lbnRcbiAqIEByZXR1cm5zIHt2ZWMzfSBhIG5ldyAzRCB2ZWN0b3JcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVZhbHVlcyh4LCB5LCB6KSB7XG4gIHZhciBvdXQgPSBuZXcgZ2xNYXRyaXguQVJSQVlfVFlQRSgzKTtcbiAgb3V0WzBdID0geDtcbiAgb3V0WzFdID0geTtcbiAgb3V0WzJdID0gejtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ29weSB0aGUgdmFsdWVzIGZyb20gb25lIHZlYzMgdG8gYW5vdGhlclxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgc291cmNlIHZlY3RvclxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb3B5KG91dCwgYSkge1xuICBvdXRbMF0gPSBhWzBdO1xuICBvdXRbMV0gPSBhWzFdO1xuICBvdXRbMl0gPSBhWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGNvbXBvbmVudHMgb2YgYSB2ZWMzIHRvIHRoZSBnaXZlbiB2YWx1ZXNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtOdW1iZXJ9IHggWCBjb21wb25lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgY29tcG9uZW50XG4gKiBAcGFyYW0ge051bWJlcn0geiBaIGNvbXBvbmVudFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXQob3V0LCB4LCB5LCB6KSB7XG4gIG91dFswXSA9IHg7XG4gIG91dFsxXSA9IHk7XG4gIG91dFsyXSA9IHo7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEFkZHMgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSBhWzJdICsgYlsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogU3VidHJhY3RzIHZlY3RvciBiIGZyb20gdmVjdG9yIGFcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdWJ0cmFjdChvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAtIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLSBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC0gYlsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTXVsdGlwbGllcyB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbXVsdGlwbHkob3V0LCBhLCBiKSB7XG4gIG91dFswXSA9IGFbMF0gKiBiWzBdO1xuICBvdXRbMV0gPSBhWzFdICogYlsxXTtcbiAgb3V0WzJdID0gYVsyXSAqIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIERpdmlkZXMgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRpdmlkZShvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gYVswXSAvIGJbMF07XG4gIG91dFsxXSA9IGFbMV0gLyBiWzFdO1xuICBvdXRbMl0gPSBhWzJdIC8gYlsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogTWF0aC5jZWlsIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjM1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gY2VpbFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjZWlsKG91dCwgYSkge1xuICBvdXRbMF0gPSBNYXRoLmNlaWwoYVswXSk7XG4gIG91dFsxXSA9IE1hdGguY2VpbChhWzFdKTtcbiAgb3V0WzJdID0gTWF0aC5jZWlsKGFbMl0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBNYXRoLmZsb29yIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjM1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gZmxvb3JcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZmxvb3Iob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGguZmxvb3IoYVswXSk7XG4gIG91dFsxXSA9IE1hdGguZmxvb3IoYVsxXSk7XG4gIG91dFsyXSA9IE1hdGguZmxvb3IoYVsyXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIG1pbmltdW0gb2YgdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1pbihvdXQsIGEsIGIpIHtcbiAgb3V0WzBdID0gTWF0aC5taW4oYVswXSwgYlswXSk7XG4gIG91dFsxXSA9IE1hdGgubWluKGFbMV0sIGJbMV0pO1xuICBvdXRbMl0gPSBNYXRoLm1pbihhWzJdLCBiWzJdKTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgbWF4aW11bSBvZiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWF4KG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBNYXRoLm1heChhWzBdLCBiWzBdKTtcbiAgb3V0WzFdID0gTWF0aC5tYXgoYVsxXSwgYlsxXSk7XG4gIG91dFsyXSA9IE1hdGgubWF4KGFbMl0sIGJbMl0pO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBNYXRoLnJvdW5kIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjM1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gcm91bmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm91bmQob3V0LCBhKSB7XG4gIG91dFswXSA9IE1hdGgucm91bmQoYVswXSk7XG4gIG91dFsxXSA9IE1hdGgucm91bmQoYVsxXSk7XG4gIG91dFsyXSA9IE1hdGgucm91bmQoYVsyXSk7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFNjYWxlcyBhIHZlYzMgYnkgYSBzY2FsYXIgbnVtYmVyXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gc2NhbGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBiIGFtb3VudCB0byBzY2FsZSB0aGUgdmVjdG9yIGJ5XG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKG91dCwgYSwgYikge1xuICBvdXRbMF0gPSBhWzBdICogYjtcbiAgb3V0WzFdID0gYVsxXSAqIGI7XG4gIG91dFsyXSA9IGFbMl0gKiBiO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBBZGRzIHR3byB2ZWMzJ3MgYWZ0ZXIgc2NhbGluZyB0aGUgc2Vjb25kIG9wZXJhbmQgYnkgYSBzY2FsYXIgdmFsdWVcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHNjYWxlIHRoZSBhbW91bnQgdG8gc2NhbGUgYiBieSBiZWZvcmUgYWRkaW5nXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlQW5kQWRkKG91dCwgYSwgYiwgc2NhbGUpIHtcbiAgb3V0WzBdID0gYVswXSArIGJbMF0gKiBzY2FsZTtcbiAgb3V0WzFdID0gYVsxXSArIGJbMV0gKiBzY2FsZTtcbiAgb3V0WzJdID0gYVsyXSArIGJbMl0gKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZXVjbGlkaWFuIGRpc3RhbmNlIGJldHdlZW4gdHdvIHZlYzMnc1xuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkaXN0YW5jZShhLCBiKSB7XG4gIHZhciB4ID0gYlswXSAtIGFbMF07XG4gIHZhciB5ID0gYlsxXSAtIGFbMV07XG4gIHZhciB6ID0gYlsyXSAtIGFbMl07XG4gIHJldHVybiBNYXRoLmh5cG90KHgsIHksIHopO1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGV1Y2xpZGlhbiBkaXN0YW5jZSBiZXR3ZWVuIHR3byB2ZWMzJ3NcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgZmlyc3Qgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgdGhlIHNlY29uZCBvcGVyYW5kXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGRpc3RhbmNlIGJldHdlZW4gYSBhbmQgYlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzcXVhcmVkRGlzdGFuY2UoYSwgYikge1xuICB2YXIgeCA9IGJbMF0gLSBhWzBdO1xuICB2YXIgeSA9IGJbMV0gLSBhWzFdO1xuICB2YXIgeiA9IGJbMl0gLSBhWzJdO1xuICByZXR1cm4geCAqIHggKyB5ICogeSArIHogKiB6O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzcXVhcmVkIGxlbmd0aCBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gY2FsY3VsYXRlIHNxdWFyZWQgbGVuZ3RoIG9mXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBzcXVhcmVkIGxlbmd0aCBvZiBhXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWFyZWRMZW5ndGgoYSkge1xuICB2YXIgeCA9IGFbMF07XG4gIHZhciB5ID0gYVsxXTtcbiAgdmFyIHogPSBhWzJdO1xuICByZXR1cm4geCAqIHggKyB5ICogeSArIHogKiB6O1xufVxuLyoqXG4gKiBOZWdhdGVzIHRoZSBjb21wb25lbnRzIG9mIGEgdmVjM1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gbmVnYXRlXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG5lZ2F0ZShvdXQsIGEpIHtcbiAgb3V0WzBdID0gLWFbMF07XG4gIG91dFsxXSA9IC1hWzFdO1xuICBvdXRbMl0gPSAtYVsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgaW52ZXJzZSBvZiB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdmVjdG9yIHRvIGludmVydFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnZlcnNlKG91dCwgYSkge1xuICBvdXRbMF0gPSAxLjAgLyBhWzBdO1xuICBvdXRbMV0gPSAxLjAgLyBhWzFdO1xuICBvdXRbMl0gPSAxLjAgLyBhWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBOb3JtYWxpemUgYSB2ZWMzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHZlY3RvciB0byBub3JtYWxpemVcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKG91dCwgYSkge1xuICB2YXIgeCA9IGFbMF07XG4gIHZhciB5ID0gYVsxXTtcbiAgdmFyIHogPSBhWzJdO1xuICB2YXIgbGVuID0geCAqIHggKyB5ICogeSArIHogKiB6O1xuXG4gIGlmIChsZW4gPiAwKSB7XG4gICAgLy9UT0RPOiBldmFsdWF0ZSB1c2Ugb2YgZ2xtX2ludnNxcnQgaGVyZT9cbiAgICBsZW4gPSAxIC8gTWF0aC5zcXJ0KGxlbik7XG4gIH1cblxuICBvdXRbMF0gPSBhWzBdICogbGVuO1xuICBvdXRbMV0gPSBhWzFdICogbGVuO1xuICBvdXRbMl0gPSBhWzJdICogbGVuO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBkb3QgcHJvZHVjdCBvZiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gZG90IHByb2R1Y3Qgb2YgYSBhbmQgYlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkb3QoYSwgYikge1xuICByZXR1cm4gYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXSArIGFbMl0gKiBiWzJdO1xufVxuLyoqXG4gKiBDb21wdXRlcyB0aGUgY3Jvc3MgcHJvZHVjdCBvZiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3Jvc3Mob3V0LCBhLCBiKSB7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBheiA9IGFbMl07XG4gIHZhciBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICBieiA9IGJbMl07XG4gIG91dFswXSA9IGF5ICogYnogLSBheiAqIGJ5O1xuICBvdXRbMV0gPSBheiAqIGJ4IC0gYXggKiBiejtcbiAgb3V0WzJdID0gYXggKiBieSAtIGF5ICogYng7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIGludGVycG9sYXRpb24gYmV0d2VlbiB0d28gdmVjMydzXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSBmaXJzdCBvcGVyYW5kXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiB0aGUgc2Vjb25kIG9wZXJhbmRcbiAqIEBwYXJhbSB7TnVtYmVyfSB0IGludGVycG9sYXRpb24gYW1vdW50LCBpbiB0aGUgcmFuZ2UgWzAtMV0sIGJldHdlZW4gdGhlIHR3byBpbnB1dHNcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGVycChvdXQsIGEsIGIsIHQpIHtcbiAgdmFyIGF4ID0gYVswXTtcbiAgdmFyIGF5ID0gYVsxXTtcbiAgdmFyIGF6ID0gYVsyXTtcbiAgb3V0WzBdID0gYXggKyB0ICogKGJbMF0gLSBheCk7XG4gIG91dFsxXSA9IGF5ICsgdCAqIChiWzFdIC0gYXkpO1xuICBvdXRbMl0gPSBheiArIHQgKiAoYlsyXSAtIGF6KTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUGVyZm9ybXMgYSBoZXJtaXRlIGludGVycG9sYXRpb24gd2l0aCB0d28gY29udHJvbCBwb2ludHNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGMgdGhlIHRoaXJkIG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBkIHRoZSBmb3VydGggb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBoZXJtaXRlKG91dCwgYSwgYiwgYywgZCwgdCkge1xuICB2YXIgZmFjdG9yVGltZXMyID0gdCAqIHQ7XG4gIHZhciBmYWN0b3IxID0gZmFjdG9yVGltZXMyICogKDIgKiB0IC0gMykgKyAxO1xuICB2YXIgZmFjdG9yMiA9IGZhY3RvclRpbWVzMiAqICh0IC0gMikgKyB0O1xuICB2YXIgZmFjdG9yMyA9IGZhY3RvclRpbWVzMiAqICh0IC0gMSk7XG4gIHZhciBmYWN0b3I0ID0gZmFjdG9yVGltZXMyICogKDMgLSAyICogdCk7XG4gIG91dFswXSA9IGFbMF0gKiBmYWN0b3IxICsgYlswXSAqIGZhY3RvcjIgKyBjWzBdICogZmFjdG9yMyArIGRbMF0gKiBmYWN0b3I0O1xuICBvdXRbMV0gPSBhWzFdICogZmFjdG9yMSArIGJbMV0gKiBmYWN0b3IyICsgY1sxXSAqIGZhY3RvcjMgKyBkWzFdICogZmFjdG9yNDtcbiAgb3V0WzJdID0gYVsyXSAqIGZhY3RvcjEgKyBiWzJdICogZmFjdG9yMiArIGNbMl0gKiBmYWN0b3IzICsgZFsyXSAqIGZhY3RvcjQ7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFBlcmZvcm1zIGEgYmV6aWVyIGludGVycG9sYXRpb24gd2l0aCB0d28gY29udHJvbCBwb2ludHNcbiAqXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCB0aGUgcmVjZWl2aW5nIHZlY3RvclxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgdGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIHRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGMgdGhlIHRoaXJkIG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBkIHRoZSBmb3VydGggb3BlcmFuZFxuICogQHBhcmFtIHtOdW1iZXJ9IHQgaW50ZXJwb2xhdGlvbiBhbW91bnQsIGluIHRoZSByYW5nZSBbMC0xXSwgYmV0d2VlbiB0aGUgdHdvIGlucHV0c1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBiZXppZXIob3V0LCBhLCBiLCBjLCBkLCB0KSB7XG4gIHZhciBpbnZlcnNlRmFjdG9yID0gMSAtIHQ7XG4gIHZhciBpbnZlcnNlRmFjdG9yVGltZXNUd28gPSBpbnZlcnNlRmFjdG9yICogaW52ZXJzZUZhY3RvcjtcbiAgdmFyIGZhY3RvclRpbWVzMiA9IHQgKiB0O1xuICB2YXIgZmFjdG9yMSA9IGludmVyc2VGYWN0b3JUaW1lc1R3byAqIGludmVyc2VGYWN0b3I7XG4gIHZhciBmYWN0b3IyID0gMyAqIHQgKiBpbnZlcnNlRmFjdG9yVGltZXNUd287XG4gIHZhciBmYWN0b3IzID0gMyAqIGZhY3RvclRpbWVzMiAqIGludmVyc2VGYWN0b3I7XG4gIHZhciBmYWN0b3I0ID0gZmFjdG9yVGltZXMyICogdDtcbiAgb3V0WzBdID0gYVswXSAqIGZhY3RvcjEgKyBiWzBdICogZmFjdG9yMiArIGNbMF0gKiBmYWN0b3IzICsgZFswXSAqIGZhY3RvcjQ7XG4gIG91dFsxXSA9IGFbMV0gKiBmYWN0b3IxICsgYlsxXSAqIGZhY3RvcjIgKyBjWzFdICogZmFjdG9yMyArIGRbMV0gKiBmYWN0b3I0O1xuICBvdXRbMl0gPSBhWzJdICogZmFjdG9yMSArIGJbMl0gKiBmYWN0b3IyICsgY1syXSAqIGZhY3RvcjMgKyBkWzJdICogZmFjdG9yNDtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIHZlY3RvciB3aXRoIHRoZSBnaXZlbiBzY2FsZVxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge051bWJlcn0gW3NjYWxlXSBMZW5ndGggb2YgdGhlIHJlc3VsdGluZyB2ZWN0b3IuIElmIG9tbWl0dGVkLCBhIHVuaXQgdmVjdG9yIHdpbGwgYmUgcmV0dXJuZWRcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tKG91dCwgc2NhbGUpIHtcbiAgc2NhbGUgPSBzY2FsZSB8fCAxLjA7XG4gIHZhciByID0gZ2xNYXRyaXguUkFORE9NKCkgKiAyLjAgKiBNYXRoLlBJO1xuICB2YXIgeiA9IGdsTWF0cml4LlJBTkRPTSgpICogMi4wIC0gMS4wO1xuICB2YXIgelNjYWxlID0gTWF0aC5zcXJ0KDEuMCAtIHogKiB6KSAqIHNjYWxlO1xuICBvdXRbMF0gPSBNYXRoLmNvcyhyKSAqIHpTY2FsZTtcbiAgb3V0WzFdID0gTWF0aC5zaW4ocikgKiB6U2NhbGU7XG4gIG91dFsyXSA9IHogKiBzY2FsZTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgdmVjMyB3aXRoIGEgbWF0NC5cbiAqIDR0aCB2ZWN0b3IgY29tcG9uZW50IGlzIGltcGxpY2l0bHkgJzEnXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0NH0gbSBtYXRyaXggdG8gdHJhbnNmb3JtIHdpdGhcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtTWF0NChvdXQsIGEsIG0pIHtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTtcbiAgdmFyIHcgPSBtWzNdICogeCArIG1bN10gKiB5ICsgbVsxMV0gKiB6ICsgbVsxNV07XG4gIHcgPSB3IHx8IDEuMDtcbiAgb3V0WzBdID0gKG1bMF0gKiB4ICsgbVs0XSAqIHkgKyBtWzhdICogeiArIG1bMTJdKSAvIHc7XG4gIG91dFsxXSA9IChtWzFdICogeCArIG1bNV0gKiB5ICsgbVs5XSAqIHogKyBtWzEzXSkgLyB3O1xuICBvdXRbMl0gPSAobVsyXSAqIHggKyBtWzZdICogeSArIG1bMTBdICogeiArIG1bMTRdKSAvIHc7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIHZlYzMgd2l0aCBhIG1hdDMuXG4gKlxuICogQHBhcmFtIHt2ZWMzfSBvdXQgdGhlIHJlY2VpdmluZyB2ZWN0b3JcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIHRoZSB2ZWN0b3IgdG8gdHJhbnNmb3JtXG4gKiBAcGFyYW0ge1JlYWRvbmx5TWF0M30gbSB0aGUgM3gzIG1hdHJpeCB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1NYXQzKG91dCwgYSwgbSkge1xuICB2YXIgeCA9IGFbMF0sXG4gICAgICB5ID0gYVsxXSxcbiAgICAgIHogPSBhWzJdO1xuICBvdXRbMF0gPSB4ICogbVswXSArIHkgKiBtWzNdICsgeiAqIG1bNl07XG4gIG91dFsxXSA9IHggKiBtWzFdICsgeSAqIG1bNF0gKyB6ICogbVs3XTtcbiAgb3V0WzJdID0geCAqIG1bMl0gKyB5ICogbVs1XSArIHogKiBtWzhdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSB2ZWMzIHdpdGggYSBxdWF0XG4gKiBDYW4gYWxzbyBiZSB1c2VkIGZvciBkdWFsIHF1YXRlcm5pb25zLiAoTXVsdGlwbHkgaXQgd2l0aCB0aGUgcmVhbCBwYXJ0KVxuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB0aGUgdmVjdG9yIHRvIHRyYW5zZm9ybVxuICogQHBhcmFtIHtSZWFkb25seVF1YXR9IHEgcXVhdGVybmlvbiB0byB0cmFuc2Zvcm0gd2l0aFxuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1RdWF0KG91dCwgYSwgcSkge1xuICAvLyBiZW5jaG1hcmtzOiBodHRwczovL2pzcGVyZi5jb20vcXVhdGVybmlvbi10cmFuc2Zvcm0tdmVjMy1pbXBsZW1lbnRhdGlvbnMtZml4ZWRcbiAgdmFyIHF4ID0gcVswXSxcbiAgICAgIHF5ID0gcVsxXSxcbiAgICAgIHF6ID0gcVsyXSxcbiAgICAgIHF3ID0gcVszXTtcbiAgdmFyIHggPSBhWzBdLFxuICAgICAgeSA9IGFbMV0sXG4gICAgICB6ID0gYVsyXTsgLy8gdmFyIHF2ZWMgPSBbcXgsIHF5LCBxel07XG4gIC8vIHZhciB1diA9IHZlYzMuY3Jvc3MoW10sIHF2ZWMsIGEpO1xuXG4gIHZhciB1dnggPSBxeSAqIHogLSBxeiAqIHksXG4gICAgICB1dnkgPSBxeiAqIHggLSBxeCAqIHosXG4gICAgICB1dnogPSBxeCAqIHkgLSBxeSAqIHg7IC8vIHZhciB1dXYgPSB2ZWMzLmNyb3NzKFtdLCBxdmVjLCB1dik7XG5cbiAgdmFyIHV1dnggPSBxeSAqIHV2eiAtIHF6ICogdXZ5LFxuICAgICAgdXV2eSA9IHF6ICogdXZ4IC0gcXggKiB1dnosXG4gICAgICB1dXZ6ID0gcXggKiB1dnkgLSBxeSAqIHV2eDsgLy8gdmVjMy5zY2FsZSh1diwgdXYsIDIgKiB3KTtcblxuICB2YXIgdzIgPSBxdyAqIDI7XG4gIHV2eCAqPSB3MjtcbiAgdXZ5ICo9IHcyO1xuICB1dnogKj0gdzI7IC8vIHZlYzMuc2NhbGUodXV2LCB1dXYsIDIpO1xuXG4gIHV1dnggKj0gMjtcbiAgdXV2eSAqPSAyO1xuICB1dXZ6ICo9IDI7IC8vIHJldHVybiB2ZWMzLmFkZChvdXQsIGEsIHZlYzMuYWRkKG91dCwgdXYsIHV1dikpO1xuXG4gIG91dFswXSA9IHggKyB1dnggKyB1dXZ4O1xuICBvdXRbMV0gPSB5ICsgdXZ5ICsgdXV2eTtcbiAgb3V0WzJdID0geiArIHV2eiArIHV1dno7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJvdGF0ZSBhIDNEIHZlY3RvciBhcm91bmQgdGhlIHgtYXhpc1xuICogQHBhcmFtIHt2ZWMzfSBvdXQgVGhlIHJlY2VpdmluZyB2ZWMzXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSBUaGUgdmVjMyBwb2ludCB0byByb3RhdGVcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBvcmlnaW4gb2YgdGhlIHJvdGF0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gcmFkIFRoZSBhbmdsZSBvZiByb3RhdGlvbiBpbiByYWRpYW5zXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZVgob3V0LCBhLCBiLCByYWQpIHtcbiAgdmFyIHAgPSBbXSxcbiAgICAgIHIgPSBbXTsgLy9UcmFuc2xhdGUgcG9pbnQgdG8gdGhlIG9yaWdpblxuXG4gIHBbMF0gPSBhWzBdIC0gYlswXTtcbiAgcFsxXSA9IGFbMV0gLSBiWzFdO1xuICBwWzJdID0gYVsyXSAtIGJbMl07IC8vcGVyZm9ybSByb3RhdGlvblxuXG4gIHJbMF0gPSBwWzBdO1xuICByWzFdID0gcFsxXSAqIE1hdGguY29zKHJhZCkgLSBwWzJdICogTWF0aC5zaW4ocmFkKTtcbiAgclsyXSA9IHBbMV0gKiBNYXRoLnNpbihyYWQpICsgcFsyXSAqIE1hdGguY29zKHJhZCk7IC8vdHJhbnNsYXRlIHRvIGNvcnJlY3QgcG9zaXRpb25cblxuICBvdXRbMF0gPSByWzBdICsgYlswXTtcbiAgb3V0WzFdID0gclsxXSArIGJbMV07XG4gIG91dFsyXSA9IHJbMl0gKyBiWzJdO1xuICByZXR1cm4gb3V0O1xufVxuLyoqXG4gKiBSb3RhdGUgYSAzRCB2ZWN0b3IgYXJvdW5kIHRoZSB5LWF4aXNcbiAqIEBwYXJhbSB7dmVjM30gb3V0IFRoZSByZWNlaXZpbmcgdmVjM1xuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgVGhlIHZlYzMgcG9pbnQgdG8gcm90YXRlXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiBUaGUgb3JpZ2luIG9mIHRoZSByb3RhdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IHJhZCBUaGUgYW5nbGUgb2Ygcm90YXRpb24gaW4gcmFkaWFuc1xuICogQHJldHVybnMge3ZlYzN9IG91dFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVZKG91dCwgYSwgYiwgcmFkKSB7XG4gIHZhciBwID0gW10sXG4gICAgICByID0gW107IC8vVHJhbnNsYXRlIHBvaW50IHRvIHRoZSBvcmlnaW5cblxuICBwWzBdID0gYVswXSAtIGJbMF07XG4gIHBbMV0gPSBhWzFdIC0gYlsxXTtcbiAgcFsyXSA9IGFbMl0gLSBiWzJdOyAvL3BlcmZvcm0gcm90YXRpb25cblxuICByWzBdID0gcFsyXSAqIE1hdGguc2luKHJhZCkgKyBwWzBdICogTWF0aC5jb3MocmFkKTtcbiAgclsxXSA9IHBbMV07XG4gIHJbMl0gPSBwWzJdICogTWF0aC5jb3MocmFkKSAtIHBbMF0gKiBNYXRoLnNpbihyYWQpOyAvL3RyYW5zbGF0ZSB0byBjb3JyZWN0IHBvc2l0aW9uXG5cbiAgb3V0WzBdID0gclswXSArIGJbMF07XG4gIG91dFsxXSA9IHJbMV0gKyBiWzFdO1xuICBvdXRbMl0gPSByWzJdICsgYlsyXTtcbiAgcmV0dXJuIG91dDtcbn1cbi8qKlxuICogUm90YXRlIGEgM0QgdmVjdG9yIGFyb3VuZCB0aGUgei1heGlzXG4gKiBAcGFyYW0ge3ZlYzN9IG91dCBUaGUgcmVjZWl2aW5nIHZlYzNcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSB2ZWMzIHBvaW50IHRvIHJvdGF0ZVxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGIgVGhlIG9yaWdpbiBvZiB0aGUgcm90YXRpb25cbiAqIEBwYXJhbSB7TnVtYmVyfSByYWQgVGhlIGFuZ2xlIG9mIHJvdGF0aW9uIGluIHJhZGlhbnNcbiAqIEByZXR1cm5zIHt2ZWMzfSBvdXRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlWihvdXQsIGEsIGIsIHJhZCkge1xuICB2YXIgcCA9IFtdLFxuICAgICAgciA9IFtdOyAvL1RyYW5zbGF0ZSBwb2ludCB0byB0aGUgb3JpZ2luXG5cbiAgcFswXSA9IGFbMF0gLSBiWzBdO1xuICBwWzFdID0gYVsxXSAtIGJbMV07XG4gIHBbMl0gPSBhWzJdIC0gYlsyXTsgLy9wZXJmb3JtIHJvdGF0aW9uXG5cbiAgclswXSA9IHBbMF0gKiBNYXRoLmNvcyhyYWQpIC0gcFsxXSAqIE1hdGguc2luKHJhZCk7XG4gIHJbMV0gPSBwWzBdICogTWF0aC5zaW4ocmFkKSArIHBbMV0gKiBNYXRoLmNvcyhyYWQpO1xuICByWzJdID0gcFsyXTsgLy90cmFuc2xhdGUgdG8gY29ycmVjdCBwb3NpdGlvblxuXG4gIG91dFswXSA9IHJbMF0gKyBiWzBdO1xuICBvdXRbMV0gPSByWzFdICsgYlsxXTtcbiAgb3V0WzJdID0gclsyXSArIGJbMl07XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIEdldCB0aGUgYW5nbGUgYmV0d2VlbiB0d28gM0QgdmVjdG9yc1xuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgVGhlIGZpcnN0IG9wZXJhbmRcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBzZWNvbmQgb3BlcmFuZFxuICogQHJldHVybnMge051bWJlcn0gVGhlIGFuZ2xlIGluIHJhZGlhbnNcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYW5nbGUoYSwgYikge1xuICB2YXIgYXggPSBhWzBdLFxuICAgICAgYXkgPSBhWzFdLFxuICAgICAgYXogPSBhWzJdLFxuICAgICAgYnggPSBiWzBdLFxuICAgICAgYnkgPSBiWzFdLFxuICAgICAgYnogPSBiWzJdLFxuICAgICAgbWFnMSA9IE1hdGguc3FydChheCAqIGF4ICsgYXkgKiBheSArIGF6ICogYXopLFxuICAgICAgbWFnMiA9IE1hdGguc3FydChieCAqIGJ4ICsgYnkgKiBieSArIGJ6ICogYnopLFxuICAgICAgbWFnID0gbWFnMSAqIG1hZzIsXG4gICAgICBjb3NpbmUgPSBtYWcgJiYgZG90KGEsIGIpIC8gbWFnO1xuICByZXR1cm4gTWF0aC5hY29zKE1hdGgubWluKE1hdGgubWF4KGNvc2luZSwgLTEpLCAxKSk7XG59XG4vKipcbiAqIFNldCB0aGUgY29tcG9uZW50cyBvZiBhIHZlYzMgdG8gemVyb1xuICpcbiAqIEBwYXJhbSB7dmVjM30gb3V0IHRoZSByZWNlaXZpbmcgdmVjdG9yXG4gKiBAcmV0dXJucyB7dmVjM30gb3V0XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHplcm8ob3V0KSB7XG4gIG91dFswXSA9IDAuMDtcbiAgb3V0WzFdID0gMC4wO1xuICBvdXRbMl0gPSAwLjA7XG4gIHJldHVybiBvdXQ7XG59XG4vKipcbiAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB2ZWN0b3JcbiAqXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYSB2ZWN0b3IgdG8gcmVwcmVzZW50IGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZlY3RvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzdHIoYSkge1xuICByZXR1cm4gXCJ2ZWMzKFwiICsgYVswXSArIFwiLCBcIiArIGFbMV0gKyBcIiwgXCIgKyBhWzJdICsgXCIpXCI7XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHZlY3RvcnMgaGF2ZSBleGFjdGx5IHRoZSBzYW1lIGVsZW1lbnRzIGluIHRoZSBzYW1lIHBvc2l0aW9uICh3aGVuIGNvbXBhcmVkIHdpdGggPT09KVxuICpcbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBhIFRoZSBmaXJzdCB2ZWN0b3IuXG4gKiBAcGFyYW0ge1JlYWRvbmx5VmVjM30gYiBUaGUgc2Vjb25kIHZlY3Rvci5cbiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmIHRoZSB2ZWN0b3JzIGFyZSBlcXVhbCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleGFjdEVxdWFscyhhLCBiKSB7XG4gIHJldHVybiBhWzBdID09PSBiWzBdICYmIGFbMV0gPT09IGJbMV0gJiYgYVsyXSA9PT0gYlsyXTtcbn1cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgdmVjdG9ycyBoYXZlIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgZWxlbWVudHMgaW4gdGhlIHNhbWUgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtSZWFkb25seVZlYzN9IGEgVGhlIGZpcnN0IHZlY3Rvci5cbiAqIEBwYXJhbSB7UmVhZG9ubHlWZWMzfSBiIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWYgdGhlIHZlY3RvcnMgYXJlIGVxdWFsLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhLCBiKSB7XG4gIHZhciBhMCA9IGFbMF0sXG4gICAgICBhMSA9IGFbMV0sXG4gICAgICBhMiA9IGFbMl07XG4gIHZhciBiMCA9IGJbMF0sXG4gICAgICBiMSA9IGJbMV0sXG4gICAgICBiMiA9IGJbMl07XG4gIHJldHVybiBNYXRoLmFicyhhMCAtIGIwKSA8PSBnbE1hdHJpeC5FUFNJTE9OICogTWF0aC5tYXgoMS4wLCBNYXRoLmFicyhhMCksIE1hdGguYWJzKGIwKSkgJiYgTWF0aC5hYnMoYTEgLSBiMSkgPD0gZ2xNYXRyaXguRVBTSUxPTiAqIE1hdGgubWF4KDEuMCwgTWF0aC5hYnMoYTEpLCBNYXRoLmFicyhiMSkpICYmIE1hdGguYWJzKGEyIC0gYjIpIDw9IGdsTWF0cml4LkVQU0lMT04gKiBNYXRoLm1heCgxLjAsIE1hdGguYWJzKGEyKSwgTWF0aC5hYnMoYjIpKTtcbn1cbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLnN1YnRyYWN0fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBzdWIgPSBzdWJ0cmFjdDtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLm11bHRpcGx5fVxuICogQGZ1bmN0aW9uXG4gKi9cblxuZXhwb3J0IHZhciBtdWwgPSBtdWx0aXBseTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLmRpdmlkZX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgZGl2ID0gZGl2aWRlO1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMuZGlzdGFuY2V9XG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGRpc3QgPSBkaXN0YW5jZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLnNxdWFyZWREaXN0YW5jZX1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3FyRGlzdCA9IHNxdWFyZWREaXN0YW5jZTtcbi8qKlxuICogQWxpYXMgZm9yIHtAbGluayB2ZWMzLmxlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgbGVuID0gbGVuZ3RoO1xuLyoqXG4gKiBBbGlhcyBmb3Ige0BsaW5rIHZlYzMuc3F1YXJlZExlbmd0aH1cbiAqIEBmdW5jdGlvblxuICovXG5cbmV4cG9ydCB2YXIgc3FyTGVuID0gc3F1YXJlZExlbmd0aDtcbi8qKlxuICogUGVyZm9ybSBzb21lIG9wZXJhdGlvbiBvdmVyIGFuIGFycmF5IG9mIHZlYzNzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGEgdGhlIGFycmF5IG9mIHZlY3RvcnMgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0ge051bWJlcn0gc3RyaWRlIE51bWJlciBvZiBlbGVtZW50cyBiZXR3ZWVuIHRoZSBzdGFydCBvZiBlYWNoIHZlYzMuIElmIDAgYXNzdW1lcyB0aWdodGx5IHBhY2tlZFxuICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gc2tpcCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBhcnJheVxuICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50IE51bWJlciBvZiB2ZWMzcyB0byBpdGVyYXRlIG92ZXIuIElmIDAgaXRlcmF0ZXMgb3ZlciBlbnRpcmUgYXJyYXlcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggdmVjdG9yIGluIHRoZSBhcnJheVxuICogQHBhcmFtIHtPYmplY3R9IFthcmddIGFkZGl0aW9uYWwgYXJndW1lbnQgdG8gcGFzcyB0byBmblxuICogQHJldHVybnMge0FycmF5fSBhXG4gKiBAZnVuY3Rpb25cbiAqL1xuXG5leHBvcnQgdmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB2ZWMgPSBjcmVhdGUoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhLCBzdHJpZGUsIG9mZnNldCwgY291bnQsIGZuLCBhcmcpIHtcbiAgICB2YXIgaSwgbDtcblxuICAgIGlmICghc3RyaWRlKSB7XG4gICAgICBzdHJpZGUgPSAzO1xuICAgIH1cblxuICAgIGlmICghb2Zmc2V0KSB7XG4gICAgICBvZmZzZXQgPSAwO1xuICAgIH1cblxuICAgIGlmIChjb3VudCkge1xuICAgICAgbCA9IE1hdGgubWluKGNvdW50ICogc3RyaWRlICsgb2Zmc2V0LCBhLmxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGwgPSBhLmxlbmd0aDtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSBvZmZzZXQ7IGkgPCBsOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmVjWzBdID0gYVtpXTtcbiAgICAgIHZlY1sxXSA9IGFbaSArIDFdO1xuICAgICAgdmVjWzJdID0gYVtpICsgMl07XG4gICAgICBmbih2ZWMsIHZlYywgYXJnKTtcbiAgICAgIGFbaV0gPSB2ZWNbMF07XG4gICAgICBhW2kgKyAxXSA9IHZlY1sxXTtcbiAgICAgIGFbaSArIDJdID0gdmVjWzJdO1xuICAgIH1cblxuICAgIHJldHVybiBhO1xuICB9O1xufSgpOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///39\n')},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nexports.STACK_OVERFLOW = exports.CIRCULAR_DEPENDENCY_IN_FACTORY = exports.POST_CONSTRUCT_ERROR = exports.MULTIPLE_POST_CONSTRUCT_METHODS = exports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = exports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = exports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = exports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = exports.ARGUMENTS_LENGTH_MISMATCH = exports.INVALID_DECORATOR_OPERATION = exports.INVALID_TO_SELF_VALUE = exports.INVALID_FUNCTION_BINDING = exports.INVALID_MIDDLEWARE_RETURN = exports.NO_MORE_SNAPSHOTS_AVAILABLE = exports.INVALID_BINDING_TYPE = exports.NOT_IMPLEMENTED = exports.CIRCULAR_DEPENDENCY = exports.UNDEFINED_INJECT_ANNOTATION = exports.MISSING_INJECT_ANNOTATION = exports.MISSING_INJECTABLE_ANNOTATION = exports.NOT_REGISTERED = exports.CANNOT_UNBIND = exports.AMBIGUOUS_MATCH = exports.KEY_NOT_FOUND = exports.NULL_ARGUMENT = exports.DUPLICATED_METADATA = exports.DUPLICATED_INJECTABLE_DECORATOR = void 0;\nexports.DUPLICATED_INJECTABLE_DECORATOR = "Cannot apply @injectable decorator multiple times.";\nexports.DUPLICATED_METADATA = "Metadata key was used more than once in a parameter:";\nexports.NULL_ARGUMENT = "NULL argument";\nexports.KEY_NOT_FOUND = "Key Not Found";\nexports.AMBIGUOUS_MATCH = "Ambiguous match found for serviceIdentifier:";\nexports.CANNOT_UNBIND = "Could not unbind serviceIdentifier:";\nexports.NOT_REGISTERED = "No matching bindings found for serviceIdentifier:";\nexports.MISSING_INJECTABLE_ANNOTATION = "Missing required @injectable annotation in:";\nexports.MISSING_INJECT_ANNOTATION = "Missing required @inject or @multiInject annotation in:";\nvar UNDEFINED_INJECT_ANNOTATION = function (name) {\n return "@inject called with undefined this could mean that the class " + name + " has " +\n "a circular dependency problem. You can use a LazyServiceIdentifer to " +\n "overcome this limitation.";\n};\nexports.UNDEFINED_INJECT_ANNOTATION = UNDEFINED_INJECT_ANNOTATION;\nexports.CIRCULAR_DEPENDENCY = "Circular dependency found:";\nexports.NOT_IMPLEMENTED = "Sorry, this feature is not fully implemented yet.";\nexports.INVALID_BINDING_TYPE = "Invalid binding type:";\nexports.NO_MORE_SNAPSHOTS_AVAILABLE = "No snapshot available to restore.";\nexports.INVALID_MIDDLEWARE_RETURN = "Invalid return type in middleware. Middleware must return!";\nexports.INVALID_FUNCTION_BINDING = "Value provided to function binding must be a function!";\nexports.INVALID_TO_SELF_VALUE = "The toSelf function can only be applied when a constructor is " +\n "used as service identifier";\nexports.INVALID_DECORATOR_OPERATION = "The @inject @multiInject @tagged and @named decorators " +\n "must be applied to the parameters of a class constructor or a class property.";\nvar ARGUMENTS_LENGTH_MISMATCH = function () {\n var values = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n values[_i] = arguments[_i];\n }\n return "The number of constructor arguments in the derived class " +\n (values[0] + " must be >= than the number of constructor arguments of its base class.");\n};\nexports.ARGUMENTS_LENGTH_MISMATCH = ARGUMENTS_LENGTH_MISMATCH;\nexports.CONTAINER_OPTIONS_MUST_BE_AN_OBJECT = "Invalid Container constructor argument. Container options " +\n "must be an object.";\nexports.CONTAINER_OPTIONS_INVALID_DEFAULT_SCOPE = "Invalid Container option. Default scope must " +\n "be a string (\'singleton\' or \'transient\').";\nexports.CONTAINER_OPTIONS_INVALID_AUTO_BIND_INJECTABLE = "Invalid Container option. Auto bind injectable must " +\n "be a boolean";\nexports.CONTAINER_OPTIONS_INVALID_SKIP_BASE_CHECK = "Invalid Container option. Skip base check must " +\n "be a boolean";\nexports.MULTIPLE_POST_CONSTRUCT_METHODS = "Cannot apply @postConstruct decorator multiple times in the same class";\nvar POST_CONSTRUCT_ERROR = function () {\n var values = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n values[_i] = arguments[_i];\n }\n return "@postConstruct error in class " + values[0] + ": " + values[1];\n};\nexports.POST_CONSTRUCT_ERROR = POST_CONSTRUCT_ERROR;\nvar CIRCULAR_DEPENDENCY_IN_FACTORY = function () {\n var values = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n values[_i] = arguments[_i];\n }\n return "It looks like there is a circular dependency " +\n ("in one of the \'" + values[0] + "\' bindings. Please investigate bindings with") +\n ("service identifier \'" + values[1] + "\'.");\n};\nexports.CIRCULAR_DEPENDENCY_IN_FACTORY = CIRCULAR_DEPENDENCY_IN_FACTORY;\nexports.STACK_OVERFLOW = "Maximum call stack size exceeded";\n//# sourceMappingURL=error_msgs.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9jb25zdGFudHMvZXJyb3JfbXNncy5qcz8zMGUzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsdUJBQXVCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsdUJBQXVCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLHVCQUF1QjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiNDAuanMiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuU1RBQ0tfT1ZFUkZMT1cgPSBleHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWSA9IGV4cG9ydHMuUE9TVF9DT05TVFJVQ1RfRVJST1IgPSBleHBvcnRzLk1VTFRJUExFX1BPU1RfQ09OU1RSVUNUX01FVEhPRFMgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLID0gZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0FVVE9fQklORF9JTkpFQ1RBQkxFID0gZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0RFRkFVTFRfU0NPUEUgPSBleHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX01VU1RfQkVfQU5fT0JKRUNUID0gZXhwb3J0cy5BUkdVTUVOVFNfTEVOR1RIX01JU01BVENIID0gZXhwb3J0cy5JTlZBTElEX0RFQ09SQVRPUl9PUEVSQVRJT04gPSBleHBvcnRzLklOVkFMSURfVE9fU0VMRl9WQUxVRSA9IGV4cG9ydHMuSU5WQUxJRF9GVU5DVElPTl9CSU5ESU5HID0gZXhwb3J0cy5JTlZBTElEX01JRERMRVdBUkVfUkVUVVJOID0gZXhwb3J0cy5OT19NT1JFX1NOQVBTSE9UU19BVkFJTEFCTEUgPSBleHBvcnRzLklOVkFMSURfQklORElOR19UWVBFID0gZXhwb3J0cy5OT1RfSU1QTEVNRU5URUQgPSBleHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1kgPSBleHBvcnRzLlVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTiA9IGV4cG9ydHMuTUlTU0lOR19JTkpFQ1RfQU5OT1RBVElPTiA9IGV4cG9ydHMuTUlTU0lOR19JTkpFQ1RBQkxFX0FOTk9UQVRJT04gPSBleHBvcnRzLk5PVF9SRUdJU1RFUkVEID0gZXhwb3J0cy5DQU5OT1RfVU5CSU5EID0gZXhwb3J0cy5BTUJJR1VPVVNfTUFUQ0ggPSBleHBvcnRzLktFWV9OT1RfRk9VTkQgPSBleHBvcnRzLk5VTExfQVJHVU1FTlQgPSBleHBvcnRzLkRVUExJQ0FURURfTUVUQURBVEEgPSBleHBvcnRzLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IgPSB2b2lkIDA7XG5leHBvcnRzLkRVUExJQ0FURURfSU5KRUNUQUJMRV9ERUNPUkFUT1IgPSBcIkNhbm5vdCBhcHBseSBAaW5qZWN0YWJsZSBkZWNvcmF0b3IgbXVsdGlwbGUgdGltZXMuXCI7XG5leHBvcnRzLkRVUExJQ0FURURfTUVUQURBVEEgPSBcIk1ldGFkYXRhIGtleSB3YXMgdXNlZCBtb3JlIHRoYW4gb25jZSBpbiBhIHBhcmFtZXRlcjpcIjtcbmV4cG9ydHMuTlVMTF9BUkdVTUVOVCA9IFwiTlVMTCBhcmd1bWVudFwiO1xuZXhwb3J0cy5LRVlfTk9UX0ZPVU5EID0gXCJLZXkgTm90IEZvdW5kXCI7XG5leHBvcnRzLkFNQklHVU9VU19NQVRDSCA9IFwiQW1iaWd1b3VzIG1hdGNoIGZvdW5kIGZvciBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuQ0FOTk9UX1VOQklORCA9IFwiQ291bGQgbm90IHVuYmluZCBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuTk9UX1JFR0lTVEVSRUQgPSBcIk5vIG1hdGNoaW5nIGJpbmRpbmdzIGZvdW5kIGZvciBzZXJ2aWNlSWRlbnRpZmllcjpcIjtcbmV4cG9ydHMuTUlTU0lOR19JTkpFQ1RBQkxFX0FOTk9UQVRJT04gPSBcIk1pc3NpbmcgcmVxdWlyZWQgQGluamVjdGFibGUgYW5ub3RhdGlvbiBpbjpcIjtcbmV4cG9ydHMuTUlTU0lOR19JTkpFQ1RfQU5OT1RBVElPTiA9IFwiTWlzc2luZyByZXF1aXJlZCBAaW5qZWN0IG9yIEBtdWx0aUluamVjdCBhbm5vdGF0aW9uIGluOlwiO1xudmFyIFVOREVGSU5FRF9JTkpFQ1RfQU5OT1RBVElPTiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgcmV0dXJuIFwiQGluamVjdCBjYWxsZWQgd2l0aCB1bmRlZmluZWQgdGhpcyBjb3VsZCBtZWFuIHRoYXQgdGhlIGNsYXNzIFwiICsgbmFtZSArIFwiIGhhcyBcIiArXG4gICAgICAgIFwiYSBjaXJjdWxhciBkZXBlbmRlbmN5IHByb2JsZW0uIFlvdSBjYW4gdXNlIGEgTGF6eVNlcnZpY2VJZGVudGlmZXIgdG8gIFwiICtcbiAgICAgICAgXCJvdmVyY29tZSB0aGlzIGxpbWl0YXRpb24uXCI7XG59O1xuZXhwb3J0cy5VTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT04gPSBVTkRFRklORURfSU5KRUNUX0FOTk9UQVRJT047XG5leHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1kgPSBcIkNpcmN1bGFyIGRlcGVuZGVuY3kgZm91bmQ6XCI7XG5leHBvcnRzLk5PVF9JTVBMRU1FTlRFRCA9IFwiU29ycnksIHRoaXMgZmVhdHVyZSBpcyBub3QgZnVsbHkgaW1wbGVtZW50ZWQgeWV0LlwiO1xuZXhwb3J0cy5JTlZBTElEX0JJTkRJTkdfVFlQRSA9IFwiSW52YWxpZCBiaW5kaW5nIHR5cGU6XCI7XG5leHBvcnRzLk5PX01PUkVfU05BUFNIT1RTX0FWQUlMQUJMRSA9IFwiTm8gc25hcHNob3QgYXZhaWxhYmxlIHRvIHJlc3RvcmUuXCI7XG5leHBvcnRzLklOVkFMSURfTUlERExFV0FSRV9SRVRVUk4gPSBcIkludmFsaWQgcmV0dXJuIHR5cGUgaW4gbWlkZGxld2FyZS4gTWlkZGxld2FyZSBtdXN0IHJldHVybiFcIjtcbmV4cG9ydHMuSU5WQUxJRF9GVU5DVElPTl9CSU5ESU5HID0gXCJWYWx1ZSBwcm92aWRlZCB0byBmdW5jdGlvbiBiaW5kaW5nIG11c3QgYmUgYSBmdW5jdGlvbiFcIjtcbmV4cG9ydHMuSU5WQUxJRF9UT19TRUxGX1ZBTFVFID0gXCJUaGUgdG9TZWxmIGZ1bmN0aW9uIGNhbiBvbmx5IGJlIGFwcGxpZWQgd2hlbiBhIGNvbnN0cnVjdG9yIGlzIFwiICtcbiAgICBcInVzZWQgYXMgc2VydmljZSBpZGVudGlmaWVyXCI7XG5leHBvcnRzLklOVkFMSURfREVDT1JBVE9SX09QRVJBVElPTiA9IFwiVGhlIEBpbmplY3QgQG11bHRpSW5qZWN0IEB0YWdnZWQgYW5kIEBuYW1lZCBkZWNvcmF0b3JzIFwiICtcbiAgICBcIm11c3QgYmUgYXBwbGllZCB0byB0aGUgcGFyYW1ldGVycyBvZiBhIGNsYXNzIGNvbnN0cnVjdG9yIG9yIGEgY2xhc3MgcHJvcGVydHkuXCI7XG52YXIgQVJHVU1FTlRTX0xFTkdUSF9NSVNNQVRDSCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdmFsdWVzID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgdmFsdWVzW19pXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgfVxuICAgIHJldHVybiBcIlRoZSBudW1iZXIgb2YgY29uc3RydWN0b3IgYXJndW1lbnRzIGluIHRoZSBkZXJpdmVkIGNsYXNzIFwiICtcbiAgICAgICAgKHZhbHVlc1swXSArIFwiIG11c3QgYmUgPj0gdGhhbiB0aGUgbnVtYmVyIG9mIGNvbnN0cnVjdG9yIGFyZ3VtZW50cyBvZiBpdHMgYmFzZSBjbGFzcy5cIik7XG59O1xuZXhwb3J0cy5BUkdVTUVOVFNfTEVOR1RIX01JU01BVENIID0gQVJHVU1FTlRTX0xFTkdUSF9NSVNNQVRDSDtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfTVVTVF9CRV9BTl9PQkpFQ1QgPSBcIkludmFsaWQgQ29udGFpbmVyIGNvbnN0cnVjdG9yIGFyZ3VtZW50LiBDb250YWluZXIgb3B0aW9ucyBcIiArXG4gICAgXCJtdXN0IGJlIGFuIG9iamVjdC5cIjtcbmV4cG9ydHMuQ09OVEFJTkVSX09QVElPTlNfSU5WQUxJRF9ERUZBVUxUX1NDT1BFID0gXCJJbnZhbGlkIENvbnRhaW5lciBvcHRpb24uIERlZmF1bHQgc2NvcGUgbXVzdCBcIiArXG4gICAgXCJiZSBhIHN0cmluZyAoJ3NpbmdsZXRvbicgb3IgJ3RyYW5zaWVudCcpLlwiO1xuZXhwb3J0cy5DT05UQUlORVJfT1BUSU9OU19JTlZBTElEX0FVVE9fQklORF9JTkpFQ1RBQkxFID0gXCJJbnZhbGlkIENvbnRhaW5lciBvcHRpb24uIEF1dG8gYmluZCBpbmplY3RhYmxlIG11c3QgXCIgK1xuICAgIFwiYmUgYSBib29sZWFuXCI7XG5leHBvcnRzLkNPTlRBSU5FUl9PUFRJT05TX0lOVkFMSURfU0tJUF9CQVNFX0NIRUNLID0gXCJJbnZhbGlkIENvbnRhaW5lciBvcHRpb24uIFNraXAgYmFzZSBjaGVjayBtdXN0IFwiICtcbiAgICBcImJlIGEgYm9vbGVhblwiO1xuZXhwb3J0cy5NVUxUSVBMRV9QT1NUX0NPTlNUUlVDVF9NRVRIT0RTID0gXCJDYW5ub3QgYXBwbHkgQHBvc3RDb25zdHJ1Y3QgZGVjb3JhdG9yIG11bHRpcGxlIHRpbWVzIGluIHRoZSBzYW1lIGNsYXNzXCI7XG52YXIgUE9TVF9DT05TVFJVQ1RfRVJST1IgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgIHZhbHVlc1tfaV0gPSBhcmd1bWVudHNbX2ldO1xuICAgIH1cbiAgICByZXR1cm4gXCJAcG9zdENvbnN0cnVjdCBlcnJvciBpbiBjbGFzcyBcIiArIHZhbHVlc1swXSArIFwiOiBcIiArIHZhbHVlc1sxXTtcbn07XG5leHBvcnRzLlBPU1RfQ09OU1RSVUNUX0VSUk9SID0gUE9TVF9DT05TVFJVQ1RfRVJST1I7XG52YXIgQ0lSQ1VMQVJfREVQRU5ERU5DWV9JTl9GQUNUT1JZID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBbXTtcbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICB2YWx1ZXNbX2ldID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIFwiSXQgbG9va3MgbGlrZSB0aGVyZSBpcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgXCIgK1xuICAgICAgICAoXCJpbiBvbmUgb2YgdGhlICdcIiArIHZhbHVlc1swXSArIFwiJyBiaW5kaW5ncy4gUGxlYXNlIGludmVzdGlnYXRlIGJpbmRpbmdzIHdpdGhcIikgK1xuICAgICAgICAoXCJzZXJ2aWNlIGlkZW50aWZpZXIgJ1wiICsgdmFsdWVzWzFdICsgXCInLlwiKTtcbn07XG5leHBvcnRzLkNJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWSA9IENJUkNVTEFSX0RFUEVOREVOQ1lfSU5fRkFDVE9SWTtcbmV4cG9ydHMuU1RBQ0tfT1ZFUkZMT1cgPSBcIk1heGltdW0gY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lcnJvcl9tc2dzLmpzLm1hcCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///40\n')},function(module,exports){eval('function _typeof(obj) {\n "@babel/helpers - typeof";\n\n if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {\n module.exports = _typeof = function _typeof(obj) {\n return typeof obj;\n };\n\n module.exports["default"] = module.exports, module.exports.__esModule = true;\n } else {\n module.exports = _typeof = function _typeof(obj) {\n return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n };\n\n module.exports["default"] = module.exports, module.exports.__esModule = true;\n }\n\n return _typeof(obj);\n}\n\nmodule.exports = _typeof;\nmodule.exports["default"] = module.exports, module.exports.__esModule = true;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2YuanM/NzAzNyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiI0MS5qcyIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gIFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjtcblxuICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgICAgcmV0dXJuIHR5cGVvZiBvYmo7XG4gICAgfTtcblxuICAgIG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IF90eXBlb2YgPSBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7XG4gICAgfTtcblxuICAgIG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBfdHlwZW9mKG9iaik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3R5cGVvZjtcbm1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///41\n')},function(module,exports,__webpack_require__){eval("/* global window */\n\nvar lodash;\n\nif (true) {\n try {\n lodash = {\n clone: __webpack_require__(323),\n constant: __webpack_require__(163),\n each: __webpack_require__(204),\n filter: __webpack_require__(207),\n has: __webpack_require__(218),\n isArray: __webpack_require__(31),\n isEmpty: __webpack_require__(399),\n isFunction: __webpack_require__(86),\n isUndefined: __webpack_require__(219),\n keys: __webpack_require__(59),\n map: __webpack_require__(220),\n reduce: __webpack_require__(222),\n size: __webpack_require__(402),\n transform: __webpack_require__(408),\n union: __webpack_require__(409),\n values: __webpack_require__(227)\n };\n } catch (e) {\n // continue regardless of error\n }\n}\n\nif (!lodash) {\n lodash = window._;\n}\n\nmodule.exports = lodash;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZ3JhcGhsaWIvbGliL2xvZGFzaC5qcz8zM2RlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBOztBQUVBLElBQUksSUFBNkI7QUFDakM7QUFDQTtBQUNBLGFBQWEsbUJBQU8sQ0FBQyxHQUFjO0FBQ25DLGdCQUFnQixtQkFBTyxDQUFDLEdBQWlCO0FBQ3pDLFlBQVksbUJBQU8sQ0FBQyxHQUFhO0FBQ2pDLGNBQWMsbUJBQU8sQ0FBQyxHQUFlO0FBQ3JDLFlBQVksbUJBQU8sQ0FBQyxHQUFZO0FBQ2hDLGVBQWUsbUJBQU8sQ0FBQyxFQUFnQjtBQUN2QyxlQUFlLG1CQUFPLENBQUMsR0FBZ0I7QUFDdkMsa0JBQWtCLG1CQUFPLENBQUMsRUFBbUI7QUFDN0MsbUJBQW1CLG1CQUFPLENBQUMsR0FBb0I7QUFDL0MsWUFBWSxtQkFBTyxDQUFDLEVBQWE7QUFDakMsV0FBVyxtQkFBTyxDQUFDLEdBQVk7QUFDL0IsY0FBYyxtQkFBTyxDQUFDLEdBQWU7QUFDckMsWUFBWSxtQkFBTyxDQUFDLEdBQWE7QUFDakMsaUJBQWlCLG1CQUFPLENBQUMsR0FBa0I7QUFDM0MsYUFBYSxtQkFBTyxDQUFDLEdBQWM7QUFDbkMsY0FBYyxtQkFBTyxDQUFDLEdBQWU7QUFDckM7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSIsImZpbGUiOiI0Mi5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGdsb2JhbCB3aW5kb3cgKi9cblxudmFyIGxvZGFzaDtcblxuaWYgKHR5cGVvZiByZXF1aXJlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgdHJ5IHtcbiAgICBsb2Rhc2ggPSB7XG4gICAgICBjbG9uZTogcmVxdWlyZShcImxvZGFzaC9jbG9uZVwiKSxcbiAgICAgIGNvbnN0YW50OiByZXF1aXJlKFwibG9kYXNoL2NvbnN0YW50XCIpLFxuICAgICAgZWFjaDogcmVxdWlyZShcImxvZGFzaC9lYWNoXCIpLFxuICAgICAgZmlsdGVyOiByZXF1aXJlKFwibG9kYXNoL2ZpbHRlclwiKSxcbiAgICAgIGhhczogIHJlcXVpcmUoXCJsb2Rhc2gvaGFzXCIpLFxuICAgICAgaXNBcnJheTogcmVxdWlyZShcImxvZGFzaC9pc0FycmF5XCIpLFxuICAgICAgaXNFbXB0eTogcmVxdWlyZShcImxvZGFzaC9pc0VtcHR5XCIpLFxuICAgICAgaXNGdW5jdGlvbjogcmVxdWlyZShcImxvZGFzaC9pc0Z1bmN0aW9uXCIpLFxuICAgICAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoXCJsb2Rhc2gvaXNVbmRlZmluZWRcIiksXG4gICAgICBrZXlzOiByZXF1aXJlKFwibG9kYXNoL2tleXNcIiksXG4gICAgICBtYXA6IHJlcXVpcmUoXCJsb2Rhc2gvbWFwXCIpLFxuICAgICAgcmVkdWNlOiByZXF1aXJlKFwibG9kYXNoL3JlZHVjZVwiKSxcbiAgICAgIHNpemU6IHJlcXVpcmUoXCJsb2Rhc2gvc2l6ZVwiKSxcbiAgICAgIHRyYW5zZm9ybTogcmVxdWlyZShcImxvZGFzaC90cmFuc2Zvcm1cIiksXG4gICAgICB1bmlvbjogcmVxdWlyZShcImxvZGFzaC91bmlvblwiKSxcbiAgICAgIHZhbHVlczogcmVxdWlyZShcImxvZGFzaC92YWx1ZXNcIilcbiAgICB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gY29udGludWUgcmVnYXJkbGVzcyBvZiBlcnJvclxuICB9XG59XG5cbmlmICghbG9kYXNoKSB7XG4gIGxvZGFzaCA9IHdpbmRvdy5fO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZGFzaDtcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///42\n")},function(module,exports){eval("/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzT2JqZWN0LmpzPzFhOGMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxFQUFFO0FBQ2IsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwiZmlsZSI6IjQzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGVcbiAqIFtsYW5ndWFnZSB0eXBlXShodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcylcbiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///43\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('/* unused harmony export version */\n/* harmony import */ var _shape__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(57);\n/* harmony import */ var _antv_g_base__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21);\n/* harmony import */ var _canvas__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(280);\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Canvas", function() { return _canvas__WEBPACK_IMPORTED_MODULE_2__["a"]; });\n\n/* harmony import */ var _group__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(77);\n/* harmony import */ var _util_arc_params__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(93);\n\n\n\n\n\n\nvar version = \'0.5.12\';\n//# sourceMappingURL=index.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvZy1jYW52YXMvZXNtL2luZGV4LmpzPzUzYzgiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFpQztBQUNKO0FBQ2dCO0FBQ0Y7QUFDMUI7QUFDMkM7QUFDckQ7QUFDUCIsImZpbGUiOiI0NC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIFNoYXBlIGZyb20gJy4vc2hhcGUnO1xuZXhwb3J0ICogZnJvbSAnQGFudHYvZy1iYXNlJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgQ2FudmFzIH0gZnJvbSAnLi9jYW52YXMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBHcm91cCB9IGZyb20gJy4vZ3JvdXAnO1xuZXhwb3J0IHsgU2hhcGUgfTtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgZ2V0QXJjUGFyYW1zIH0gZnJvbSAnLi91dGlsL2FyYy1wYXJhbXMnO1xuZXhwb3J0IHZhciB2ZXJzaW9uID0gJzAuNS4xMic7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///44\n')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.uniqueId = exports.getEdgesByNodeId = exports.getOutEdgesNodeId = exports.getNeighbors = void 0;\n\n/**\n * 获取指定节点的所有邻居\n * @param nodeId 节点 ID\n * @param edges 图中的所有边数据\n * @param type 邻居类型\n */\nvar getNeighbors = function getNeighbors(nodeId, edges, type) {\n if (edges === void 0) {\n edges = [];\n }\n\n var currentEdges = edges.filter(function (edge) {\n return edge.source === nodeId || edge.target === nodeId;\n });\n\n if (type === 'target') {\n // 当前节点为 source,它所指向的目标节点\n var neighhborsConverter_1 = function neighhborsConverter_1(edge) {\n return edge.source === nodeId;\n };\n\n return currentEdges.filter(neighhborsConverter_1).map(function (edge) {\n return edge.target;\n });\n }\n\n if (type === 'source') {\n // 当前节点为 target,它所指向的源节点\n var neighhborsConverter_2 = function neighhborsConverter_2(edge) {\n return edge.target === nodeId;\n };\n\n return currentEdges.filter(neighhborsConverter_2).map(function (edge) {\n return edge.source;\n });\n } // 若未指定 type ,则返回所有邻居\n\n\n var neighhborsConverter = function neighhborsConverter(edge) {\n return edge.source === nodeId ? edge.target : edge.source;\n };\n\n return currentEdges.map(neighhborsConverter);\n};\n/**\n * 获取指定节点的出边\n * @param nodeId 节点 ID\n * @param edges 图中的所有边数据\n */\n\n\nexports.getNeighbors = getNeighbors;\n\nvar getOutEdgesNodeId = function getOutEdgesNodeId(nodeId, edges) {\n return edges.filter(function (edge) {\n return edge.source === nodeId;\n });\n};\n/**\n * 获取指定节点的边,包括出边和入边\n * @param nodeId 节点 ID\n * @param edges 图中的所有边数据\n */\n\n\nexports.getOutEdgesNodeId = getOutEdgesNodeId;\n\nvar getEdgesByNodeId = function getEdgesByNodeId(nodeId, edges) {\n return edges.filter(function (edge) {\n return edge.source === nodeId || edge.target === nodeId;\n });\n};\n/**\n * 生成唯一的 ID,规则是序号 + 时间戳\n * @param index 序号\n */\n\n\nexports.getEdgesByNodeId = getEdgesByNodeId;\n\nvar uniqueId = function uniqueId(index) {\n if (index === void 0) {\n index = 0;\n }\n\n var random1 = (\"\" + Math.random()).split('.')[1].substr(0, 5);\n var random2 = (\"\" + Math.random()).split('.')[1].substr(0, 5);\n return index + \"-\" + random1 + random2;\n};\n\nexports.uniqueId = uniqueId;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQGFudHYvYWxnb3JpdGhtL2xpYi91dGlsLmpzP2RjZmUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWI7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMLEdBQUc7OztBQUdIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwiZmlsZSI6IjQ1LmpzIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLnVuaXF1ZUlkID0gZXhwb3J0cy5nZXRFZGdlc0J5Tm9kZUlkID0gZXhwb3J0cy5nZXRPdXRFZGdlc05vZGVJZCA9IGV4cG9ydHMuZ2V0TmVpZ2hib3JzID0gdm9pZCAwO1xuXG4vKipcbiAqIOiOt+WPluaMh+WumuiKgueCueeahOaJgOaciemCu+WxhVxuICogQHBhcmFtIG5vZGVJZCDoioLngrkgSURcbiAqIEBwYXJhbSBlZGdlcyDlm77kuK3nmoTmiYDmnInovrnmlbDmja5cbiAqIEBwYXJhbSB0eXBlIOmCu+Wxheexu+Wei1xuICovXG52YXIgZ2V0TmVpZ2hib3JzID0gZnVuY3Rpb24gZ2V0TmVpZ2hib3JzKG5vZGVJZCwgZWRnZXMsIHR5cGUpIHtcbiAgaWYgKGVkZ2VzID09PSB2b2lkIDApIHtcbiAgICBlZGdlcyA9IFtdO1xuICB9XG5cbiAgdmFyIGN1cnJlbnRFZGdlcyA9IGVkZ2VzLmZpbHRlcihmdW5jdGlvbiAoZWRnZSkge1xuICAgIHJldHVybiBlZGdlLnNvdXJjZSA9PT0gbm9kZUlkIHx8IGVkZ2UudGFyZ2V0ID09PSBub2RlSWQ7XG4gIH0pO1xuXG4gIGlmICh0eXBlID09PSAndGFyZ2V0Jykge1xuICAgIC8vIOW9k+WJjeiKgueCueS4uiBzb3VyY2XvvIzlroPmiYDmjIflkJHnmoTnm67moIfoioLngrlcbiAgICB2YXIgbmVpZ2hoYm9yc0NvbnZlcnRlcl8xID0gZnVuY3Rpb24gbmVpZ2hoYm9yc0NvbnZlcnRlcl8xKGVkZ2UpIHtcbiAgICAgIHJldHVybiBlZGdlLnNvdXJjZSA9PT0gbm9kZUlkO1xuICAgIH07XG5cbiAgICByZXR1cm4gY3VycmVudEVkZ2VzLmZpbHRlcihuZWlnaGhib3JzQ29udmVydGVyXzEpLm1hcChmdW5jdGlvbiAoZWRnZSkge1xuICAgICAgcmV0dXJuIGVkZ2UudGFyZ2V0O1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHR5cGUgPT09ICdzb3VyY2UnKSB7XG4gICAgLy8g5b2T5YmN6IqC54K55Li6IHRhcmdldO+8jOWug+aJgOaMh+WQkeeahOa6kOiKgueCuVxuICAgIHZhciBuZWlnaGhib3JzQ29udmVydGVyXzIgPSBmdW5jdGlvbiBuZWlnaGhib3JzQ29udmVydGVyXzIoZWRnZSkge1xuICAgICAgcmV0dXJuIGVkZ2UudGFyZ2V0ID09PSBub2RlSWQ7XG4gICAgfTtcblxuICAgIHJldHVybiBjdXJyZW50RWRnZXMuZmlsdGVyKG5laWdoaGJvcnNDb252ZXJ0ZXJfMikubWFwKGZ1bmN0aW9uIChlZGdlKSB7XG4gICAgICByZXR1cm4gZWRnZS5zb3VyY2U7XG4gICAgfSk7XG4gIH0gLy8g6Iul5pyq5oyH5a6aIHR5cGUg77yM5YiZ6L+U5Zue5omA5pyJ6YK75bGFXG5cblxuICB2YXIgbmVpZ2hoYm9yc0NvbnZlcnRlciA9IGZ1bmN0aW9uIG5laWdoaGJvcnNDb252ZXJ0ZXIoZWRnZSkge1xuICAgIHJldHVybiBlZGdlLnNvdXJjZSA9PT0gbm9kZUlkID8gZWRnZS50YXJnZXQgOiBlZGdlLnNvdXJjZTtcbiAgfTtcblxuICByZXR1cm4gY3VycmVudEVkZ2VzLm1hcChuZWlnaGhib3JzQ29udmVydGVyKTtcbn07XG4vKipcbiAqIOiOt+WPluaMh+WumuiKgueCueeahOWHuui+uVxuICogQHBhcmFtIG5vZGVJZCDoioLngrkgSURcbiAqIEBwYXJhbSBlZGdlcyDlm77kuK3nmoTmiYDmnInovrnmlbDmja5cbiAqL1xuXG5cbmV4cG9ydHMuZ2V0TmVpZ2hib3JzID0gZ2V0TmVpZ2hib3JzO1xuXG52YXIgZ2V0T3V0RWRnZXNOb2RlSWQgPSBmdW5jdGlvbiBnZXRPdXRFZGdlc05vZGVJZChub2RlSWQsIGVkZ2VzKSB7XG4gIHJldHVybiBlZGdlcy5maWx0ZXIoZnVuY3Rpb24gKGVkZ2UpIHtcbiAgICByZXR1cm4gZWRnZS5zb3VyY2UgPT09IG5vZGVJZDtcbiAgfSk7XG59O1xuLyoqXG4gKiDojrflj5bmjIflrproioLngrnnmoTovrnvvIzljIXmi6zlh7rovrnlkozlhaXovrlcbiAqIEBwYXJhbSBub2RlSWQg6IqC54K5IElEXG4gKiBAcGFyYW0gZWRnZXMg5Zu+5Lit55qE5omA5pyJ6L655pWw5o2uXG4gKi9cblxuXG5leHBvcnRzLmdldE91dEVkZ2VzTm9kZUlkID0gZ2V0T3V0RWRnZXNOb2RlSWQ7XG5cbnZhciBnZXRFZGdlc0J5Tm9kZUlkID0gZnVuY3Rpb24gZ2V0RWRnZXNCeU5vZGVJZChub2RlSWQsIGVkZ2VzKSB7XG4gIHJldHVybiBlZGdlcy5maWx0ZXIoZnVuY3Rpb24gKGVkZ2UpIHtcbiAgICByZXR1cm4gZWRnZS5zb3VyY2UgPT09IG5vZGVJZCB8fCBlZGdlLnRhcmdldCA9PT0gbm9kZUlkO1xuICB9KTtcbn07XG4vKipcbiAqIOeUn+aIkOWUr+S4gOeahCBJRO+8jOinhOWImeaYr+W6j+WPtyArIOaXtumXtOaIs1xuICogQHBhcmFtIGluZGV4IOW6j+WPt1xuICovXG5cblxuZXhwb3J0cy5nZXRFZGdlc0J5Tm9kZUlkID0gZ2V0RWRnZXNCeU5vZGVJZDtcblxudmFyIHVuaXF1ZUlkID0gZnVuY3Rpb24gdW5pcXVlSWQoaW5kZXgpIHtcbiAgaWYgKGluZGV4ID09PSB2b2lkIDApIHtcbiAgICBpbmRleCA9IDA7XG4gIH1cblxuICB2YXIgcmFuZG9tMSA9IChcIlwiICsgTWF0aC5yYW5kb20oKSkuc3BsaXQoJy4nKVsxXS5zdWJzdHIoMCwgNSk7XG4gIHZhciByYW5kb20yID0gKFwiXCIgKyBNYXRoLnJhbmRvbSgpKS5zcGxpdCgnLicpWzFdLnN1YnN0cigwLCA1KTtcbiAgcmV0dXJuIGluZGV4ICsgXCItXCIgKyByYW5kb20xICsgcmFuZG9tMjtcbn07XG5cbmV4cG9ydHMudW5pcXVlSWQgPSB1bmlxdWVJZDsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///45\n")},function(module,exports,__webpack_require__){eval("// eslint-disable-next-line no-redeclare\n/* global window */\n\nvar graphlib;\n\nif (true) {\n try {\n graphlib = __webpack_require__(321);\n } catch (e) {\n // continue regardless of error\n }\n}\n\nif (!graphlib) {\n graphlib = window.graphlib;\n}\n\nmodule.exports = graphlib;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZGFncmVqcy9saWIvZ3JhcGhsaWIuanM/M2ZkMiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBOztBQUVBOztBQUVBLElBQUksSUFBNkI7QUFDakM7QUFDQSxlQUFlLG1CQUFPLENBQUMsR0FBVTtBQUNqQyxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSIsImZpbGUiOiI0Ni5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZWRlY2xhcmVcbi8qIGdsb2JhbCB3aW5kb3cgKi9cblxudmFyIGdyYXBobGliO1xuXG5pZiAodHlwZW9mIHJlcXVpcmUgPT09IFwiZnVuY3Rpb25cIikge1xuICB0cnkge1xuICAgIGdyYXBobGliID0gcmVxdWlyZShcImdyYXBobGliXCIpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gY29udGludWUgcmVnYXJkbGVzcyBvZiBlcnJvclxuICB9XG59XG5cbmlmICghZ3JhcGhsaWIpIHtcbiAgZ3JhcGhsaWIgPSB3aW5kb3cuZ3JhcGhsaWI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ3JhcGhsaWI7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///46\n")},function(module,exports,__webpack_require__){eval("var freeGlobal = __webpack_require__(186);\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbG9kYXNoL19yb290LmpzPzJiM2UiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUJBQWlCLG1CQUFPLENBQUMsR0FBZTs7QUFFeEM7QUFDQTs7QUFFQTtBQUNBOztBQUVBIiwiZmlsZSI6IjQ3LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGZyZWVHbG9iYWwgPSByZXF1aXJlKCcuL19mcmVlR2xvYmFsJyk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgc2VsZmAuICovXG52YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjtcblxuLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG52YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblxubW9kdWxlLmV4cG9ydHMgPSByb290O1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///47\n")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nexports.Metadata = void 0;\nvar METADATA_KEY = __webpack_require__(32);\nvar Metadata = (function () {\n function Metadata(key, value) {\n this.key = key;\n this.value = value;\n }\n Metadata.prototype.toString = function () {\n if (this.key === METADATA_KEY.NAMED_TAG) {\n return "named: " + this.value.toString() + " ";\n }\n else {\n return "tagged: { key:" + this.key.toString() + ", value: " + this.value + " }";\n }\n };\n return Metadata;\n}());\nexports.Metadata = Metadata;\n//# sourceMappingURL=metadata.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaW52ZXJzaWZ5L2xpYi9wbGFubmluZy9tZXRhZGF0YS5qcz8xOTc5Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFhO0FBQ2IsOENBQThDLGNBQWM7QUFDNUQ7QUFDQSxtQkFBbUIsbUJBQU8sQ0FBQyxFQUE0QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qiw2REFBNkQ7QUFDMUY7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0EiLCJmaWxlIjoiNDguanMiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuTWV0YWRhdGEgPSB2b2lkIDA7XG52YXIgTUVUQURBVEFfS0VZID0gcmVxdWlyZShcIi4uL2NvbnN0YW50cy9tZXRhZGF0YV9rZXlzXCIpO1xudmFyIE1ldGFkYXRhID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXRhZGF0YShrZXksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMua2V5ID0ga2V5O1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIE1ldGFkYXRhLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMua2V5ID09PSBNRVRBREFUQV9LRVkuTkFNRURfVEFHKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJuYW1lZDogXCIgKyB0aGlzLnZhbHVlLnRvU3RyaW5nKCkgKyBcIiBcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBcInRhZ2dlZDogeyBrZXk6XCIgKyB0aGlzLmtleS50b1N0cmluZygpICsgXCIsIHZhbHVlOiBcIiArIHRoaXMudmFsdWUgKyBcIiB9XCI7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNZXRhZGF0YTtcbn0oKSk7XG5leHBvcnRzLk1ldGFkYXRhID0gTWV0YWRhdGE7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZXRhZGF0YS5qcy5tYXAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///48\n')},function(module,exports){eval("/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzT2JqZWN0TGlrZS5qcz8xMzEwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEVBQUU7QUFDYixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwiZmlsZSI6IjQ5LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///49\n")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, \"G6GraphEvent\", function() { return /* reexport */ behavior_G6GraphEvent; });\n__webpack_require__.d(__webpack_exports__, \"G6Event\", function() { return /* reexport */ G6Event; });\n__webpack_require__.d(__webpack_exports__, \"Node\", function() { return /* reexport */ item_node; });\n__webpack_require__.d(__webpack_exports__, \"Edge\", function() { return /* reexport */ item_edge; });\n__webpack_require__.d(__webpack_exports__, \"Combo\", function() { return /* reexport */ item_combo; });\n__webpack_require__.d(__webpack_exports__, \"Hull\", function() { return /* reexport */ item_hull; });\n__webpack_require__.d(__webpack_exports__, \"registerNode\", function() { return /* reexport */ registerNode; });\n__webpack_require__.d(__webpack_exports__, \"registerCombo\", function() { return /* reexport */ registerCombo; });\n__webpack_require__.d(__webpack_exports__, \"AbstractGraph\", function() { return /* reexport */ graph_graph; });\n__webpack_require__.d(__webpack_exports__, \"registerEdge\", function() { return /* reexport */ registerEdge; });\n__webpack_require__.d(__webpack_exports__, \"registerBehavior\", function() { return /* reexport */ registerBehavior; });\n__webpack_require__.d(__webpack_exports__, \"AbstractLayout\", function() { return /* reexport */ controller_layout; });\n__webpack_require__.d(__webpack_exports__, \"AbstractEvent\", function() { return /* reexport */ controller_event; });\n__webpack_require__.d(__webpack_exports__, \"BaseGlobal\", function() { return /* reexport */ BaseGlobal; });\n__webpack_require__.d(__webpack_exports__, \"Graph\", function() { return /* reexport */ es_graph_graph; });\n__webpack_require__.d(__webpack_exports__, \"TreeGraph\", function() { return /* reexport */ tree_graph; });\n__webpack_require__.d(__webpack_exports__, \"Util\", function() { return /* reexport */ es_util; });\n__webpack_require__.d(__webpack_exports__, \"Layout\", function() { return /* reexport */ Layouts; });\n__webpack_require__.d(__webpack_exports__, \"TreeLayout\", function() { return /* reexport */ tree_layout; });\n__webpack_require__.d(__webpack_exports__, \"registerLayout\", function() { return /* reexport */ layout_registerLayout; });\n__webpack_require__.d(__webpack_exports__, \"Global\", function() { return /* reexport */ es_global; });\n__webpack_require__.d(__webpack_exports__, \"Minimap\", function() { return /* reexport */ Minimap; });\n__webpack_require__.d(__webpack_exports__, \"Grid\", function() { return /* reexport */ es_Grid; });\n__webpack_require__.d(__webpack_exports__, \"Bundling\", function() { return /* reexport */ es_Bundling; });\n__webpack_require__.d(__webpack_exports__, \"Menu\", function() { return /* reexport */ es_Menu; });\n__webpack_require__.d(__webpack_exports__, \"Fisheye\", function() { return /* reexport */ es_Fisheye; });\n__webpack_require__.d(__webpack_exports__, \"Algorithm\", function() { return /* reexport */ Algorithm; });\n__webpack_require__.d(__webpack_exports__, \"ToolBar\", function() { return /* reexport */ es_ToolBar; });\n__webpack_require__.d(__webpack_exports__, \"Tooltip\", function() { return /* reexport */ es_Tooltip; });\n__webpack_require__.d(__webpack_exports__, \"TimeBar\", function() { return /* reexport */ es_TimeBar; });\n__webpack_require__.d(__webpack_exports__, \"ImageMinimap\", function() { return /* reexport */ ImageMinimap; });\n__webpack_require__.d(__webpack_exports__, \"EdgeFilterLens\", function() { return /* reexport */ es_EdgeFilterLens; });\n__webpack_require__.d(__webpack_exports__, \"SnapLine\", function() { return /* reexport */ es_SnapLine; });\n__webpack_require__.d(__webpack_exports__, \"Legend\", function() { return /* reexport */ es_Legend; });\n__webpack_require__.d(__webpack_exports__, \"Arrow\", function() { return /* reexport */ element_arrow; });\n__webpack_require__.d(__webpack_exports__, \"Marker\", function() { return /* reexport */ marker; });\n__webpack_require__.d(__webpack_exports__, \"Shape\", function() { return /* reexport */ es_element; });\n__webpack_require__.d(__webpack_exports__, \"version\", function() { return /* binding */ version; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/algorithm/es/index.js\nvar es_namespaceObject = {};\n__webpack_require__.r(es_namespaceObject);\n__webpack_require__.d(es_namespaceObject, \"getAdjMatrix\", function() { return adjacent_matrix; });\n__webpack_require__.d(es_namespaceObject, \"breadthFirstSearch\", function() { return bfs; });\n__webpack_require__.d(es_namespaceObject, \"connectedComponent\", function() { return getConnectedComponents; });\n__webpack_require__.d(es_namespaceObject, \"getDegree\", function() { return es_degree; });\n__webpack_require__.d(es_namespaceObject, \"getInDegree\", function() { return getInDegree; });\n__webpack_require__.d(es_namespaceObject, \"getOutDegree\", function() { return getOutDegree; });\n__webpack_require__.d(es_namespaceObject, \"detectCycle\", function() { return detect_cycle; });\n__webpack_require__.d(es_namespaceObject, \"detectDirectedCycle\", function() { return es_detectDirectedCycle; });\n__webpack_require__.d(es_namespaceObject, \"detectAllCycles\", function() { return detectAllCycles; });\n__webpack_require__.d(es_namespaceObject, \"detectAllDirectedCycle\", function() { return detect_cycle_detectAllDirectedCycle; });\n__webpack_require__.d(es_namespaceObject, \"detectAllUndirectedCycle\", function() { return detect_cycle_detectAllUndirectedCycle; });\n__webpack_require__.d(es_namespaceObject, \"depthFirstSearch\", function() { return depthFirstSearch; });\n__webpack_require__.d(es_namespaceObject, \"dijkstra\", function() { return es_dijkstra; });\n__webpack_require__.d(es_namespaceObject, \"findAllPath\", function() { return find_path_findAllPath; });\n__webpack_require__.d(es_namespaceObject, \"findShortestPath\", function() { return find_path_findShortestPath; });\n__webpack_require__.d(es_namespaceObject, \"floydWarshall\", function() { return es_floydWarshall; });\n__webpack_require__.d(es_namespaceObject, \"labelPropagation\", function() { return label_propagation; });\n__webpack_require__.d(es_namespaceObject, \"louvain\", function() { return es_louvain; });\n__webpack_require__.d(es_namespaceObject, \"minimumSpanningTree\", function() { return mts; });\n__webpack_require__.d(es_namespaceObject, \"pageRank\", function() { return es_pageRank; });\n__webpack_require__.d(es_namespaceObject, \"getNeighbors\", function() { return getNeighbors; });\n__webpack_require__.d(es_namespaceObject, \"Stack\", function() { return structs_stack; });\n__webpack_require__.d(es_namespaceObject, \"GADDI\", function() { return gaddi; });\n__webpack_require__.d(es_namespaceObject, \"default\", function() { return es; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-core/es/util/math.js\nvar math_namespaceObject = {};\n__webpack_require__.r(math_namespaceObject);\n__webpack_require__.d(math_namespaceObject, \"compare\", function() { return compare; });\n__webpack_require__.d(math_namespaceObject, \"getLineIntersect\", function() { return getLineIntersect; });\n__webpack_require__.d(math_namespaceObject, \"getRectIntersectByPoint\", function() { return getRectIntersectByPoint; });\n__webpack_require__.d(math_namespaceObject, \"getCircleIntersectByPoint\", function() { return getCircleIntersectByPoint; });\n__webpack_require__.d(math_namespaceObject, \"getEllipseIntersectByPoint\", function() { return getEllipseIntersectByPoint; });\n__webpack_require__.d(math_namespaceObject, \"applyMatrix\", function() { return math_applyMatrix; });\n__webpack_require__.d(math_namespaceObject, \"invertMatrix\", function() { return math_invertMatrix; });\n__webpack_require__.d(math_namespaceObject, \"getCircleCenterByPoints\", function() { return getCircleCenterByPoints; });\n__webpack_require__.d(math_namespaceObject, \"distance\", function() { return math_distance; });\n__webpack_require__.d(math_namespaceObject, \"scaleMatrix\", function() { return scaleMatrix; });\n__webpack_require__.d(math_namespaceObject, \"floydWarshall\", function() { return math_floydWarshall; });\n__webpack_require__.d(math_namespaceObject, \"getAdjMatrix\", function() { return getAdjMatrix; });\n__webpack_require__.d(math_namespaceObject, \"translate\", function() { return translate; });\n__webpack_require__.d(math_namespaceObject, \"move\", function() { return move; });\n__webpack_require__.d(math_namespaceObject, \"scale\", function() { return math_scale; });\n__webpack_require__.d(math_namespaceObject, \"rotate\", function() { return math_rotate; });\n__webpack_require__.d(math_namespaceObject, \"getDegree\", function() { return getDegree; });\n__webpack_require__.d(math_namespaceObject, \"isPointInPolygon\", function() { return isPointInPolygon; });\n__webpack_require__.d(math_namespaceObject, \"intersectBBox\", function() { return intersectBBox; });\n__webpack_require__.d(math_namespaceObject, \"isPolygonsIntersect\", function() { return math_isPolygonsIntersect; });\n__webpack_require__.d(math_namespaceObject, \"Line\", function() { return math_Line; });\n__webpack_require__.d(math_namespaceObject, \"getBBoxBoundLine\", function() { return getBBoxBoundLine; });\n__webpack_require__.d(math_namespaceObject, \"itemIntersectByLine\", function() { return itemIntersectByLine; });\n__webpack_require__.d(math_namespaceObject, \"fractionToLine\", function() { return fractionToLine; });\n__webpack_require__.d(math_namespaceObject, \"getPointsCenter\", function() { return getPointsCenter; });\n__webpack_require__.d(math_namespaceObject, \"squareDist\", function() { return squareDist; });\n__webpack_require__.d(math_namespaceObject, \"pointLineSquareDist\", function() { return pointLineSquareDist; });\n__webpack_require__.d(math_namespaceObject, \"isPointsOverlap\", function() { return isPointsOverlap; });\n__webpack_require__.d(math_namespaceObject, \"pointRectSquareDist\", function() { return pointRectSquareDist; });\n__webpack_require__.d(math_namespaceObject, \"pointLineDistance\", function() { return math_pointLineDistance; });\n__webpack_require__.d(math_namespaceObject, \"lerp\", function() { return lerp; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-core/es/util/graphic.js\nvar graphic_namespaceObject = {};\n__webpack_require__.r(graphic_namespaceObject);\n__webpack_require__.d(graphic_namespaceObject, \"getBBox\", function() { return graphic_getBBox; });\n__webpack_require__.d(graphic_namespaceObject, \"getLoopCfgs\", function() { return graphic_getLoopCfgs; });\n__webpack_require__.d(graphic_namespaceObject, \"getLabelPosition\", function() { return graphic_getLabelPosition; });\n__webpack_require__.d(graphic_namespaceObject, \"traverseTree\", function() { return traverseTree; });\n__webpack_require__.d(graphic_namespaceObject, \"traverseTreeUp\", function() { return traverseTreeUp; });\n__webpack_require__.d(graphic_namespaceObject, \"getLetterWidth\", function() { return graphic_getLetterWidth; });\n__webpack_require__.d(graphic_namespaceObject, \"getTextSize\", function() { return getTextSize; });\n__webpack_require__.d(graphic_namespaceObject, \"plainCombosToTrees\", function() { return graphic_plainCombosToTrees; });\n__webpack_require__.d(graphic_namespaceObject, \"reconstructTree\", function() { return reconstructTree; });\n__webpack_require__.d(graphic_namespaceObject, \"getComboBBox\", function() { return getComboBBox; });\n__webpack_require__.d(graphic_namespaceObject, \"shouldRefreshEdge\", function() { return graphic_shouldRefreshEdge; });\n__webpack_require__.d(graphic_namespaceObject, \"cloneBesidesImg\", function() { return graphic_cloneBesidesImg; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-core/es/util/base.js\nvar base_namespaceObject = {};\n__webpack_require__.r(base_namespaceObject);\n__webpack_require__.d(base_namespaceObject, \"uniqueId\", function() { return base_uniqueId; });\n__webpack_require__.d(base_namespaceObject, \"formatPadding\", function() { return base_formatPadding; });\n__webpack_require__.d(base_namespaceObject, \"cloneEvent\", function() { return base_cloneEvent; });\n__webpack_require__.d(base_namespaceObject, \"isViewportChanged\", function() { return isViewportChanged; });\n__webpack_require__.d(base_namespaceObject, \"isNaN\", function() { return base_isNaN; });\n__webpack_require__.d(base_namespaceObject, \"calculationItemsBBox\", function() { return calculationItemsBBox; });\n__webpack_require__.d(base_namespaceObject, \"processParallelEdges\", function() { return processParallelEdges; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-core/es/util/path.js\nvar path_namespaceObject = {};\n__webpack_require__.r(path_namespaceObject);\n__webpack_require__.d(path_namespaceObject, \"getSpline\", function() { return path_getSpline; });\n__webpack_require__.d(path_namespaceObject, \"getControlPoint\", function() { return path_getControlPoint; });\n__webpack_require__.d(path_namespaceObject, \"pointsToPolygon\", function() { return pointsToPolygon; });\n__webpack_require__.d(path_namespaceObject, \"pathToPoints\", function() { return pathToPoints; });\n__webpack_require__.d(path_namespaceObject, \"getClosedSpline\", function() { return getClosedSpline; });\n__webpack_require__.d(path_namespaceObject, \"roundedHull\", function() { return roundedHull; });\n__webpack_require__.d(path_namespaceObject, \"paddedHull\", function() { return paddedHull; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-core/es/util/color.js\nvar color_namespaceObject = {};\n__webpack_require__.r(color_namespaceObject);\n__webpack_require__.d(color_namespaceObject, \"defaultSubjectColors\", function() { return defaultSubjectColors; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-pc/es/util/color.js\nvar util_color_namespaceObject = {};\n__webpack_require__.r(util_color_namespaceObject);\n__webpack_require__.d(util_color_namespaceObject, \"mixColor\", function() { return color_mixColor; });\n__webpack_require__.d(util_color_namespaceObject, \"getColorsWithSubjectColor\", function() { return getColorsWithSubjectColor; });\n__webpack_require__.d(util_color_namespaceObject, \"getColorSetsBySubjectColors\", function() { return getColorSetsBySubjectColors; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-pc/es/util/layout.js\nvar util_layout_namespaceObject = {};\n__webpack_require__.r(util_layout_namespaceObject);\n__webpack_require__.d(util_layout_namespaceObject, \"proccessToFunc\", function() { return layout_proccessToFunc; });\n__webpack_require__.d(util_layout_namespaceObject, \"buildTextureData\", function() { return layout_buildTextureData; });\n__webpack_require__.d(util_layout_namespaceObject, \"buildTextureDataWithOneEdgeAttr\", function() { return buildTextureDataWithOneEdgeAttr; });\n__webpack_require__.d(util_layout_namespaceObject, \"buildTextureDataWithTwoEdgeAttr\", function() { return layout_buildTextureDataWithTwoEdgeAttr; });\n__webpack_require__.d(util_layout_namespaceObject, \"attributesToTextureData\", function() { return layout_attributesToTextureData; });\n__webpack_require__.d(util_layout_namespaceObject, \"arrayToTextureData\", function() { return layout_arrayToTextureData; });\n__webpack_require__.d(util_layout_namespaceObject, \"radialLayout\", function() { return radialLayout; });\n\n// NAMESPACE OBJECT: ./node_modules/@antv/g6-pc/es/util/gpu.js\nvar util_gpu_namespaceObject = {};\n__webpack_require__.r(util_gpu_namespaceObject);\n__webpack_require__.d(util_gpu_namespaceObject, \"gpuDetector\", function() { return gpuDetector; });\n\n// NAMESPACE OBJECT: ./node_modules/fecha/lib/fecha.js\nvar fecha_namespaceObject = {};\n__webpack_require__.r(fecha_namespaceObject);\n__webpack_require__.d(fecha_namespaceObject, \"default\", function() { return lib_fecha; });\n__webpack_require__.d(fecha_namespaceObject, \"assign\", function() { return fecha_assign; });\n__webpack_require__.d(fecha_namespaceObject, \"format\", function() { return fecha_format; });\n__webpack_require__.d(fecha_namespaceObject, \"parse\", function() { return parse; });\n__webpack_require__.d(fecha_namespaceObject, \"defaultI18n\", function() { return defaultI18n; });\n__webpack_require__.d(fecha_namespaceObject, \"setGlobalDateI18n\", function() { return setGlobalDateI18n; });\n__webpack_require__.d(fecha_namespaceObject, \"setGlobalDateMasks\", function() { return setGlobalDateMasks; });\n\n// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js\nvar tslib_es6 = __webpack_require__(1);\n\n// EXTERNAL MODULE: ./node_modules/@antv/util/esm/index.js + 110 modules\nvar esm = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/behavior/behaviorOption.js\n // 自定义 Behavior 时候共有的方法\n\n/* harmony default export */ var behaviorOption = ({\n getDefaultCfg: function getDefaultCfg() {\n return {};\n },\n\n /**\n * register event handler, behavior will auto bind events\n * for example:\n * return {\n * click: 'onClick'\n * }\n */\n getEvents: function getEvents() {\n return {};\n },\n updateCfg: function updateCfg(cfg) {\n Object.assign(this, cfg);\n return true;\n },\n shouldBegin: function shouldBegin() {\n return true;\n },\n shouldUpdate: function shouldUpdate() {\n return true;\n },\n shouldEnd: function shouldEnd() {\n return true;\n },\n\n /**\n * auto bind events when register behavior\n * @param graph Graph instance\n */\n bind: function bind(graph) {\n var _this = this;\n\n var events = this.events;\n this.graph = graph;\n\n if (this.type === 'drag-canvas' || this.type === 'brush-select' || this.type === 'lasso-select') {\n graph.get('canvas').set('draggable', true);\n }\n\n Object(esm[\"each\"])(events, function (handler, event) {\n graph.on(event, handler);\n }); // To avoid the tabs switching makes the keydown related behaviors disable\n\n document.addEventListener('visibilitychange', function () {\n _this.keydown = false;\n });\n },\n unbind: function unbind(graph) {\n var events = this.events;\n var draggable = graph.get('canvas').get('draggable');\n\n if (this.type === 'drag-canvas' || this.type === 'brush-select' || this.type === 'lasso-select') {\n graph.get('canvas').set('draggable', false);\n }\n\n Object(esm[\"each\"])(events, function (handler, event) {\n graph.off(event, handler);\n });\n graph.get('canvas').set('draggable', draggable);\n },\n get: function get(val) {\n return this[val];\n },\n set: function set(key, val) {\n this[key] = val;\n return this;\n }\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/behavior/behavior.js\n\n\n\nvar behavior_Behavior =\n/** @class */\nfunction () {\n function Behavior() {}\n /**\n * 自定义 Behavior\n * @param type Behavior 名称\n * @param behavior Behavior 定义的方法集合\n */\n\n\n Behavior.registerBehavior = function (type, behavior) {\n if (!behavior) {\n throw new Error(\"please specify handler for this behavior: \" + type);\n }\n\n var prototype = Object(esm[\"clone\"])(behaviorOption);\n Object.assign(prototype, behavior); // eslint-disable-next-line func-names\n\n var base = function base(cfg) {\n var _this = this;\n\n Object.assign(this, this.getDefaultCfg(), cfg);\n var events = this.getEvents();\n this.events = null;\n var eventsToBind = {};\n\n if (events) {\n Object(esm[\"each\"])(events, function (handle, event) {\n eventsToBind[event] = Object(esm[\"wrapBehavior\"])(_this, handle);\n });\n this.events = eventsToBind;\n }\n };\n\n base.prototype = prototype;\n Behavior.types[type] = base;\n };\n\n Behavior.hasBehavior = function (type) {\n return !!Behavior.types[type];\n };\n\n Behavior.getBehavior = function (type) {\n return Behavior.types[type];\n }; // 所有自定义的 Behavior 的实例\n\n\n Behavior.types = {};\n return Behavior;\n}();\n\n/* harmony default export */ var behavior_behavior = (behavior_Behavior);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/behavior/index.js\n\n/* harmony default export */ var es_behavior = (behavior_behavior);\n// EXTERNAL MODULE: ./node_modules/@antv/event-emitter/esm/index.js\nvar event_emitter_esm = __webpack_require__(138);\n\n// EXTERNAL MODULE: ./node_modules/@antv/matrix-util/esm/index.js + 1 modules\nvar matrix_util_esm = __webpack_require__(14);\n\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/adjacent-matrix.js\nvar adjacent_matrix_adjMatrix = function adjMatrix(graphData, directed) {\n var nodes = graphData.nodes,\n edges = graphData.edges;\n var matrix = []; // map node with index in data.nodes\n\n var nodeMap = {};\n\n if (!nodes) {\n throw new Error(\"invalid nodes data!\");\n }\n\n if (nodes) {\n nodes.forEach(function (node, i) {\n nodeMap[node.id] = i;\n var row = [];\n matrix.push(row);\n });\n }\n\n if (edges) {\n edges.forEach(function (edge) {\n var source = edge.source,\n target = edge.target;\n var sIndex = nodeMap[source];\n var tIndex = nodeMap[target];\n if (!sIndex && sIndex !== 0 || !tIndex && tIndex !== 0) return;\n matrix[sIndex][tIndex] = 1;\n\n if (!directed) {\n matrix[tIndex][sIndex] = 1;\n }\n });\n }\n\n return matrix;\n};\n\n/* harmony default export */ var adjacent_matrix = (adjacent_matrix_adjMatrix);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/structs/linked-list.js\nvar defaultComparator = function defaultComparator(a, b) {\n if (a === b) {\n return true;\n }\n\n return false;\n};\n/**\n * 链表中单个元素节点\n */\n\n\nvar LinkedListNode =\n/** @class */\nfunction () {\n function LinkedListNode(value, next) {\n if (next === void 0) {\n next = null;\n }\n\n this.value = value;\n this.next = next;\n }\n\n LinkedListNode.prototype.toString = function (callback) {\n return callback ? callback(this.value) : \"\" + this.value;\n };\n\n return LinkedListNode;\n}();\n\n\n\nvar LinkedList =\n/** @class */\nfunction () {\n function LinkedList(comparator) {\n if (comparator === void 0) {\n comparator = defaultComparator;\n }\n\n this.head = null;\n this.tail = null;\n this.compare = comparator;\n }\n /**\n * 将指定元素添加到链表头部\n * @param value\n */\n\n\n LinkedList.prototype.prepend = function (value) {\n // 在头部添加一个节点\n var newNode = new LinkedListNode(value, this.head);\n this.head = newNode;\n\n if (!this.tail) {\n this.tail = newNode;\n }\n\n return this;\n };\n /**\n * 将指定元素添加到链表中\n * @param value\n */\n\n\n LinkedList.prototype.append = function (value) {\n var newNode = new LinkedListNode(value); // 如果不存在头节点,则将创建的新节点作为头节点\n\n if (!this.head) {\n this.head = newNode;\n this.tail = newNode;\n return this;\n } // 将新节点附加到链表末尾\n\n\n this.tail.next = newNode;\n this.tail = newNode;\n return this;\n };\n /**\n * 删除指定元素\n * @param value 要删除的元素\n */\n\n\n LinkedList.prototype.delete = function (value) {\n if (!this.head) {\n return null;\n }\n\n var deleteNode = null; // 如果删除的是头部元素,则将next作为头元素\n\n while (this.head && this.compare(this.head.value, value)) {\n deleteNode = this.head;\n this.head = this.head.next;\n }\n\n var currentNode = this.head;\n\n if (currentNode !== null) {\n // 如果删除了节点以后,将next节点前移\n while (currentNode.next) {\n if (this.compare(currentNode.next.value, value)) {\n deleteNode = currentNode.next;\n currentNode.next = currentNode.next.next;\n } else {\n currentNode = currentNode.next;\n }\n }\n } // 检查尾部节点是否被删除\n\n\n if (this.compare(this.tail.value, value)) {\n this.tail = currentNode;\n }\n\n return deleteNode;\n };\n /**\n * 查找指定的元素\n * @param param0\n */\n\n\n LinkedList.prototype.find = function (_a) {\n var _b = _a.value,\n value = _b === void 0 ? undefined : _b,\n _c = _a.callback,\n callback = _c === void 0 ? undefined : _c;\n\n if (!this.head) {\n return null;\n }\n\n var currentNode = this.head;\n\n while (currentNode) {\n // 如果指定了 callback,则按指定的 callback 查找\n if (callback && callback(currentNode.value)) {\n return currentNode;\n } // 如果指定了 value,则按 value 查找\n\n\n if (value !== undefined && this.compare(currentNode.value, value)) {\n return currentNode;\n }\n\n currentNode = currentNode.next;\n }\n\n return null;\n };\n /**\n * 删除尾部节点\n */\n\n\n LinkedList.prototype.deleteTail = function () {\n var deletedTail = this.tail;\n\n if (this.head === this.tail) {\n // 链表中只有一个元素\n this.head = null;\n this.tail = null;\n return deletedTail;\n }\n\n var currentNode = this.head;\n\n while (currentNode.next) {\n if (!currentNode.next.next) {\n currentNode.next = null;\n } else {\n currentNode = currentNode.next;\n }\n }\n\n this.tail = currentNode;\n return deletedTail;\n };\n /**\n * 删除头部节点\n */\n\n\n LinkedList.prototype.deleteHead = function () {\n if (!this.head) {\n return null;\n }\n\n var deletedHead = this.head;\n\n if (this.head.next) {\n this.head = this.head.next;\n } else {\n this.head = null;\n this.tail = null;\n }\n\n return deletedHead;\n };\n /**\n * 将一组元素转成链表中的节点\n * @param values 链表中的元素\n */\n\n\n LinkedList.prototype.fromArray = function (values) {\n var _this = this;\n\n values.forEach(function (value) {\n return _this.append(value);\n });\n return this;\n };\n /**\n * 将链表中的节点转成数组元素\n */\n\n\n LinkedList.prototype.toArray = function () {\n var nodes = [];\n var currentNode = this.head;\n\n while (currentNode) {\n nodes.push(currentNode);\n currentNode = currentNode.next;\n }\n\n return nodes;\n };\n /**\n * 反转链表中的元素节点\n */\n\n\n LinkedList.prototype.reverse = function () {\n var currentNode = this.head;\n var prevNode = null;\n var nextNode = null;\n\n while (currentNode) {\n // 存储下一个元素节点\n nextNode = currentNode.next; // 更改当前节点的下一个节点,以便将它连接到上一个节点上\n\n currentNode.next = prevNode; // 将 prevNode 和 currentNode 向前移动一步\n\n prevNode = currentNode;\n currentNode = nextNode;\n }\n\n this.tail = this.head;\n this.head = prevNode;\n };\n\n LinkedList.prototype.toString = function (callback) {\n if (callback === void 0) {\n callback = undefined;\n }\n\n return this.toArray().map(function (node) {\n return node.toString(callback);\n }).toString();\n };\n\n return LinkedList;\n}();\n\n/* harmony default export */ var linked_list = (LinkedList);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/structs/queue.js\n\n\nvar queue_Queue =\n/** @class */\nfunction () {\n function Queue() {\n this.linkedList = new linked_list();\n }\n /**\n * 队列是否为空\n */\n\n\n Queue.prototype.isEmpty = function () {\n return !this.linkedList.head;\n };\n /**\n * 读取队列头部的元素, 不删除队列中的元素\n */\n\n\n Queue.prototype.peek = function () {\n if (!this.linkedList.head) {\n return null;\n }\n\n return this.linkedList.head.value;\n };\n /**\n * 在队列的尾部新增一个元素\n * @param value\n */\n\n\n Queue.prototype.enqueue = function (value) {\n this.linkedList.append(value);\n };\n /**\n * 删除队列中的头部元素,如果队列为空,则返回 null\n */\n\n\n Queue.prototype.dequeue = function () {\n var removeHead = this.linkedList.deleteHead();\n return removeHead ? removeHead.value : null;\n };\n\n Queue.prototype.toString = function (callback) {\n return this.linkedList.toString(callback);\n };\n\n return Queue;\n}();\n\n/* harmony default export */ var structs_queue = (queue_Queue);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/util.js\n/**\n * 获取指定节点的所有邻居\n * @param nodeId 节点 ID\n * @param edges 图中的所有边数据\n * @param type 邻居类型\n */\nvar getNeighbors = function getNeighbors(nodeId, edges, type) {\n if (edges === void 0) {\n edges = [];\n }\n\n var currentEdges = edges.filter(function (edge) {\n return edge.source === nodeId || edge.target === nodeId;\n });\n\n if (type === 'target') {\n // 当前节点为 source,它所指向的目标节点\n var neighhborsConverter_1 = function neighhborsConverter_1(edge) {\n return edge.source === nodeId;\n };\n\n return currentEdges.filter(neighhborsConverter_1).map(function (edge) {\n return edge.target;\n });\n }\n\n if (type === 'source') {\n // 当前节点为 target,它所指向的源节点\n var neighhborsConverter_2 = function neighhborsConverter_2(edge) {\n return edge.target === nodeId;\n };\n\n return currentEdges.filter(neighhborsConverter_2).map(function (edge) {\n return edge.source;\n });\n } // 若未指定 type ,则返回所有邻居\n\n\n var neighhborsConverter = function neighhborsConverter(edge) {\n return edge.source === nodeId ? edge.target : edge.source;\n };\n\n return currentEdges.map(neighhborsConverter);\n};\n/**\n * 获取指定节点的出边\n * @param nodeId 节点 ID\n * @param edges 图中的所有边数据\n */\n\nvar getOutEdgesNodeId = function getOutEdgesNodeId(nodeId, edges) {\n return edges.filter(function (edge) {\n return edge.source === nodeId;\n });\n};\n/**\n * 获取指定节点的边,包括出边和入边\n * @param nodeId 节点 ID\n * @param edges 图中的所有边数据\n */\n\nvar getEdgesByNodeId = function getEdgesByNodeId(nodeId, edges) {\n return edges.filter(function (edge) {\n return edge.source === nodeId || edge.target === nodeId;\n });\n};\n/**\n * 生成唯一的 ID,规则是序号 + 时间戳\n * @param index 序号\n */\n\nvar util_uniqueId = function uniqueId(index) {\n if (index === void 0) {\n index = 0;\n }\n\n var random1 = (\"\" + Math.random()).split('.')[1].substr(0, 5);\n var random2 = (\"\" + Math.random()).split('.')[1].substr(0, 5);\n return index + \"-\" + random1 + random2;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/bfs.js\n\n\n/**\n *\n * @param callbacks\n * allowTraversal: 确定 BFS 是否从顶点沿着边遍历到其邻居,默认情况下,同一个节点只能遍历一次\n * enterNode: 当 BFS 访问某个节点时调用\n * leaveNode: 当 BFS 访问访问结束某个节点时调用\n */\n\nfunction initCallbacks(callbacks) {\n if (callbacks === void 0) {\n callbacks = {};\n }\n\n var initiatedCallback = callbacks;\n\n var stubCallback = function stubCallback() {};\n\n var allowTraversalCallback = function () {\n var seen = {};\n return function (_a) {\n var next = _a.next;\n var id = next;\n\n if (!seen[id]) {\n seen[id] = true;\n return true;\n }\n\n return false;\n };\n }();\n\n initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback;\n initiatedCallback.enter = callbacks.enter || stubCallback;\n initiatedCallback.leave = callbacks.leave || stubCallback;\n return initiatedCallback;\n}\n/**\n * 广度优先遍历图\n * @param graph Graph 图实例\n * @param startNode 开始遍历的节点\n * @param originalCallbacks 回调\n */\n\n\nvar bfs_breadthFirstSearch = function breadthFirstSearch(graphData, startNodeId, originalCallbacks, directed) {\n if (directed === void 0) {\n directed = true;\n }\n\n var callbacks = initCallbacks(originalCallbacks);\n var nodeQueue = new structs_queue();\n var _a = graphData.edges,\n edges = _a === void 0 ? [] : _a; // 初始化队列元素\n\n nodeQueue.enqueue(startNodeId);\n var previousNode = '';\n\n var _loop_1 = function _loop_1() {\n var currentNode = nodeQueue.dequeue();\n callbacks.enter({\n current: currentNode,\n previous: previousNode\n }); // 将所有邻居添加到队列中以便遍历\n\n getNeighbors(currentNode, edges, directed ? 'target' : undefined).forEach(function (nextNode) {\n if (callbacks.allowTraversal({\n previous: previousNode,\n current: currentNode,\n next: nextNode\n })) {\n nodeQueue.enqueue(nextNode);\n }\n });\n callbacks.leave({\n current: currentNode,\n previous: previousNode\n }); // 下一次循环之前存储当前顶点\n\n previousNode = currentNode;\n }; // 遍历队列中的所有顶点\n\n\n while (!nodeQueue.isEmpty()) {\n _loop_1();\n }\n};\n\n/* harmony default export */ var bfs = (bfs_breadthFirstSearch);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/connected-component.js\n\n/**\n * Generate all connected components for an undirected graph\n * @param graph\n */\n\nvar connected_component_detectConnectedComponents = function detectConnectedComponents(graphData) {\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var allComponents = [];\n var visited = {};\n var nodeStack = [];\n\n var getComponent = function getComponent(node) {\n nodeStack.push(node);\n visited[node.id] = true;\n var neighbors = getNeighbors(node.id, edges);\n\n var _loop_1 = function _loop_1(i) {\n var neighbor = neighbors[i];\n\n if (!visited[neighbor]) {\n var targetNode = nodes.filter(function (node) {\n return node.id === neighbor;\n });\n\n if (targetNode.length > 0) {\n getComponent(targetNode[0]);\n }\n }\n };\n\n for (var i = 0; i < neighbors.length; ++i) {\n _loop_1(i);\n }\n };\n\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n\n if (!visited[node.id]) {\n // 对于无向图进行dfs遍历,每一次调用后都得到一个连通分量\n getComponent(node);\n var component = [];\n\n while (nodeStack.length > 0) {\n component.push(nodeStack.pop());\n }\n\n allComponents.push(component);\n }\n }\n\n return allComponents;\n};\n/**\n * Tarjan's Algorithm 复杂度 O(|V|+|E|)\n * For directed graph only\n * a directed graph is said to be strongly connected if \"every vertex is reachable from every other vertex\".\n * refer: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm\n * @param graph\n * @return a list of strongly connected components\n */\n\nvar connected_component_detectStrongConnectComponents = function detectStrongConnectComponents(graphData) {\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var nodeStack = [];\n var inStack = {}; // 辅助判断是否已经在stack中,减少查找开销\n\n var indices = {};\n var lowLink = {};\n var allComponents = [];\n var index = 0;\n\n var getComponent = function getComponent(node) {\n // Set the depth index for v to the smallest unused index\n indices[node.id] = index;\n lowLink[node.id] = index;\n index += 1;\n nodeStack.push(node);\n inStack[node.id] = true; // 考虑每个邻接点\n\n var neighbors = getNeighbors(node.id, edges, 'target').filter(function (n) {\n return nodes.map(function (node) {\n return node.id;\n }).indexOf(n) > -1;\n });\n\n var _loop_2 = function _loop_2(i) {\n var targetNodeID = neighbors[i];\n\n if (!indices[targetNodeID] && indices[targetNodeID] !== 0) {\n var targetNode = nodes.filter(function (node) {\n return node.id === targetNodeID;\n });\n\n if (targetNode.length > 0) {\n getComponent(targetNode[0]);\n } // tree edge\n\n\n lowLink[node.id] = Math.min(lowLink[node.id], lowLink[targetNodeID]);\n } else if (inStack[targetNodeID]) {\n // back edge, target node is in the current SCC\n lowLink[node.id] = Math.min(lowLink[node.id], indices[targetNodeID]);\n }\n };\n\n for (var i = 0; i < neighbors.length; i++) {\n _loop_2(i);\n } // If node is a root node, generate an SCC\n\n\n if (lowLink[node.id] === indices[node.id]) {\n var component = [];\n\n while (nodeStack.length > 0) {\n var tmpNode = nodeStack.pop();\n inStack[tmpNode.id] = false;\n component.push(tmpNode);\n if (tmpNode === node) break;\n }\n\n if (component.length > 0) {\n allComponents.push(component);\n }\n }\n };\n\n for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {\n var node = nodes_1[_i];\n\n if (!indices[node.id] && indices[node.id] !== 0) {\n getComponent(node);\n }\n }\n\n return allComponents;\n};\nfunction getConnectedComponents(graphData, directed) {\n if (directed) return connected_component_detectStrongConnectComponents(graphData);\n return connected_component_detectConnectedComponents(graphData);\n}\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/degree.js\nvar degree = function degree(graphData) {\n var degrees = {};\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n nodes.forEach(function (node) {\n degrees[node.id] = {\n degree: 0,\n inDegree: 0,\n outDegree: 0\n };\n });\n edges.forEach(function (edge) {\n degrees[edge.source].degree++;\n degrees[edge.source].outDegree++;\n degrees[edge.target].degree++;\n degrees[edge.target].inDegree++;\n });\n return degrees;\n};\n\n/* harmony default export */ var es_degree = (degree);\n/**\n * 获取指定节点的入度\n * @param graphData 图数据\n * @param nodeId 节点ID\n */\n\nvar getInDegree = function getInDegree(graphData, nodeId) {\n var nodeDegree = degree(graphData);\n\n if (nodeDegree[nodeId]) {\n return degree(graphData)[nodeId].inDegree;\n }\n\n return 0;\n};\n/**\n * 获取指定节点的出度\n * @param graphData 图数据\n * @param nodeId 节点ID\n */\n\nvar getOutDegree = function getOutDegree(graphData, nodeId) {\n var nodeDegree = degree(graphData);\n\n if (nodeDegree[nodeId]) {\n return degree(graphData)[nodeId].outDegree;\n }\n\n return 0;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/dfs.js\n\n\nfunction dfs_initCallbacks(callbacks) {\n if (callbacks === void 0) {\n callbacks = {};\n }\n\n var initiatedCallback = callbacks;\n\n var stubCallback = function stubCallback() {};\n\n var allowTraversalCallback = function () {\n var seen = {};\n return function (_a) {\n var next = _a.next;\n\n if (!seen[next]) {\n seen[next] = true;\n return true;\n }\n\n return false;\n };\n }();\n\n initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback;\n initiatedCallback.enter = callbacks.enter || stubCallback;\n initiatedCallback.leave = callbacks.leave || stubCallback;\n return initiatedCallback;\n}\n/**\n * @param {Graph} graph\n * @param {GraphNode} currentNode\n * @param {GraphNode} previousNode\n * @param {Callbacks} callbacks\n */\n\n\nfunction depthFirstSearchRecursive(graphData, currentNode, previousNode, callbacks) {\n callbacks.enter({\n current: currentNode,\n previous: previousNode\n });\n var _a = graphData.edges,\n edges = _a === void 0 ? [] : _a;\n getNeighbors(currentNode, edges, 'target').forEach(function (nextNode) {\n if (callbacks.allowTraversal({\n previous: previousNode,\n current: currentNode,\n next: nextNode\n })) {\n depthFirstSearchRecursive(graphData, nextNode, currentNode, callbacks);\n }\n });\n callbacks.leave({\n current: currentNode,\n previous: previousNode\n });\n}\n/**\n * 深度优先遍历图\n * @param data GraphData 图数据\n * @param startNodeId 开始遍历的节点的 ID\n * @param originalCallbacks 回调\n */\n\n\nfunction depthFirstSearch(graphData, startNodeId, callbacks) {\n depthFirstSearchRecursive(graphData, startNodeId, '', dfs_initCallbacks(callbacks));\n}\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/detect-cycle.js\n\n\n\n\nvar detect_cycle_detectDirectedCycle = function detectDirectedCycle(graphData) {\n var cycle = null;\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a;\n var dfsParentMap = {}; // 所有没有被访问的节点集合\n\n var unvisitedSet = {}; // 正在被访问的节点集合\n\n var visitingSet = {}; // 所有已经被访问过的节点集合\n\n var visitedSet = {}; // 初始化 unvisitedSet\n\n nodes.forEach(function (node) {\n unvisitedSet[node.id] = node;\n });\n var callbacks = {\n enter: function enter(_a) {\n var currentNode = _a.current,\n previousNode = _a.previous;\n\n if (visitingSet[currentNode]) {\n // 如果当前节点正在访问中,则说明检测到环路了\n cycle = {};\n var currentCycleNode = currentNode;\n var previousCycleNode = previousNode;\n\n while (previousCycleNode !== currentNode) {\n cycle[currentCycleNode] = previousCycleNode;\n currentCycleNode = previousCycleNode;\n previousCycleNode = dfsParentMap[previousCycleNode];\n }\n\n cycle[currentCycleNode] = previousCycleNode;\n } else {\n // 如果不存在正在访问集合中,则将其放入正在访问集合,并从未访问集合中删除\n visitingSet[currentNode] = currentNode;\n delete unvisitedSet[currentNode]; // 更新 DSF parents 列表\n\n dfsParentMap[currentNode] = previousNode;\n }\n },\n leave: function leave(_a) {\n var currentNode = _a.current; // 如果所有的节点的子节点都已经访问过了,则从正在访问集合中删除掉,并将其移入到已访问集合中,\n // 同时也意味着当前节点的所有邻居节点都被访问过了\n\n visitedSet[currentNode] = currentNode;\n delete visitingSet[currentNode];\n },\n allowTraversal: function allowTraversal(_a) {\n var nextNode = _a.next; // 如果检测到环路则需要终止所有进一步的遍历,否则会导致无限循环遍历\n\n if (cycle) {\n return false;\n } // 仅允许遍历没有访问的节点,visitedSet 中的都已经访问过了\n\n\n return !visitedSet[nextNode];\n }\n }; // 开始遍历节点\n\n while (Object.keys(unvisitedSet).length) {\n // 从第一个节点开始进行 DFS 遍历\n var firsetUnVisitedKey = Object.keys(unvisitedSet)[0];\n depthFirstSearch(graphData, firsetUnVisitedKey, callbacks);\n }\n\n return cycle;\n};\n/**\n * 检测无向图中的所有Base cycles\n * refer: https://www.codeproject.com/Articles/1158232/Enumerating-All-Cycles-in-an-Undirected-Graph\n * @param graph\n * @param nodeIds 节点 ID 的数组\n * @param include 包含或排除指定的节点\n * @return [{[key: string]: INode}] 返回一组base cycles\n */\n\n\nvar detect_cycle_detectAllUndirectedCycle = function detectAllUndirectedCycle(graphData, nodeIds, include) {\n var _a, _b;\n\n if (include === void 0) {\n include = true;\n }\n\n var allCycles = [];\n var components = getConnectedComponents(graphData, false); // loop through all connected components\n\n for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {\n var component = components_1[_i];\n if (!component.length) continue;\n var root = component[0];\n var rootId = root.id;\n var stack = [root];\n var parent_1 = (_a = {}, _a[rootId] = root, _a);\n var used = (_b = {}, _b[rootId] = new Set(), _b); // walk a spanning tree to find cycles\n\n while (stack.length > 0) {\n var curNode = stack.pop();\n var curNodeId = curNode.id;\n var neighbors = getNeighbors(curNodeId, graphData.edges);\n\n var _loop_1 = function _loop_1(i) {\n var _c;\n\n var neighborId = neighbors[i];\n var neighbor = graphData.nodes.find(function (node) {\n return node.id === neighborId;\n }); // const neighborId = neighbor.get('id');\n\n if (neighborId === curNodeId) {\n // 自环\n allCycles.push((_c = {}, _c[neighborId] = curNode, _c));\n } else if (!(neighborId in used)) {\n // visit a new node\n parent_1[neighborId] = curNode;\n stack.push(neighbor);\n used[neighborId] = new Set([curNode]);\n } else if (!used[curNodeId].has(neighbor)) {\n // a cycle found\n var cycleValid = true;\n var cyclePath = [neighbor, curNode];\n var p = parent_1[curNodeId];\n\n while (used[neighborId].size && !used[neighborId].has(p)) {\n cyclePath.push(p);\n if (p === parent_1[p.id]) break;else p = parent_1[p.id];\n }\n\n cyclePath.push(p);\n\n if (nodeIds && include) {\n // 如果有指定包含的节点\n cycleValid = false;\n\n if (cyclePath.findIndex(function (node) {\n return nodeIds.indexOf(node.id) > -1;\n }) > -1) {\n cycleValid = true;\n }\n } else if (nodeIds && !include) {\n // 如果有指定不包含的节点\n if (cyclePath.findIndex(function (node) {\n return nodeIds.indexOf(node.id) > -1;\n }) > -1) {\n cycleValid = false;\n }\n } // 把 node list 形式转换为 cycle 的格式\n\n\n if (cycleValid) {\n var cycle = {};\n\n for (var index = 1; index < cyclePath.length; index += 1) {\n cycle[cyclePath[index - 1].id] = cyclePath[index];\n }\n\n if (cyclePath.length) {\n cycle[cyclePath[cyclePath.length - 1].id] = cyclePath[0];\n }\n\n allCycles.push(cycle);\n }\n\n used[neighborId].add(curNode);\n }\n };\n\n for (var i = 0; i < neighbors.length; i += 1) {\n _loop_1(i);\n }\n }\n }\n\n return allCycles;\n};\n/**\n * Johnson's algorithm, 时间复杂度 O((V + E)(C + 1))$ and space bounded by O(V + E)\n * refer: https://www.cs.tufts.edu/comp/150GA/homeworks/hw1/Johnson%2075.PDF\n * refer: https://networkx.github.io/documentation/stable/_modules/networkx/algorithms/cycles.html#simple_cycles\n * @param graph\n * @param nodeIds 节点 ID 的数组\n * @param include 包含或排除指定的节点\n * @return [{[key: string]: INode}] 返回所有的 simple cycles\n */\n\nvar detect_cycle_detectAllDirectedCycle = function detectAllDirectedCycle(graphData, nodeIds, include) {\n if (include === void 0) {\n include = true;\n }\n\n var path = []; // stack of nodes in current path\n\n var blocked = new Set();\n var B = []; // remember portions of the graph that yield no elementary circuit\n\n var allCycles = [];\n var idx2Node = {};\n var node2Idx = {}; // 辅助函数: unblock all blocked nodes\n\n var unblock = function unblock(thisNode) {\n var stack = [thisNode];\n\n while (stack.length > 0) {\n var node = stack.pop();\n\n if (blocked.has(node)) {\n blocked.delete(node);\n B[node.id].forEach(function (n) {\n stack.push(n);\n });\n B[node.id].clear();\n }\n }\n };\n\n var circuit = function circuit(node, start, adjList) {\n var closed = false; // whether a path is closed\n\n if (nodeIds && include === false && nodeIds.indexOf(node.id) > -1) return closed;\n path.push(node);\n blocked.add(node);\n var neighbors = adjList[node.id];\n\n for (var i = 0; i < neighbors.length; i += 1) {\n var neighbor = idx2Node[neighbors[i]];\n\n if (neighbor === start) {\n var cycle = {};\n\n for (var index = 1; index < path.length; index += 1) {\n cycle[path[index - 1].id] = path[index];\n }\n\n if (path.length) {\n cycle[path[path.length - 1].id] = path[0];\n }\n\n allCycles.push(cycle);\n closed = true;\n } else if (!blocked.has(neighbor)) {\n if (circuit(neighbor, start, adjList)) {\n closed = true;\n }\n }\n }\n\n if (closed) {\n unblock(node);\n } else {\n for (var i = 0; i < neighbors.length; i += 1) {\n var neighbor = idx2Node[neighbors[i]];\n\n if (!B[neighbor.id].has(node)) {\n B[neighbor.id].add(node);\n }\n }\n }\n\n path.pop();\n return closed;\n };\n\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a; // Johnson's algorithm 要求给节点赋顺序,先按节点在数组中的顺序\n\n for (var i = 0; i < nodes.length; i += 1) {\n var node = nodes[i];\n var nodeId = node.id;\n node2Idx[nodeId] = i;\n idx2Node[i] = node;\n } // 如果有指定包含的节点,则把指定节点排序在前,以便提早结束搜索\n\n\n if (nodeIds && include) {\n var _loop_2 = function _loop_2(i) {\n var nodeId = nodeIds[i];\n node2Idx[nodes[i].id] = node2Idx[nodeId];\n node2Idx[nodeId] = 0;\n idx2Node[0] = nodes.find(function (node) {\n return node.id === nodeId;\n });\n idx2Node[node2Idx[nodes[i].id]] = nodes[i];\n };\n\n for (var i = 0; i < nodeIds.length; i++) {\n _loop_2(i);\n }\n } // 返回 节点顺序 >= nodeOrder 的强连通分量的adjList\n\n\n var getMinComponentAdj = function getMinComponentAdj(components) {\n var _a;\n\n var minCompIdx;\n var minIdx = Infinity; // Find least component and the lowest node\n\n for (var i = 0; i < components.length; i += 1) {\n var comp = components[i];\n\n for (var j = 0; j < comp.length; j++) {\n var nodeIdx_1 = node2Idx[comp[j].id];\n\n if (nodeIdx_1 < minIdx) {\n minIdx = nodeIdx_1;\n minCompIdx = i;\n }\n }\n }\n\n var component = components[minCompIdx];\n var adjList = [];\n\n for (var i = 0; i < component.length; i += 1) {\n var node = component[i];\n adjList[node.id] = [];\n\n for (var _i = 0, _b = getNeighbors(node.id, graphData.edges, 'target').filter(function (n) {\n return component.map(function (c) {\n return c.id;\n }).indexOf(n) > -1;\n }); _i < _b.length; _i++) {\n var neighbor = _b[_i]; // 对自环情况 (点连向自身) 特殊处理:记录自环,但不加入adjList\n\n if (neighbor === node.id && !(include === false && nodeIds.indexOf(node.id) > -1)) {\n allCycles.push((_a = {}, _a[node.id] = node, _a));\n } else {\n adjList[node.id].push(node2Idx[neighbor]);\n }\n }\n }\n\n return {\n component: component,\n adjList: adjList,\n minIdx: minIdx\n };\n };\n\n var nodeIdx = 0;\n\n while (nodeIdx < nodes.length) {\n var subgraphNodes = nodes.filter(function (n) {\n return node2Idx[n.id] >= nodeIdx;\n });\n var sccs = connected_component_detectStrongConnectComponents({\n nodes: subgraphNodes,\n edges: graphData.edges\n }).filter(function (component) {\n return component.length > 1;\n });\n if (sccs.length === 0) break;\n var scc = getMinComponentAdj(sccs);\n var minIdx = scc.minIdx,\n adjList = scc.adjList,\n component = scc.component;\n\n if (component.length > 1) {\n component.forEach(function (node) {\n B[node.id] = new Set();\n });\n var startNode = idx2Node[minIdx]; // startNode 不在指定要包含的节点中,提前结束搜索\n\n if (nodeIds && include && nodeIds.indexOf(startNode.id) === -1) return allCycles;\n circuit(startNode, startNode, adjList);\n nodeIdx = minIdx + 1;\n } else {\n break;\n }\n }\n\n return allCycles;\n};\n/**\n * 查找图中所有满足要求的圈\n * @param graph\n * @param directed 是否为有向图\n * @param nodeIds 节点 ID 的数组,若不指定,则返回图中所有的圈\n * @param include 包含或排除指定的节点\n * @return [{[key: string]: Node}] 包含所有环的数组,每个环用一个Object表示,其中key为节点id,value为该节点在环中指向的下一个节点\n */\n\nvar detectAllCycles = function detectAllCycles(graphData, directed, nodeIds, include) {\n if (include === void 0) {\n include = true;\n }\n\n if (directed) return detect_cycle_detectAllDirectedCycle(graphData, nodeIds, include);\n return detect_cycle_detectAllUndirectedCycle(graphData, nodeIds, include);\n};\n/* harmony default export */ var detect_cycle = (detect_cycle_detectDirectedCycle);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/dijkstra.js\n\n\n\n\nvar minVertex = function minVertex(D, nodes, marks) {\n // 找出最小的点\n var minDis = Infinity;\n var minNode;\n\n for (var i = 0; i < nodes.length; i++) {\n var nodeId = nodes[i].id;\n\n if (!marks[nodeId] && D[nodeId] <= minDis) {\n minDis = D[nodeId];\n minNode = nodes[i];\n }\n }\n\n return minNode;\n};\n\nvar dijkstra_dijkstra = function dijkstra(graphData, source, directed, weightPropertyName) {\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var nodeIds = [];\n var marks = {};\n var D = {};\n var prevs = {}; // key: 顶点, value: 顶点的前驱点数组(可能有多条等长的最短路径)\n\n nodes.forEach(function (node, i) {\n var id = node.id;\n nodeIds.push(id);\n D[id] = Infinity;\n if (id === source) D[id] = 0;\n });\n var nodeNum = nodes.length;\n\n var _loop_1 = function _loop_1(i) {\n // Process the vertices\n var minNode = minVertex(D, nodes, marks);\n var minNodeId = minNode.id;\n marks[minNodeId] = true;\n if (D[minNodeId] === Infinity) return \"continue\"; // Unreachable vertices cannot be the intermediate point\n\n var relatedEdges = [];\n if (directed) relatedEdges = getOutEdgesNodeId(minNodeId, edges);else relatedEdges = getEdgesByNodeId(minNodeId, edges);\n relatedEdges.forEach(function (edge) {\n var edgeTarget = edge.target;\n var edgeSource = edge.source;\n var w = edgeTarget === minNodeId ? edgeSource : edgeTarget;\n var weight = weightPropertyName && edge[weightPropertyName] ? edge[weightPropertyName] : 1;\n\n if (D[w] > D[minNode.id] + weight) {\n D[w] = D[minNode.id] + weight;\n prevs[w] = [minNode.id];\n } else if (D[w] === D[minNode.id] + weight) {\n prevs[w].push(minNode.id);\n }\n });\n };\n\n for (var i = 0; i < nodeNum; i++) {\n _loop_1(i);\n }\n\n prevs[source] = [source]; // 每个节点存可能存在多条最短路径\n\n var paths = {};\n\n for (var target in D) {\n if (D[target] !== Infinity) {\n findAllPaths(source, target, prevs, paths);\n }\n } // 兼容之前单路径\n\n\n var path = {};\n\n for (var target in paths) {\n path[target] = paths[target][0];\n }\n\n return {\n length: D,\n path: path,\n allPath: paths\n };\n};\n\n/* harmony default export */ var es_dijkstra = (dijkstra_dijkstra);\n\nfunction findAllPaths(source, target, prevs, foundPaths) {\n if (source === target) {\n return [source];\n }\n\n if (foundPaths[target]) {\n return foundPaths[target];\n }\n\n var paths = [];\n\n for (var _i = 0, _a = prevs[target]; _i < _a.length; _i++) {\n var prev = _a[_i];\n var prevPaths = findAllPaths(source, prev, prevs, foundPaths);\n if (!prevPaths) return;\n\n for (var _b = 0, prevPaths_1 = prevPaths; _b < prevPaths_1.length; _b++) {\n var prePath = prevPaths_1[_b];\n if (Object(esm[\"isArray\"])(prePath)) paths.push(Object(tslib_es6[\"__spreadArray\"])(Object(tslib_es6[\"__spreadArray\"])([], prePath), [target]));else paths.push([prePath, target]);\n }\n }\n\n foundPaths[target] = paths;\n return foundPaths[target];\n}\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/find-path.js\n\n\nvar find_path_findShortestPath = function findShortestPath(graphData, start, end, directed, weightPropertyName) {\n var _a = es_dijkstra(graphData, start, directed, weightPropertyName),\n length = _a.length,\n path = _a.path,\n allPath = _a.allPath;\n\n return {\n length: length[end],\n path: path[end],\n allPath: allPath[end]\n };\n};\nvar find_path_findAllPath = function findAllPath(graphData, start, end, directed) {\n var _a;\n\n if (start === end) return [[start]];\n var _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var visited = [start];\n var isVisited = (_a = {}, _a[start] = true, _a);\n var stack = []; // 辅助栈,用于存储访问过的节点的邻居节点\n\n var allPath = [];\n var neighbors = directed ? getNeighbors(start, edges, 'target') : getNeighbors(start, edges);\n stack.push(neighbors);\n\n while (visited.length > 0 && stack.length > 0) {\n var children = stack[stack.length - 1];\n\n if (children.length) {\n var child = children.shift();\n\n if (child) {\n visited.push(child);\n isVisited[child] = true;\n neighbors = directed ? getNeighbors(child, edges, 'target') : getNeighbors(child, edges);\n stack.push(neighbors.filter(function (neighbor) {\n return !isVisited[neighbor];\n }));\n }\n } else {\n var node = visited.pop();\n isVisited[node] = false;\n stack.pop();\n continue;\n }\n\n if (visited[visited.length - 1] === end) {\n var path = visited.map(function (node) {\n return node;\n });\n allPath.push(path);\n var node = visited.pop();\n isVisited[node] = false;\n stack.pop();\n }\n }\n\n return allPath;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/floydWarshall.js\n\n\nvar floydWarshall_floydWarshall = function floydWarshall(graphData, directed) {\n var adjacentMatrix = adjacent_matrix(graphData, directed);\n var dist = [];\n var size = adjacentMatrix.length;\n\n for (var i = 0; i < size; i += 1) {\n dist[i] = [];\n\n for (var j = 0; j < size; j += 1) {\n if (i === j) {\n dist[i][j] = 0;\n } else if (adjacentMatrix[i][j] === 0 || !adjacentMatrix[i][j]) {\n dist[i][j] = Infinity;\n } else {\n dist[i][j] = adjacentMatrix[i][j];\n }\n }\n } // floyd\n\n\n for (var k = 0; k < size; k += 1) {\n for (var i = 0; i < size; i += 1) {\n for (var j = 0; j < size; j += 1) {\n if (dist[i][j] > dist[i][k] + dist[k][j]) {\n dist[i][j] = dist[i][k] + dist[k][j];\n }\n }\n }\n }\n\n return dist;\n};\n\n/* harmony default export */ var es_floydWarshall = (floydWarshall_floydWarshall);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/label-propagation.js\n\n\n/**\n * 标签传播算法\n * @param graphData 图数据\n * @param directed 是否有向图,默认为 false\n * @param weightPropertyName 权重的属性字段\n * @param maxIteration 最大迭代次数\n */\n\nvar label_propagation_labelPropagation = function labelPropagation(graphData, directed, weightPropertyName, maxIteration) {\n if (directed === void 0) {\n directed = false;\n }\n\n if (weightPropertyName === void 0) {\n weightPropertyName = 'weight';\n }\n\n if (maxIteration === void 0) {\n maxIteration = 1000;\n } // the origin data\n\n\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var clusters = {};\n var nodeMap = {}; // init the clusters and nodeMap\n\n nodes.forEach(function (node, i) {\n var cid = util_uniqueId();\n node.clusterId = cid;\n clusters[cid] = {\n id: cid,\n nodes: [node]\n };\n nodeMap[node.id] = {\n node: node,\n idx: i\n };\n }); // the adjacent matrix of calNodes inside clusters\n\n var adjMatrix = adjacent_matrix(graphData, directed); // the sum of each row in adjacent matrix\n\n var ks = [];\n /**\n * neighbor nodes (id for key and weight for value) for each node\n * neighbors = {\n * id(node_id): { id(neighbor_1_id): weight(weight of the edge), id(neighbor_2_id): weight(weight of the edge), ... },\n * ...\n * }\n */\n\n var neighbors = {};\n adjMatrix.forEach(function (row, i) {\n var k = 0;\n var iid = nodes[i].id;\n neighbors[iid] = {};\n row.forEach(function (entry, j) {\n if (!entry) return;\n k += entry;\n var jid = nodes[j].id;\n neighbors[iid][jid] = entry;\n });\n ks.push(k);\n });\n var iter = 0;\n\n var _loop_1 = function _loop_1() {\n var changed = false;\n nodes.forEach(function (node) {\n var neighborClusters = {};\n Object.keys(neighbors[node.id]).forEach(function (neighborId) {\n var neighborWeight = neighbors[node.id][neighborId];\n var neighborNode = nodeMap[neighborId].node;\n var neighborClusterId = neighborNode.clusterId;\n if (!neighborClusters[neighborClusterId]) neighborClusters[neighborClusterId] = 0;\n neighborClusters[neighborClusterId] += neighborWeight;\n }); // find the cluster with max weight\n\n var maxWeight = -Infinity;\n var bestClusterIds = [];\n Object.keys(neighborClusters).forEach(function (clusterId) {\n if (maxWeight < neighborClusters[clusterId]) {\n maxWeight = neighborClusters[clusterId];\n bestClusterIds = [clusterId];\n } else if (maxWeight === neighborClusters[clusterId]) {\n bestClusterIds.push(clusterId);\n }\n });\n if (bestClusterIds.length === 1 && bestClusterIds[0] === node.clusterId) return;\n var selfClusterIdx = bestClusterIds.indexOf(node.clusterId);\n if (selfClusterIdx >= 0) bestClusterIds.splice(selfClusterIdx, 1);\n\n if (bestClusterIds && bestClusterIds.length) {\n changed = true; // remove from origin cluster\n\n var selfCluster = clusters[node.clusterId];\n var nodeInSelfClusterIdx = selfCluster.nodes.indexOf(node);\n selfCluster.nodes.splice(nodeInSelfClusterIdx, 1); // move the node to the best cluster\n\n var randomIdx = Math.floor(Math.random() * bestClusterIds.length);\n var bestCluster = clusters[bestClusterIds[randomIdx]];\n bestCluster.nodes.push(node);\n node.clusterId = bestCluster.id;\n }\n });\n if (!changed) return \"break\";\n iter++;\n };\n\n while (iter < maxIteration) {\n var state_1 = _loop_1();\n\n if (state_1 === \"break\") break;\n } // delete the empty clusters\n\n\n Object.keys(clusters).forEach(function (clusterId) {\n var cluster = clusters[clusterId];\n\n if (!cluster.nodes || !cluster.nodes.length) {\n delete clusters[clusterId];\n }\n }); // get the cluster edges\n\n var clusterEdges = [];\n var clusterEdgeMap = {};\n edges.forEach(function (edge) {\n var source = edge.source,\n target = edge.target;\n var weight = edge[weightPropertyName] || 1;\n var sourceClusterId = nodeMap[source].node.clusterId;\n var targetClusterId = nodeMap[target].node.clusterId;\n var newEdgeId = sourceClusterId + \"---\" + targetClusterId;\n\n if (clusterEdgeMap[newEdgeId]) {\n clusterEdgeMap[newEdgeId].weight += weight;\n clusterEdgeMap[newEdgeId].count++;\n } else {\n var newEdge = {\n source: sourceClusterId,\n target: targetClusterId,\n weight: weight,\n count: 1\n };\n clusterEdgeMap[newEdgeId] = newEdge;\n clusterEdges.push(newEdge);\n }\n });\n var clustersArray = [];\n Object.keys(clusters).forEach(function (clusterId) {\n clustersArray.push(clusters[clusterId]);\n });\n return {\n clusters: clustersArray,\n clusterEdges: clusterEdges\n };\n};\n\n/* harmony default export */ var label_propagation = (label_propagation_labelPropagation);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/louvain.js\n\n\nvar getModularity = function getModularity(nodes, adjMatrix, ks, m) {\n var length = adjMatrix.length;\n var param = 2 * m;\n var modularity = 0;\n\n for (var i = 0; i < length; i++) {\n var clusteri = nodes[i].clusterId;\n\n for (var j = 0; j < length; j++) {\n var clusterj = nodes[j].clusterId;\n if (clusteri !== clusterj) continue;\n var entry = adjMatrix[i][j] || 0;\n var ki = ks[i] || 0;\n var kj = ks[j] || 0;\n modularity += entry - ki * kj / param;\n }\n }\n\n modularity *= 1 / param;\n return modularity;\n};\n/**\n * 社区发现 louvain 算法\n * @param graphData 图数据\n * @param directed 是否有向图,默认为 false\n * @param weightPropertyName 权重的属性字段\n * @param threshold\n */\n\n\nvar louvain_louvain = function louvain(graphData, directed, weightPropertyName, threshold) {\n if (directed === void 0) {\n directed = false;\n }\n\n if (weightPropertyName === void 0) {\n weightPropertyName = 'weight';\n }\n\n if (threshold === void 0) {\n threshold = 0.0001;\n } // the origin data\n\n\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var uniqueId = 1;\n var clusters = {};\n var nodeMap = {}; // init the clusters and nodeMap\n\n nodes.forEach(function (node, i) {\n var cid = String(uniqueId++);\n node.clusterId = cid;\n clusters[cid] = {\n id: cid,\n nodes: [node]\n };\n nodeMap[node.id] = {\n node: node,\n idx: i\n };\n }); // the adjacent matrix of calNodes inside clusters\n\n var adjMatrix = adjacent_matrix(graphData, directed); // the sum of each row in adjacent matrix\n\n var ks = [];\n /**\n * neighbor nodes (id for key and weight for value) for each node\n * neighbors = {\n * id(node_id): { id(neighbor_1_id): weight(weight of the edge), id(neighbor_2_id): weight(weight of the edge), ... },\n * ...\n * }\n */\n\n var neighbors = {}; // the sum of the weights of all edges in the graph\n\n var m = 0;\n adjMatrix.forEach(function (row, i) {\n var k = 0;\n var iid = nodes[i].id;\n neighbors[iid] = {};\n row.forEach(function (entry, j) {\n if (!entry) return;\n k += entry;\n var jid = nodes[j].id;\n neighbors[iid][jid] = entry;\n m += entry;\n });\n ks.push(k);\n });\n m /= 2;\n var totalModularity = Infinity;\n var previousModularity = Infinity;\n var iter = 0;\n\n while (true) {\n // whether to terminate the iterations\n totalModularity = getModularity(nodes, adjMatrix, ks, m);\n if (Math.abs(totalModularity - previousModularity) < threshold || iter > 100) break;\n previousModularity = totalModularity;\n iter++; // pre compute some values for current clusters\n\n Object.keys(clusters).forEach(function (clusterId) {\n // sum of weights of edges to nodes in cluster\n var sumTot = 0;\n edges.forEach(function (edge) {\n var source = edge.source,\n target = edge.target;\n var sourceClusterId = nodeMap[source].node.clusterId;\n var targetClusterId = nodeMap[target].node.clusterId;\n\n if (sourceClusterId === clusterId && targetClusterId !== clusterId || targetClusterId === clusterId && sourceClusterId !== clusterId) {\n sumTot = sumTot + (edge[weightPropertyName] || 1);\n }\n });\n clusters[clusterId].sumTot = sumTot;\n }); // move the nodes to increase the delta modularity\n\n nodes.forEach(function (node, i) {\n var selfCluster = clusters[node.clusterId];\n var bestIncrease = 0;\n var bestCluster;\n var commonParam = ks[i] / (2 * m); // sum of weights of edges from node to nodes in cluster\n\n var kiin = 0;\n var selfClusterNodes = selfCluster.nodes;\n selfClusterNodes.forEach(function (scNode) {\n var scNodeIdx = nodeMap[scNode.id].idx;\n kiin += adjMatrix[i][scNodeIdx] || 0;\n }); // the modurarity for **removing** the node i from the origin cluster of node i\n\n var removeModurarity = kiin - selfCluster.sumTot * commonParam; // the neightbors of the node\n\n var nodeNeighborIds = neighbors[node.id];\n Object.keys(nodeNeighborIds).forEach(function (neighborNodeId) {\n var neighborNode = nodeMap[neighborNodeId].node;\n var neighborClusterId = neighborNode.clusterId; // if the node and the neighbor of node are in the same cluster, reutrn\n\n if (neighborClusterId === node.clusterId) return;\n var neighborCluster = clusters[neighborClusterId];\n var clusterNodes = neighborCluster.nodes; // if the cluster is empty, remove the cluster and return\n\n if (!clusterNodes || !clusterNodes.length) return; // sum of weights of edges from node to nodes in cluster\n\n var neighborClusterKiin = 0;\n clusterNodes.forEach(function (cNode) {\n var cNodeIdx = nodeMap[cNode.id].idx;\n neighborClusterKiin += adjMatrix[i][cNodeIdx] || 0;\n }); // modurarity for **adding** node i into this neighbor cluster\n\n var addModurarity = neighborClusterKiin - neighborCluster.sumTot * commonParam; // the increase modurarity is the difference between addModurarity and removeModurarity\n\n var increase = addModurarity - removeModurarity; // find the best cluster to move node i into\n\n if (increase > bestIncrease) {\n bestIncrease = increase;\n bestCluster = neighborCluster;\n }\n }); // if found a best cluster to move into\n\n if (bestIncrease > 0) {\n bestCluster.nodes.push(node);\n var previousClusterId_1 = node.clusterId;\n node.clusterId = bestCluster.id; // move the node to the best cluster\n\n var nodeInSelfClusterIdx = selfCluster.nodes.indexOf(node); // remove from origin cluster\n\n selfCluster.nodes.splice(nodeInSelfClusterIdx, 1); // update sumTot for clusters\n // sum of weights of edges to nodes in cluster\n\n var neighborClusterSumTot_1 = 0;\n var selfClusterSumTot_1 = 0;\n edges.forEach(function (edge) {\n var source = edge.source,\n target = edge.target;\n var sourceClusterId = nodeMap[source].node.clusterId;\n var targetClusterId = nodeMap[target].node.clusterId;\n\n if (sourceClusterId === bestCluster.id && targetClusterId !== bestCluster.id || targetClusterId === bestCluster.id && sourceClusterId !== bestCluster.id) {\n neighborClusterSumTot_1 = neighborClusterSumTot_1 + (edge[weightPropertyName] || 1);\n }\n\n if (sourceClusterId === previousClusterId_1 && targetClusterId !== previousClusterId_1 || targetClusterId === previousClusterId_1 && sourceClusterId !== previousClusterId_1) {\n selfClusterSumTot_1 = selfClusterSumTot_1 + (edge[weightPropertyName] || 1);\n }\n }); // the nodes of the clusters to move into and remove are changed, update their sumTot\n\n bestCluster.sumTot = neighborClusterSumTot_1;\n selfCluster.sumTot = selfClusterSumTot_1;\n }\n });\n } // delete the empty clusters, assign increasing clusterId\n\n\n var newClusterIdMap = {};\n var clusterIdx = 0;\n Object.keys(clusters).forEach(function (clusterId) {\n var cluster = clusters[clusterId];\n\n if (!cluster.nodes || !cluster.nodes.length) {\n delete clusters[clusterId];\n return;\n }\n\n var newId = String(clusterIdx + 1);\n\n if (newId === clusterId) {\n return;\n }\n\n cluster.id = newId;\n cluster.nodes = cluster.nodes.map(function (item) {\n return {\n id: item.id,\n clusterId: newId\n };\n });\n clusters[newId] = cluster;\n newClusterIdMap[clusterId] = newId;\n delete clusters[clusterId];\n clusterIdx++;\n });\n nodes.forEach(function (node) {\n if (node.clusterId && newClusterIdMap[node.clusterId]) node.clusterId = newClusterIdMap[node.clusterId];\n }); // get the cluster edges\n\n var clusterEdges = [];\n var clusterEdgeMap = {};\n edges.forEach(function (edge) {\n var source = edge.source,\n target = edge.target;\n var weight = edge[weightPropertyName] || 1;\n var sourceClusterId = nodeMap[source].node.clusterId;\n var targetClusterId = nodeMap[target].node.clusterId;\n var newEdgeId = sourceClusterId + \"---\" + targetClusterId;\n\n if (clusterEdgeMap[newEdgeId]) {\n clusterEdgeMap[newEdgeId].weight += weight;\n clusterEdgeMap[newEdgeId].count++;\n } else {\n var newEdge = {\n source: sourceClusterId,\n target: targetClusterId,\n weight: weight,\n count: 1\n };\n clusterEdgeMap[newEdgeId] = newEdge;\n clusterEdges.push(newEdge);\n }\n });\n var clustersArray = [];\n Object.keys(clusters).forEach(function (clusterId) {\n clustersArray.push(clusters[clusterId]);\n });\n return {\n clusters: clustersArray,\n clusterEdges: clusterEdges\n };\n};\n\n/* harmony default export */ var es_louvain = (louvain_louvain);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/structs/union-find.js\n/**\n * 并查集 Disjoint set to support quick union\n */\nvar UnionFind =\n/** @class */\nfunction () {\n function UnionFind(items) {\n this.count = items.length;\n this.parent = {};\n\n for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {\n var i = items_1[_i];\n this.parent[i] = i;\n }\n } // find the root of the item\n\n\n UnionFind.prototype.find = function (item) {\n while (this.parent[item] !== item) {\n item = this.parent[item];\n }\n\n return item;\n };\n\n UnionFind.prototype.union = function (a, b) {\n var rootA = this.find(a);\n var rootB = this.find(b);\n if (rootA === rootB) return; // make the element with smaller root the parent\n\n if (rootA < rootB) {\n if (this.parent[b] !== b) this.union(this.parent[b], a);\n this.parent[b] = this.parent[a];\n } else {\n if (this.parent[a] !== a) this.union(this.parent[a], b);\n this.parent[a] = this.parent[b];\n }\n }; // whether a and b are connected, i.e. a and b have the same root\n\n\n UnionFind.prototype.connected = function (a, b) {\n return this.find(a) === this.find(b);\n };\n\n return UnionFind;\n}();\n\n/* harmony default export */ var union_find = (UnionFind);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/structs/binary-heap.js\nvar defaultCompare = function defaultCompare(a, b) {\n return a - b;\n};\n\nvar MinBinaryHeap =\n/** @class */\nfunction () {\n function MinBinaryHeap(compareFn) {\n if (compareFn === void 0) {\n compareFn = defaultCompare;\n }\n\n this.compareFn = compareFn;\n this.list = [];\n }\n\n MinBinaryHeap.prototype.getLeft = function (index) {\n return 2 * index + 1;\n };\n\n MinBinaryHeap.prototype.getRight = function (index) {\n return 2 * index + 2;\n };\n\n MinBinaryHeap.prototype.getParent = function (index) {\n if (index === 0) {\n return null;\n }\n\n return Math.floor((index - 1) / 2);\n };\n\n MinBinaryHeap.prototype.isEmpty = function () {\n return this.list.length <= 0;\n };\n\n MinBinaryHeap.prototype.top = function () {\n return this.isEmpty() ? undefined : this.list[0];\n };\n\n MinBinaryHeap.prototype.delMin = function () {\n var top = this.top();\n var bottom = this.list.pop();\n\n if (this.list.length > 0) {\n this.list[0] = bottom;\n this.moveDown(0);\n }\n\n return top;\n };\n\n MinBinaryHeap.prototype.insert = function (value) {\n if (value !== null) {\n this.list.push(value);\n var index = this.list.length - 1;\n this.moveUp(index);\n return true;\n }\n\n return false;\n };\n\n MinBinaryHeap.prototype.moveUp = function (index) {\n var parent = this.getParent(index);\n\n while (index && index > 0 && this.compareFn(this.list[parent], this.list[index]) > 0) {\n // swap\n var tmp = this.list[parent];\n this.list[parent] = this.list[index];\n this.list[index] = tmp; // [this.list[index], this.list[parent]] = [this.list[parent], this.list[index]]\n\n index = parent;\n parent = this.getParent(index);\n }\n };\n\n MinBinaryHeap.prototype.moveDown = function (index) {\n var _a;\n\n var element = index;\n var left = this.getLeft(index);\n var right = this.getRight(index);\n var size = this.list.length;\n\n if (left !== null && left < size && this.compareFn(this.list[element], this.list[left]) > 0) {\n element = left;\n } else if (right !== null && right < size && this.compareFn(this.list[element], this.list[right]) > 0) {\n element = right;\n }\n\n if (index !== element) {\n _a = [this.list[element], this.list[index]], this.list[index] = _a[0], this.list[element] = _a[1];\n this.moveDown(element);\n }\n };\n\n return MinBinaryHeap;\n}();\n\n/* harmony default export */ var binary_heap = (MinBinaryHeap);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/mts.js\n\n\n\n/**\n * Prim algorithm,use priority queue,复杂度 O(E+V*logV), V: 节点数量,E: 边的数量\n * refer: https://en.wikipedia.org/wiki/Prim%27s_algorithm\n * @param graph\n * @param weight 指定用于作为边权重的属性,若不指定,则认为所有边权重一致\n */\n\nvar mts_primMST = function primMST(graphData, weight) {\n var selectedEdges = [];\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n\n if (nodes.length === 0) {\n return selectedEdges;\n } // 从nodes[0]开始\n\n\n var currNode = nodes[0];\n var visited = new Set();\n visited.add(currNode); // 用二叉堆维护距已加入节点的其他节点的边的权值\n\n var compareWeight = function compareWeight(a, b) {\n if (weight) {\n return a.weight - b.weight;\n }\n\n return 0;\n };\n\n var edgeQueue = new binary_heap(compareWeight);\n getEdgesByNodeId(currNode.id, edges).forEach(function (edge) {\n edgeQueue.insert(edge);\n });\n\n while (!edgeQueue.isEmpty()) {\n // 选取与已加入的结点之间边权最小的结点\n var currEdge = edgeQueue.delMin();\n var source = currEdge.source;\n var target = currEdge.target;\n if (visited.has(source) && visited.has(target)) continue;\n selectedEdges.push(currEdge);\n\n if (!visited.has(source)) {\n visited.add(source);\n getEdgesByNodeId(source, edges).forEach(function (edge) {\n edgeQueue.insert(edge);\n });\n }\n\n if (!visited.has(target)) {\n visited.add(target);\n getEdgesByNodeId(target, edges).forEach(function (edge) {\n edgeQueue.insert(edge);\n });\n }\n }\n\n return selectedEdges;\n};\n/**\n * Kruskal algorithm,复杂度 O(E*logE), E: 边的数量\n * refer: https://en.wikipedia.org/wiki/Kruskal%27s_algorithm\n * @param graph\n * @param weight 指定用于作为边权重的属性,若不指定,则认为所有边权重一致\n * @return IEdge[] 返回构成MST的边的数组\n */\n\n\nvar mts_kruskalMST = function kruskalMST(graphData, weight) {\n var selectedEdges = [];\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n\n if (nodes.length === 0) {\n return selectedEdges;\n } // 若指定weight,则将所有的边按权值从小到大排序\n\n\n var weightEdges = edges.map(function (edge) {\n return edge;\n });\n\n if (weight) {\n weightEdges.sort(function (a, b) {\n return a.weight - b.weight;\n });\n }\n\n var disjointSet = new union_find(nodes.map(function (n) {\n return n.id;\n })); // 从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边\n // 直到遍历完所有点或边\n\n while (weightEdges.length > 0) {\n var curEdge = weightEdges.shift();\n var source = curEdge.source;\n var target = curEdge.target;\n\n if (!disjointSet.connected(source, target)) {\n selectedEdges.push(curEdge);\n disjointSet.union(source, target);\n }\n }\n\n return selectedEdges;\n};\n/**\n * 最小生成树\n * refer: https://en.wikipedia.org/wiki/Kruskal%27s_algorithm\n * @param graph\n * @param weight 指定用于作为边权重的属性,若不指定,则认为所有边权重一致\n * @param algo 'prim' | 'kruskal' 算法类型\n * @return EdgeConfig[] 返回构成MST的边的数组\n */\n\n\nvar minimumSpanningTree = function minimumSpanningTree(graphData, weight, algo) {\n var algos = {\n prim: mts_primMST,\n kruskal: mts_kruskalMST\n };\n if (!algo) return mts_kruskalMST(graphData, weight);\n return algos[algo](graphData, weight);\n};\n\n/* harmony default export */ var mts = (minimumSpanningTree);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/pageRank.js\n\n\n/**\n * PageRank https://en.wikipedia.org/wiki/PageRank\n * refer: https://github.com/anvaka/ngraph.pagerank\n * @param graph\n * @param epsilon 判断是否收敛的精度值,默认 0.000001\n * @param linkProb 阻尼系数(dumping factor),指任意时刻,用户访问到某节点后继续访问该节点链接的下一个节点的概率,经验值 0.85\n */\n\nvar pageRank_pageRank = function pageRank(graphData, epsilon, linkProb) {\n if (typeof epsilon !== 'number') epsilon = 0.000001;\n if (typeof linkProb !== 'number') linkProb = 0.85;\n var distance = 1;\n var leakedRank = 0;\n var maxIterations = 1000;\n var _a = graphData.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = graphData.edges,\n edges = _b === void 0 ? [] : _b;\n var nodesCount = nodes.length;\n var currentRank;\n var curRanks = {};\n var prevRanks = {}; // Initialize pageranks 初始化\n\n for (var j = 0; j < nodesCount; ++j) {\n var node = nodes[j];\n var nodeId = node.id;\n curRanks[nodeId] = 1 / nodesCount;\n prevRanks[nodeId] = 1 / nodesCount;\n }\n\n var nodeDegree = es_degree(graphData);\n\n while (maxIterations > 0 && distance > epsilon) {\n leakedRank = 0;\n\n for (var j = 0; j < nodesCount; ++j) {\n var node = nodes[j];\n var nodeId = node.id;\n currentRank = 0;\n\n if (nodeDegree[node.id].inDegree === 0) {\n curRanks[nodeId] = 0;\n } else {\n var neighbors = getNeighbors(nodeId, edges, 'source');\n\n for (var i = 0; i < neighbors.length; ++i) {\n var neighbor = neighbors[i];\n var outDegree = nodeDegree[neighbor].outDegree;\n if (outDegree > 0) currentRank += prevRanks[neighbor] / outDegree;\n }\n\n curRanks[nodeId] = linkProb * currentRank;\n leakedRank += curRanks[nodeId];\n }\n }\n\n leakedRank = (1 - leakedRank) / nodesCount;\n distance = 0;\n\n for (var j = 0; j < nodesCount; ++j) {\n var node = nodes[j];\n var nodeId = node.id;\n currentRank = curRanks[nodeId] + leakedRank;\n distance += Math.abs(currentRank - prevRanks[nodeId]);\n prevRanks[nodeId] = currentRank;\n }\n\n maxIterations -= 1;\n }\n\n return prevRanks;\n};\n\n/* harmony default export */ var es_pageRank = (pageRank_pageRank);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/gSpan/struct.js\nvar VACANT_EDGE_ID = -1;\nvar VACANT_NODE_ID = -1;\nvar VACANT_EDGE_LABEL = \"-1\";\nvar VACANT_NODE_LABEL = \"-1\";\nvar VACANT_GRAPH_ID = -1;\nvar AUTO_EDGE_ID = \"-1\";\n\nvar struct_Edge =\n/** @class */\nfunction () {\n function Edge(id, from, to, label) {\n if (id === void 0) {\n id = VACANT_EDGE_ID;\n }\n\n if (from === void 0) {\n from = VACANT_NODE_ID;\n }\n\n if (to === void 0) {\n to = VACANT_NODE_ID;\n }\n\n if (label === void 0) {\n label = VACANT_EDGE_LABEL;\n }\n\n this.id = id;\n this.from = from;\n this.to = to;\n this.label = label;\n }\n\n return Edge;\n}();\n\n\n\nvar struct_Node =\n/** @class */\nfunction () {\n function Node(id, label) {\n if (id === void 0) {\n id = VACANT_NODE_ID;\n }\n\n if (label === void 0) {\n label = VACANT_NODE_LABEL;\n }\n\n this.id = id;\n this.label = label;\n this.edges = [];\n this.edgeMap = {};\n }\n\n Node.prototype.addEdge = function (edge) {\n this.edges.push(edge);\n this.edgeMap[edge.id] = edge;\n };\n\n return Node;\n}();\n\n\n\nvar struct_Graph =\n/** @class */\nfunction () {\n function Graph(id, edgeIdAutoIncrease, directed) {\n if (id === void 0) {\n id = VACANT_NODE_ID;\n }\n\n if (edgeIdAutoIncrease === void 0) {\n edgeIdAutoIncrease = true;\n }\n\n if (directed === void 0) {\n directed = false;\n }\n\n this.id = id;\n this.edgeIdAutoIncrease = edgeIdAutoIncrease;\n this.edges = [];\n this.nodes = [];\n this.nodeMap = {};\n this.edgeMap = {};\n this.nodeLabelMap = {};\n this.edgeLabelMap = {};\n this.counter = 0;\n this.directed = directed;\n }\n\n Graph.prototype.getNodeNum = function () {\n return this.nodes.length;\n };\n\n Graph.prototype.addNode = function (id, label) {\n if (this.nodeMap[id]) return;\n var node = new struct_Node(id, label);\n this.nodes.push(node);\n this.nodeMap[id] = node;\n if (!this.nodeLabelMap[label]) this.nodeLabelMap[label] = [];\n this.nodeLabelMap[label].push(id);\n };\n\n Graph.prototype.addEdge = function (id, from, to, label) {\n if (this.edgeIdAutoIncrease || id === undefined) id = this.counter++;\n if (this.nodeMap[from] && this.nodeMap[to] && this.nodeMap[to].edgeMap[id]) return;\n var edge = new struct_Edge(id, from, to, label);\n this.edges.push(edge);\n this.edgeMap[id] = edge;\n this.nodeMap[from].addEdge(edge);\n if (!this.edgeLabelMap[label]) this.edgeLabelMap[label] = [];\n this.edgeLabelMap[label].push(edge);\n\n if (!this.directed) {\n var rEdge = new struct_Edge(id, to, from, label);\n this.nodeMap[to].addEdge(rEdge);\n this.edgeLabelMap[label].push(rEdge);\n }\n };\n\n return Graph;\n}();\n\n\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/gSpan/gSpan.js\n\n\n\nvar gSpan_DFSedge =\n/** @class */\nfunction () {\n function DFSedge(fromNode, toNode, fromNodeLabel, edgeLabel, toNodeLabel) {\n this.fromNode = fromNode;\n this.toNode = toNode;\n this.nodeEdgeNodeLabel = {\n nodeLabel1: fromNodeLabel || VACANT_NODE_LABEL,\n edgeLabel: edgeLabel || VACANT_EDGE_LABEL,\n nodeLabel2: toNodeLabel || VACANT_NODE_LABEL\n };\n }\n\n DFSedge.prototype.equalTo = function (other) {\n return this.fromNode === other.formNode && this.toNode === other.toNode && this.nodeEdgeNodeLabel === other.nodeEdgeNodeLabel;\n };\n\n DFSedge.prototype.notEqualTo = function (other) {\n return !this.equalTo(other);\n };\n\n return DFSedge;\n}(); // DFScode 是 DESedge 的数组\n\n\nvar gSpan_DFScode =\n/** @class */\nfunction () {\n function DFScode() {\n this.rmpath = [];\n this.dfsEdgeList = [];\n }\n\n DFScode.prototype.equalTo = function (other) {\n var aLength = this.dfsEdgeList.length;\n var bLength = other.length;\n if (aLength !== bLength) return false;\n\n for (var i = 0; i < aLength; i++) {\n if (this.dfsEdgeList[i] !== other[i]) return false;\n }\n\n return true;\n };\n\n DFScode.prototype.notEqualTo = function (other) {\n return !this.equalTo(other);\n };\n /** 增加一条 edge 到 DFScode */\n\n\n DFScode.prototype.pushBack = function (fromNode, toNode, fromNodeLabel, edgeLabel, toNodeLabel) {\n this.dfsEdgeList.push(new gSpan_DFSedge(fromNode, toNode, fromNodeLabel, edgeLabel, toNodeLabel));\n return this.dfsEdgeList;\n };\n /** 根据 dfs 构建图 */\n\n\n DFScode.prototype.toGraph = function (graphId, directed) {\n if (graphId === void 0) {\n graphId = VACANT_GRAPH_ID;\n }\n\n if (directed === void 0) {\n directed = false;\n }\n\n var graph = new struct_Graph(graphId, true, directed);\n this.dfsEdgeList.forEach(function (dfsEdge) {\n var fromNodeId = dfsEdge.fromNode;\n var toNodeId = dfsEdge.toNode;\n var _a = dfsEdge.nodeEdgeNodeLabel,\n nodeLabel1 = _a.nodeLabel1,\n edgeLabel = _a.edgeLabel,\n nodeLabel2 = _a.nodeLabel2;\n if (nodeLabel1 !== VACANT_NODE_LABEL) graph.addNode(fromNodeId, nodeLabel1);\n if (nodeLabel2 !== VACANT_NODE_LABEL) graph.addNode(toNodeId, nodeLabel2);\n if (nodeLabel1 !== VACANT_NODE_LABEL && nodeLabel2 !== nodeLabel1) graph.addEdge(undefined, fromNodeId, toNodeId, edgeLabel);\n });\n return graph;\n }; // 建立 rightmost path\n\n\n DFScode.prototype.buildRmpath = function () {\n this.rmpath = [];\n var oldFrom = undefined;\n var selfLength = this.dfsEdgeList.length;\n\n for (var i = selfLength - 1; i >= 0; i--) {\n var dfsEdge = this.dfsEdgeList[i];\n var fromNodeIdx = dfsEdge.fromNode;\n var toNodeIdx = dfsEdge.toNode;\n\n if (fromNodeIdx < toNodeIdx && (oldFrom === undefined || toNodeIdx === oldFrom)) {\n this.rmpath.push(i);\n oldFrom = fromNodeIdx;\n }\n }\n\n return this.rmpath;\n };\n\n DFScode.prototype.getNodeNum = function () {\n var nodeMap = {};\n this.dfsEdgeList.forEach(function (dfsEdge) {\n if (!nodeMap[dfsEdge.fromNode]) nodeMap[dfsEdge.fromNode] = true;\n if (!nodeMap[dfsEdge.toNode]) nodeMap[dfsEdge.toNode] = true;\n });\n return Object.keys(nodeMap).length;\n };\n\n return DFScode;\n}();\n\nvar History =\n/** @class */\nfunction () {\n function History(pdfs) {\n this.his = {};\n this.nodesUsed = {};\n this.edgesUsed = {};\n this.edges = [];\n if (!pdfs) return;\n\n while (pdfs) {\n var e = pdfs.edge;\n this.edges.push(e);\n this.nodesUsed[e.from] = 1;\n this.nodesUsed[e.to] = 1;\n this.edgesUsed[e.id] = 1;\n pdfs = pdfs.preNode;\n } // 倒序\n\n\n this.edges = this.edges.reverse();\n }\n\n History.prototype.hasNode = function (node) {\n return this.nodesUsed[node.id] === 1;\n };\n\n History.prototype.hasEdge = function (edge) {\n return this.edgesUsed[edge.id] === 1;\n };\n\n return History;\n}();\n\nvar gSpan_GSpan =\n/** @class */\nfunction () {\n function GSpan(_a) {\n var graphs = _a.graphs,\n _b = _a.minSupport,\n minSupport = _b === void 0 ? 2 : _b,\n _c = _a.minNodeNum,\n minNodeNum = _c === void 0 ? 1 : _c,\n _d = _a.maxNodeNum,\n maxNodeNum = _d === void 0 ? 4 : _d,\n _e = _a.top,\n top = _e === void 0 ? 10 : _e,\n _f = _a.directed,\n directed = _f === void 0 ? false : _f,\n _g = _a.verbose,\n verbose = _g === void 0 ? false : _g; // -------- 第零步,初始化-------\n\n this.graphs = graphs;\n this.dfsCode = new gSpan_DFScode();\n this.support = 0;\n this.frequentSize1Subgraphs = [];\n this.frequentSubgraphs = [];\n this.minSupport = minSupport;\n this.top = top;\n this.directed = directed;\n this.counter = 0; // TODO? timestamp = {}\n\n this.maxNodeNum = maxNodeNum;\n this.minNodeNum = minNodeNum;\n this.verbose = verbose;\n if (this.maxNodeNum < this.minNodeNum) this.maxNodeNum = this.minNodeNum;\n this.reportDF = []; // matrix\n } // Line 352\n\n\n GSpan.prototype.findForwardRootEdges = function (graph, fromNode) {\n var _this = this;\n\n var result = [];\n var nodeMap = graph.nodeMap;\n fromNode.edges.forEach(function (edge) {\n if (_this.directed || fromNode.label <= nodeMap[edge.to].label) result.push(edge);\n });\n return result;\n };\n\n GSpan.prototype.findBackwardEdge = function (graph, edge1, edge2, history) {\n if (!this.directed && edge1 === edge2) return null;\n var nodeMap = graph.nodeMap;\n var edge2To = nodeMap[edge2.to];\n var edge2ToEdges = edge2To.edges;\n var edgeLength = edge2ToEdges.length;\n\n for (var i = 0; i < edgeLength; i++) {\n var edge = edge2ToEdges[i];\n if (history.hasEdge(edge) || edge.to !== edge1.from) continue;\n\n if (!this.directed) {\n if (edge1.label < edge.label || edge1.label === edge.label && nodeMap[edge1.to].label <= nodeMap[edge2.to].label) {\n return edge;\n }\n } else {\n if (nodeMap[edge1.from].label < nodeMap[edge2.to].label || nodeMap[edge1.from].label === nodeMap[edge2.to].label && edge1.label <= edge.label) {\n return edge;\n }\n }\n }\n\n return null;\n };\n\n GSpan.prototype.findForwardPureEdges = function (graph, rightmostEdge, minNodeLabel, history) {\n var result = [];\n var rightmostEdgeToId = rightmostEdge.to;\n var edges = graph.nodeMap[rightmostEdgeToId].edges;\n var edgeLength = edges.length;\n\n for (var i = 0; i < edgeLength; i++) {\n var edge = edges[i];\n var toNode = graph.nodeMap[edge.to];\n\n if (minNodeLabel <= toNode.label && !history.hasNode(toNode)) {\n result.push(edge);\n }\n }\n\n return result;\n };\n\n GSpan.prototype.findForwardRmpathEdges = function (graph, rightmostEdge, minNodeLabel, history) {\n var result = [];\n var nodeMap = graph.nodeMap;\n var toNodeLabel = nodeMap[rightmostEdge.to].label;\n var fromNode = nodeMap[rightmostEdge.from];\n var edges = fromNode.edges;\n var edgeLength = edges.length;\n\n for (var i = 0; i < edgeLength; i++) {\n var edge = edges[i];\n var newToNodeLabel = nodeMap[edge.to].label;\n\n if (rightmostEdge.to === edge.to || minNodeLabel > newToNodeLabel || history.hasNode(nodeMap[edge.to])) {\n continue;\n }\n\n if (rightmostEdge.label < edge.label || rightmostEdge.label === edge.label && toNodeLabel <= newToNodeLabel) {\n result.push(edge);\n }\n }\n\n return result;\n };\n\n GSpan.prototype.getSupport = function (projected) {\n var graphMap = {};\n projected.forEach(function (pro) {\n if (!graphMap[pro.graphId]) graphMap[pro.graphId] = true;\n });\n return Object.keys(graphMap).length;\n };\n\n GSpan.prototype.findMinLabel = function (obj) {\n var minLabel = undefined;\n Object.keys(obj).forEach(function (nodeEdgeNodeLabel) {\n var _a = obj[nodeEdgeNodeLabel],\n nodeLabel1 = _a.nodeLabel1,\n edgeLabel = _a.edgeLabel,\n nodeLabel2 = _a.nodeLabel2;\n\n if (!minLabel) {\n minLabel = {\n nodeLabel1: nodeLabel1,\n edgeLabel: edgeLabel,\n nodeLabel2: nodeLabel2\n };\n return;\n }\n\n if (nodeLabel1 < minLabel.nodeLabel1 || nodeLabel1 === minLabel.nodeLabel1 && edgeLabel < minLabel.edgeLabel || nodeLabel1 === minLabel.nodeLabel1 && edgeLabel === minLabel.edgeLabel && nodeLabel2 < minLabel.nodeLabel2) {\n minLabel = {\n nodeLabel1: nodeLabel1,\n edgeLabel: edgeLabel,\n nodeLabel2: nodeLabel2\n };\n }\n });\n return minLabel;\n };\n\n GSpan.prototype.isMin = function () {\n var _this = this;\n\n var dfsCode = this.dfsCode;\n if (this.verbose) console.log(\"isMin checking\", dfsCode);\n if (dfsCode.dfsEdgeList.length === 1) return true;\n var directed = this.directed;\n var graph = dfsCode.toGraph(VACANT_GRAPH_ID, directed);\n var nodeMap = graph.nodeMap;\n var dfsCodeMin = new gSpan_DFScode();\n var root = {};\n graph.nodes.forEach(function (node) {\n var forwardEdges = _this.findForwardRootEdges(graph, node);\n\n forwardEdges.forEach(function (edge) {\n var otherNode = nodeMap[edge.to];\n var nodeEdgeNodeLabel = node.label + \"-\" + edge.label + \"-\" + otherNode.label;\n if (!root[nodeEdgeNodeLabel]) root[nodeEdgeNodeLabel] = {\n projected: [],\n nodeLabel1: node.label,\n edgeLabel: edge.label,\n nodeLabel2: otherNode.label\n };\n var pdfs = {\n graphId: graph.id,\n edge: edge,\n preNode: null\n };\n root[nodeEdgeNodeLabel].projected.push(pdfs);\n });\n }); // 比较 root 中每一项的 nodeEdgeNodeLabel 大小,按照 nodeLabel1、edgeLabe、nodeLabel2 的顺序比较\n\n var minLabel = this.findMinLabel(root); // line 419\n\n if (!minLabel) return;\n dfsCodeMin.dfsEdgeList.push(new gSpan_DFSedge(0, 1, minLabel.nodeLabel1, minLabel.edgeLabel, minLabel.nodeLabel2)); // line 423\n\n var projectIsMin = function projectIsMin(projected) {\n // right most path\n var rmpath = dfsCodeMin.buildRmpath();\n var minNodeLabel = dfsCodeMin.dfsEdgeList[0].nodeEdgeNodeLabel.nodeLabel1;\n var maxToC = dfsCodeMin.dfsEdgeList[rmpath[0]].toNode; // node id\n\n var backwardRoot = {};\n var flag = false,\n newTo = 0;\n var end = directed ? -1 : 0; // 遍历到 1 还是到 0\n\n var _loop_1 = function _loop_1(i) {\n if (flag) return \"break\"; // line 435\n\n projected.forEach(function (p) {\n var history = new History(p);\n\n var backwardEdge = _this.findBackwardEdge(graph, history.edges[rmpath[i]], history.edges[rmpath[0]], history);\n\n if (backwardEdge) {\n // Line 441\n if (!backwardRoot[backwardEdge.label]) {\n backwardRoot[backwardEdge.label] = {\n projected: [],\n edgeLabel: backwardEdge.label\n };\n }\n\n backwardRoot[backwardEdge.label].projected.push({\n graphId: graph.id,\n edge: backwardRoot,\n preNode: p\n });\n newTo = dfsCodeMin.dfsEdgeList[rmpath[i]].fromNode;\n flag = true;\n }\n });\n };\n\n for (var i = rmpath.length - 1; i > end; i--) {\n var state_1 = _loop_1(i);\n\n if (state_1 === \"break\") break;\n }\n\n if (flag) {\n var minBackwardEdgeLabel = _this.findMinLabel(backwardRoot);\n\n dfsCodeMin.dfsEdgeList.push(new gSpan_DFSedge(maxToC, newTo, VACANT_NODE_LABEL, minBackwardEdgeLabel.edgeLabel, VACANT_NODE_LABEL));\n var idx_1 = dfsCodeMin.dfsEdgeList.length - 1;\n if (_this.dfsCode.dfsEdgeList[idx_1] !== dfsCodeMin.dfsEdgeList[idx_1]) return false;\n return projectIsMin(backwardRoot[minBackwardEdgeLabel.edgeLabel].projected);\n }\n\n var forwardRoot = {};\n flag = false;\n var newFrom = 0;\n projected.forEach(function (p) {\n var history = new History(p);\n\n var forwardPureEdges = _this.findForwardPureEdges(graph, history.edges[rmpath[0]], minNodeLabel, history);\n\n if (forwardPureEdges.length > 0) {\n flag = true;\n newFrom = maxToC;\n forwardPureEdges.forEach(function (edge) {\n var key = edge.label + \"-\" + nodeMap[edge.to].label;\n if (!forwardRoot[key]) forwardRoot[key] = {\n projected: [],\n edgeLabel: edge.label,\n nodeLabel2: nodeMap[edge.to].label\n };\n forwardRoot[key].projected.push({\n graphId: graph.id,\n edge: edge,\n preNode: p\n });\n });\n }\n });\n var pathLength = rmpath.length;\n\n var _loop_2 = function _loop_2(i) {\n if (flag) return \"break\";\n var value = rmpath[i];\n projected.forEach(function (p) {\n var history = new History(p);\n\n var forwardRmpathEdges = _this.findForwardRmpathEdges(graph, history.edges[value], minNodeLabel, history);\n\n if (forwardRmpathEdges.length > 0) {\n flag = true;\n newFrom = dfsCodeMin.dfsEdgeList[value].fromNode;\n forwardRmpathEdges.forEach(function (edge) {\n var key = edge.label + \"-\" + nodeMap[edge.to].label;\n if (!forwardRoot[key]) forwardRoot[key] = {\n projected: [],\n edgeLabel: edge.label,\n nodeLabel2: nodeMap[edge.to].label\n };\n forwardRoot[key].projected.push({\n graphId: graph.id,\n edge: edge,\n preNode: p\n });\n });\n }\n });\n };\n\n for (var i = 0; i < pathLength; i++) {\n var state_2 = _loop_2(i);\n\n if (state_2 === \"break\") break;\n }\n\n if (!flag) return true;\n\n var forwardMinEdgeNodeLabel = _this.findMinLabel(forwardRoot);\n\n dfsCodeMin.dfsEdgeList.push(new gSpan_DFSedge(newFrom, maxToC + 1, VACANT_NODE_LABEL, forwardMinEdgeNodeLabel.edgeLabel, forwardMinEdgeNodeLabel.nodeLabel2));\n var idx = dfsCodeMin.dfsEdgeList.length - 1;\n if (dfsCode.dfsEdgeList[idx] !== dfsCodeMin.dfsEdgeList[idx]) return false;\n return projectIsMin(forwardRoot[forwardMinEdgeNodeLabel.edgeLabel + \"-\" + forwardMinEdgeNodeLabel.nodeLabel2].projected);\n };\n\n var key = minLabel.nodeLabel1 + \"-\" + minLabel.edgeLabel + \"-\" + minLabel.nodeLabel2;\n return projectIsMin(root[key].projected);\n };\n\n GSpan.prototype.report = function () {\n if (this.dfsCode.getNodeNum() < this.minNodeNum) return;\n this.counter++;\n var graph = this.dfsCode.toGraph(this.counter, this.directed);\n this.frequentSubgraphs.push(Object(esm[\"clone\"])(graph));\n };\n\n GSpan.prototype.subGraphMining = function (projected) {\n var _this = this;\n\n var support = this.getSupport(projected);\n if (support < this.minSupport) return;\n if (!this.isMin()) return;\n this.report();\n var nodeNum = this.dfsCode.getNodeNum();\n var rmpath = this.dfsCode.buildRmpath();\n var maxToC = this.dfsCode.dfsEdgeList[rmpath[0]].toNode;\n var minNodeLabel = this.dfsCode.dfsEdgeList[0].nodeEdgeNodeLabel.nodeLabel1;\n var forwardRoot = {};\n var backwardRoot = {};\n projected.forEach(function (p) {\n var graph = _this.graphs[p.graphId];\n var nodeMap = graph.nodeMap;\n var history = new History(p); // backward Line 526\n\n for (var i = rmpath.length - 1; i >= 0; i--) {\n var backwardEdge = _this.findBackwardEdge(graph, history.edges[rmpath[i]], history.edges[rmpath[0]], history);\n\n if (backwardEdge) {\n var key = _this.dfsCode.dfsEdgeList[rmpath[i]].fromNode + \"-\" + backwardEdge.label;\n if (!backwardRoot[key]) backwardRoot[key] = {\n projected: [],\n toNodeId: _this.dfsCode.dfsEdgeList[rmpath[i]].fromNode,\n edgeLabel: backwardEdge.label\n };\n backwardRoot[key].projected.push({\n graphId: p.graphId,\n edge: backwardEdge,\n preNode: p\n });\n }\n } // pure forward\n\n\n if (nodeNum >= _this.maxNodeNum) return;\n\n var forwardPureEdges = _this.findForwardPureEdges(graph, history.edges[rmpath[0]], minNodeLabel, history);\n\n forwardPureEdges.forEach(function (edge) {\n var key = maxToC + \"-\" + edge.label + \"-\" + nodeMap[edge.to].label;\n if (!forwardRoot[key]) forwardRoot[key] = {\n projected: [],\n fromNodeId: maxToC,\n edgeLabel: edge.label,\n nodeLabel2: nodeMap[edge.to].label\n };\n forwardRoot[key].projected.push({\n graphId: p.graphId,\n edge: edge,\n preNode: p\n });\n });\n\n var _loop_3 = function _loop_3(i) {\n var forwardRmpathEdges = _this.findForwardRmpathEdges(graph, history.edges[rmpath[i]], minNodeLabel, history);\n\n forwardRmpathEdges.forEach(function (edge) {\n var key = _this.dfsCode.dfsEdgeList[rmpath[i]].fromNode + \"-\" + edge.label + \"-\" + nodeMap[edge.to].label;\n if (!forwardRoot[key]) forwardRoot[key] = {\n projected: [],\n fromNodeId: _this.dfsCode.dfsEdgeList[rmpath[i]].fromNode,\n edgeLabel: edge.label,\n nodeLabel2: nodeMap[edge.to].label\n };\n forwardRoot[key].projected.push({\n graphId: p.graphId,\n edge: edge,\n preNode: p\n });\n });\n }; // rmpath forward\n\n\n for (var i = 0; i < rmpath.length; i++) {\n _loop_3(i);\n }\n }); // backward\n\n Object.keys(backwardRoot).forEach(function (key) {\n var _a = backwardRoot[key],\n toNodeId = _a.toNodeId,\n edgeLabel = _a.edgeLabel;\n\n _this.dfsCode.dfsEdgeList.push(new gSpan_DFSedge(maxToC, toNodeId, \"-1\", edgeLabel, \"-1\"));\n\n _this.subGraphMining(backwardRoot[key].projected);\n\n _this.dfsCode.dfsEdgeList.pop();\n }); // forward\n\n Object.keys(forwardRoot).forEach(function (key) {\n var _a = forwardRoot[key],\n fromNodeId = _a.fromNodeId,\n edgeLabel = _a.edgeLabel,\n nodeLabel2 = _a.nodeLabel2;\n\n _this.dfsCode.dfsEdgeList.push(new gSpan_DFSedge(fromNodeId, maxToC + 1, VACANT_NODE_LABEL, edgeLabel, nodeLabel2));\n\n _this.subGraphMining(forwardRoot[key].projected);\n\n _this.dfsCode.dfsEdgeList.pop();\n });\n };\n\n GSpan.prototype.generate1EdgeFrequentSubGraphs = function () {\n var graphs = this.graphs;\n var directed = this.directed;\n var minSupport = this.minSupport;\n var frequentSize1Subgraphs = this.frequentSize1Subgraphs;\n var nodeLabelCounter = {},\n nodeEdgeNodeCounter = {}; // 保存各个图和各自节点的关系 map,key 格式为 graphKey-node类型\n\n var nodeLableCounted = {}; // 保存各个图和各自边的关系 map,key 格式为 graphKey-fromNode类型-edge类型-toNode类型\n\n var nodeEdgeNodeLabelCounted = {};\n Object.keys(graphs).forEach(function (key) {\n // Line 271\n var graph = graphs[key];\n var nodeMap = graph.nodeMap; // 遍历节点,记录对应图 与 每个节点的 label 到 nodeLableCounted\n\n graph.nodes.forEach(function (node, i) {\n // Line 272\n var nodeLabel = node.label;\n var graphNodeKey = key + \"-\" + nodeLabel;\n\n if (!nodeLableCounted[graphNodeKey]) {\n var counter = nodeLabelCounter[nodeLabel] || 0;\n counter++;\n nodeLabelCounter[nodeLabel] = counter;\n }\n\n nodeLableCounted[graphNodeKey] = {\n graphKey: key,\n label: nodeLabel\n }; // 遍历该节点的所有边,记录各个图和各自边的关系到 nodeEdgeNodeLabelCounted. Line 276\n\n node.edges.forEach(function (edge) {\n var nodeLabel1 = nodeLabel;\n var nodeLabel2 = nodeMap[edge.to].label;\n\n if (!directed && nodeLabel1 > nodeLabel2) {\n var tmp = nodeLabel2;\n nodeLabel2 = nodeLabel1;\n nodeLabel1 = tmp;\n }\n\n var edgeLabel = edge.label;\n var graphNodeEdgeNodeKey = key + \"-\" + nodeLabel1 + \"-\" + edgeLabel + \"-\" + nodeLabel2;\n var nodeEdgeNodeKey = nodeLabel1 + \"-\" + edgeLabel + \"-\" + nodeLabel2;\n\n if (!nodeEdgeNodeCounter[nodeEdgeNodeKey]) {\n var counter = nodeEdgeNodeCounter[nodeEdgeNodeKey] || 0;\n counter++;\n nodeEdgeNodeCounter[nodeEdgeNodeKey] = counter; // Line281\n }\n\n nodeEdgeNodeLabelCounted[graphNodeEdgeNodeKey] = {\n graphId: key,\n nodeLabel1: nodeLabel1,\n edgeLabel: edgeLabel,\n nodeLabel2: nodeLabel2\n };\n });\n });\n }); // 计算频繁的节点\n\n Object.keys(nodeLabelCounter).forEach(function (label) {\n var count = nodeLabelCounter[label];\n if (count < minSupport) return;\n var g = {\n nodes: [],\n edges: []\n };\n g.nodes.push({\n id: \"0\",\n label: label\n });\n frequentSize1Subgraphs.push(g); // if (minNodeNum <= 1) reportSize1 TODO\n });\n return frequentSize1Subgraphs;\n };\n\n GSpan.prototype.run = function () {\n var _this = this; // -------- 第一步, _generate_1edge_frequent_subgraphs:频繁的单个节点-------\n\n\n this.frequentSize1Subgraphs = this.generate1EdgeFrequentSubGraphs();\n if (this.maxNodeNum < 2) return;\n var graphs = this.graphs;\n var directed = this.directed; // PDFS 数组的 map Line 304\n\n var root = {};\n Object.keys(graphs).forEach(function (graphId) {\n var graph = graphs[graphId];\n var nodeMap = graph.nodeMap; // Line 306\n\n graph.nodes.forEach(function (node) {\n var forwardRootEdges = _this.findForwardRootEdges(graph, node); // Line 308\n\n\n forwardRootEdges.forEach(function (edge) {\n var toNode = nodeMap[edge.to];\n var nodeEdgeNodeLabel = node.label + \"-\" + edge.label + \"-\" + toNode.label;\n if (!root[nodeEdgeNodeLabel]) root[nodeEdgeNodeLabel] = {\n projected: [],\n nodeLabel1: node.label,\n edgeLabel: edge.label,\n nodeLabel2: toNode.label\n };\n var pdfs = {\n graphId: graphId,\n edge: edge,\n preNode: null\n };\n root[nodeEdgeNodeLabel].projected.push(pdfs);\n });\n });\n }); // Line 313\n\n Object.keys(root).forEach(function (nodeEdgeNodeLabel) {\n var _a = root[nodeEdgeNodeLabel],\n projected = _a.projected,\n nodeLabel1 = _a.nodeLabel1,\n edgeLabel = _a.edgeLabel,\n nodeLabel2 = _a.nodeLabel2;\n\n _this.dfsCode.dfsEdgeList.push(new gSpan_DFSedge(0, 1, nodeLabel1, edgeLabel, nodeLabel2));\n\n _this.subGraphMining(projected);\n\n _this.dfsCode.dfsEdgeList.pop();\n });\n };\n\n return GSpan;\n}();\n\nvar gSpan_formatGraphs = function formatGraphs(graphs, directed, nodeLabelProp, edgeLabelProp) {\n var result = {};\n Object.keys(graphs).forEach(function (key, i) {\n var graph = graphs[key];\n var fGraph = new struct_Graph(i, true, directed);\n var nodeIdxMap = {};\n graph.nodes.forEach(function (node, j) {\n fGraph.addNode(j, node[nodeLabelProp]);\n nodeIdxMap[node.id] = j;\n });\n graph.edges.forEach(function (edge, k) {\n var sourceIdx = nodeIdxMap[edge.source];\n var targetIdx = nodeIdxMap[edge.target];\n fGraph.addEdge(-1, sourceIdx, targetIdx, edge[edgeLabelProp]);\n });\n if (fGraph && fGraph.getNodeNum()) result[fGraph.id] = fGraph;\n });\n return result;\n};\n\nvar toGraphDatas = function toGraphDatas(graphs, nodeLabelProp, edgeLabelProp) {\n var result = [];\n graphs.forEach(function (graph) {\n var graphData = {\n nodes: [],\n edges: []\n };\n graph.nodes.forEach(function (node) {\n var _a;\n\n graphData.nodes.push((_a = {\n id: \"\" + node.id\n }, _a[nodeLabelProp] = node.label, _a));\n });\n graph.edges.forEach(function (edge) {\n var _a;\n\n graphData.edges.push((_a = {\n source: \"\" + edge.from,\n target: \"\" + edge.to\n }, _a[edgeLabelProp] = edge.label, _a));\n });\n result.push(graphData);\n });\n return result;\n};\n\nvar DEFAULT_LABEL_NAME = \"cluster\";\n/**\n * gSpan 频繁子图计算算法(frequent graph mining)\n * @param params 参数\n */\n\nvar gSpan = function gSpan(params) {\n // ------- 将图数据 GraphData 的 map 转换为格式 -------\n var graphs = params.graphs,\n _a = params.directed,\n directed = _a === void 0 ? false : _a,\n _b = params.nodeLabelProp,\n nodeLabelProp = _b === void 0 ? DEFAULT_LABEL_NAME : _b,\n _c = params.edgeLabelProp,\n edgeLabelProp = _c === void 0 ? DEFAULT_LABEL_NAME : _c;\n var formattedGraphs = gSpan_formatGraphs(graphs, directed, nodeLabelProp, edgeLabelProp);\n var minSupport = params.minSupport,\n maxNodeNum = params.maxNodeNum,\n minNodeNum = params.minNodeNum,\n verbose = params.verbose,\n top = params.top; // ------- 初始化与执行算法 -------\n\n var algoParams = {\n graphs: formattedGraphs,\n minSupport: minSupport,\n maxNodeNum: maxNodeNum,\n minNodeNum: minNodeNum,\n top: top,\n verbose: verbose,\n directed: directed\n };\n var calculator = new gSpan_GSpan(algoParams);\n calculator.run();\n var result = toGraphDatas(calculator.frequentSubgraphs, nodeLabelProp, edgeLabelProp);\n return result;\n};\n\n/* harmony default export */ var gSpan_gSpan = (gSpan);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/gaddi.js\n\n\n\n\n\n/**\n * 为 graphData 中每个节点生成邻居单元数组\n * @param graphData\n * @param spm\n * @param nodeLabelProp\n * @param k k-近邻\n */\n\nvar findKNeighborUnits = function findKNeighborUnits(graphData, spm, nodeLabelProp, k) {\n if (nodeLabelProp === void 0) {\n nodeLabelProp = 'cluster';\n }\n\n if (k === void 0) {\n k = 2;\n }\n\n var units = [];\n var nodes = graphData.nodes;\n spm.forEach(function (row, i) {\n units.push(findKNeighborUnit(nodes, row, i, nodeLabelProp, k));\n });\n return units;\n};\n\nvar findKNeighborUnit = function findKNeighborUnit(nodes, row, i, nodeLabelProp, k) {\n var unitNodeIdxs = [i];\n var neighbors = [];\n var labelCountMap = {};\n row.forEach(function (v, j) {\n if (v <= k && i !== j) {\n unitNodeIdxs.push(j);\n neighbors.push(nodes[j]);\n var label = nodes[j][nodeLabelProp];\n if (!labelCountMap[label]) labelCountMap[label] = {\n count: 1,\n dists: [v]\n };else {\n labelCountMap[label].count++;\n labelCountMap[label].dists.push(v);\n }\n }\n }); // 将 labelCountMap 中的 dists 按照从小到大排序,方便后面使用\n\n Object.keys(labelCountMap).forEach(function (label) {\n labelCountMap[label].dists = labelCountMap[label].dists.sort(function (a, b) {\n return a - b;\n });\n });\n return {\n nodeIdx: i,\n nodeId: nodes[i].id,\n nodeIdxs: unitNodeIdxs,\n neighbors: neighbors,\n neighborNum: unitNodeIdxs.length - 1,\n nodeLabelCountMap: labelCountMap\n };\n};\n/**\n * 随机寻找点对,满足距离小于 k\n * @param k 参数 k,表示 k-近邻\n * @param nodeNum 参数 length\n * @param maxNodePairNum 寻找点对的数量不超过 maxNodePairNum\n * @param spm 最短路径矩阵\n */\n\n\nvar findNodePairsRandomly = function findNodePairsRandomly(k, nodeNum, maxNodePairNum, kNeighborUnits, spm) {\n // 每个节点需要随机找出的点对数\n var nodePairNumEachNode = Math.ceil(maxNodePairNum / nodeNum);\n var nodePairMap = {};\n var foundNodePairCount = 0; // 遍历节点,为每个节点随机找出 nodePairNumEachNode 个点对,满足距离小于 k。找到的点对数量超过 maxNodePairNum 或所有节点遍历结束时终止\n\n kNeighborUnits.forEach(function (unit, i) {\n // 若未达到 nodePairNumEachNode,或循环次数小于最大循环次数(2 * nodeNum),继续循环\n var nodePairForICount = 0;\n var outerLoopCount = 0;\n var neighbors = unit.nodeIdxs; // the first one is the center node\n\n var neighborNum = unit.neighborNum - 1;\n\n while (nodePairForICount < nodePairNumEachNode) {\n // 另一端节点在节点数组中的的 index\n var oidx = neighbors[1 + Math.floor(Math.random() * neighborNum)];\n var innerLoopCount = 0; // 若随机得到的另一端 idx 不符合条件,则继续 random。条件是不是同一个节点、这个点对没有被记录过、距离小于 k\n\n while (nodePairMap[i + \"-\" + oidx] || nodePairMap[oidx + \"-\" + i]) {\n oidx = Math.floor(Math.random() * nodeNum);\n innerLoopCount++;\n if (innerLoopCount > 2 * nodeNum) break; // 循环次数大于最大循环次数(2 * nodeNum)跳出循环,避免死循环\n }\n\n if (innerLoopCount < 2 * nodeNum) {\n // 未达到最大循环次数,说明找到了合适的另一端\n nodePairMap[i + \"-\" + oidx] = {\n start: i,\n end: oidx,\n distance: spm[i][oidx]\n };\n nodePairForICount++;\n foundNodePairCount++; // 如果当前找到的点对数量达到了上限,返回结果\n\n if (foundNodePairCount >= maxNodePairNum) return nodePairMap;\n }\n\n outerLoopCount++;\n if (outerLoopCount > 2 * nodeNum) break; // 循环次数大于最大循环次数(2 * nodeNum)跳出循环,避免死循环\n } // 这个节点没有找到足够 nodePairNumEachNode 的点对。更新 nodePairNumEachNode,让后续节点找更多的点对\n\n\n if (nodePairForICount < nodePairNumEachNode) {\n var gap = nodePairNumEachNode - nodePairForICount;\n nodePairNumEachNode = (nodePairNumEachNode + gap) / (nodeNum - i - 1);\n }\n });\n return nodePairMap;\n};\n/**\n * 计算所有 nodePairMap 中节点对的相交邻居诱导子图\n * @param nodePairMap 节点对 map,key 为 node1.id-node2.id,value 为 { startNodeIdx, endNodeIdx, distance }\n * @param neighborUnits 每个节点的邻居元数组\n * @param graphData 原图数据\n * @param edgeMap 边的 map,方便检索\n * @param cachedInducedGraphMap 缓存的结果,下次进入该函数将继续更新该缓存,若 key 在缓存中存在则不需要重复计算\n */\n\n\nvar getIntersectNeighborInducedGraph = function getIntersectNeighborInducedGraph(nodePairMap, neighborUnits, graphData, cachedInducedGraphMap) {\n var nodes = graphData.nodes;\n if (!cachedInducedGraphMap) cachedInducedGraphMap = {};\n Object.keys(nodePairMap).forEach(function (key) {\n var _a, _b;\n\n if (cachedInducedGraphMap && cachedInducedGraphMap[key]) return;\n cachedInducedGraphMap[key] = {\n nodes: [],\n edges: []\n };\n var pair = nodePairMap[key];\n var startUnitNodeIds = (_a = neighborUnits[pair.start]) === null || _a === void 0 ? void 0 : _a.nodeIdxs;\n var endUnitNodeIds = (_b = neighborUnits[pair.end]) === null || _b === void 0 ? void 0 : _b.nodeIdxs;\n if (!startUnitNodeIds || !endUnitNodeIds) return; // 不存在邻元,返回空图\n\n var endSet = new Set(endUnitNodeIds);\n var intersect = startUnitNodeIds.filter(function (x) {\n return endSet.has(x);\n }); // 可能会爆栈(在 1580 + 6 nodes full-connected 时出现)\n\n if (!intersect || !intersect.length) return; // 没有交集,返回空图\n\n var intersectIdMap = {};\n var intersectLength = intersect.length;\n\n for (var i = 0; i < intersectLength; i++) {\n var node = nodes[intersect[i]];\n cachedInducedGraphMap[key].nodes.push(node); // 将交集中的点加入诱导子图\n\n intersectIdMap[node.id] = true;\n } // 遍历所有边数据,如果边的两端都在交集中,将该边加入诱导子图\n\n\n graphData.edges.forEach(function (edge) {\n if (intersectIdMap[edge.source] && intersectIdMap[edge.target]) cachedInducedGraphMap[key].edges.push(edge);\n });\n });\n return cachedInducedGraphMap;\n};\n/**\n * 计算 strcutre 在 graph 上的匹配数量\n * @param graph 图数据\n * @param structure 目前支持只有两个节点一条边的最简单结构\n * @param nodeLabelProp 节点类型字段名\n * @param edgeLabelProp 边类型字段名\n */\n\n\nvar getMatchedCount = function getMatchedCount(graph, structure, nodeLabelProp, edgeLabelProp) {\n var _a, _b;\n\n var nodeMap = {};\n graph.nodes.forEach(function (node) {\n nodeMap[node.id] = node;\n });\n var count = 0;\n if (!((_a = structure === null || structure === void 0 ? void 0 : structure.edges) === null || _a === void 0 ? void 0 : _a.length) || ((_b = structure === null || structure === void 0 ? void 0 : structure.nodes) === null || _b === void 0 ? void 0 : _b.length) < 2) return 0;\n graph.edges.forEach(function (e) {\n var sourceLabel = nodeMap[e.source][nodeLabelProp];\n var targetLabel = nodeMap[e.target][nodeLabelProp];\n var strNodeLabel1 = structure === null || structure === void 0 ? void 0 : structure.nodes[0][nodeLabelProp];\n var strNodeLabel2 = structure === null || structure === void 0 ? void 0 : structure.nodes[1][nodeLabelProp];\n var strEdgeLabel = structure === null || structure === void 0 ? void 0 : structure.edges[0][edgeLabelProp];\n if (e[edgeLabelProp] !== strEdgeLabel) return;\n\n if (sourceLabel === strNodeLabel1 && targetLabel === strNodeLabel2 || sourceLabel === strNodeLabel2 && targetLabel === strNodeLabel1) {\n count++;\n }\n });\n return count;\n};\n/**\n * structures 中寻找最具有代表性的一个。这个结构是使得 matchedCountMap 的分组方式类内间距最小,类间间距最大\n * @param matchedCountMap 每个 structure 分类后的各图匹配数量,格式 { [strcture.idx]: { [interInducedGraphKey]: count } }\n * @param structureNum strcuture 个数,与 matchedCountMap.length 对应\n * @param structures\n */\n\n\nvar findRepresentStructure = function findRepresentStructure(matchedCountMap, structureNum, structures) {\n var maxOffset = Infinity,\n representClusterType = 0;\n\n var _loop_1 = function _loop_1(i) {\n // 一种分组的 map,key 是 intGraph 的 key,value 是 structures[i] 的匹配个数\n var countMapI = matchedCountMap[i]; // 按照 value 为该组排序,生成 keys 的数组:\n\n var sortedGraphKeys = Object.keys(countMapI).sort(function (a, b) {\n return countMapI[a] - countMapI[b];\n }); // 共 100 个 graphKeys,将 graphKeys 按顺序分为 groupNum 组\n\n var groupNum = 10;\n var clusters = []; // 总共有 groupNum 个项\n\n sortedGraphKeys.forEach(function (key, j) {\n if (!clusters[j % groupNum]) clusters[j % groupNum] = {\n graphs: [],\n totalCount: 0,\n aveCount: 0\n };\n clusters[j % groupNum].graphs.push(key);\n clusters[j % groupNum].totalCount += countMapI[key];\n }); // 计算 cluster 与 cluster 之间的距离 innerDist,每个 cluster 内部的距离 intraDist\n\n var aveIntraDist = 0; // 该类的类内平均值\n\n var aveCounts = []; // 类内平均匹配数量,将用于计算类间距离\n\n clusters.forEach(function (graphsInCluster) {\n // 类内均值\n var aveCount = graphsInCluster.totalCount / graphsInCluster.graphs.length;\n graphsInCluster.aveCount = aveCount;\n aveCounts.push(aveCount); // 对于每类,计算类内间距平均值\n\n var aveIntraPerCluster = 0;\n var graphsNum = graphsInCluster.length;\n graphsInCluster.graphs.forEach(function (graphKey1, j) {\n var graph1Count = countMapI[graphKey1];\n graphsInCluster.graphs.forEach(function (graphKey2, k) {\n if (j === k) return;\n aveIntraPerCluster += Math.abs(graph1Count - countMapI[graphKey2]);\n });\n });\n aveIntraPerCluster /= graphsNum * (graphsNum - 1) / 2;\n aveIntraDist += aveIntraPerCluster;\n });\n aveIntraDist /= clusters.length; // 用类内均值计算类间距\n\n var aveInterDist = 0; // 类间间距平均值\n\n aveCounts.forEach(function (aveCount1, j) {\n aveCounts.forEach(function (aveCount2, k) {\n if (j === k) return;\n aveInterDist += Math.abs(aveCount1 - aveCount2);\n });\n aveInterDist /= aveCounts.length * (aveCounts.length - 1) / 2;\n }); // 寻找 (类间间距均值-类内间距均值) 最大的一种分组方式(对应的 structure 就是最终要找的唯一 DS(G))\n\n var offset = aveInterDist - aveIntraDist;\n\n if (maxOffset < offset) {\n maxOffset = offset;\n representClusterType = i;\n }\n };\n\n for (var i = 0; i < structureNum; i++) {\n _loop_1(i);\n }\n\n return {\n structure: structures[representClusterType],\n structureCountMap: matchedCountMap[representClusterType]\n };\n};\n\nvar getNodeMaps = function getNodeMaps(nodes, nodeLabelProp) {\n var nodeMap = {},\n nodeLabelMap = {};\n nodes.forEach(function (node, i) {\n nodeMap[node.id] = {\n idx: i,\n node: node,\n degree: 0,\n inDegree: 0,\n outDegree: 0\n };\n var label = node[nodeLabelProp];\n if (!nodeLabelMap[label]) nodeLabelMap[label] = [];\n nodeLabelMap[label].push(node);\n });\n return {\n nodeMap: nodeMap,\n nodeLabelMap: nodeLabelMap\n };\n};\n\nvar gaddi_getEdgeMaps = function getEdgeMaps(edges, edgeLabelProp, nodeMap) {\n var edgeMap = {},\n edgeLabelMap = {};\n edges.forEach(function (edge, i) {\n edgeMap[\"\" + util_uniqueId] = {\n idx: i,\n edge: edge\n };\n var label = edge[edgeLabelProp];\n if (!edgeLabelMap[label]) edgeLabelMap[label] = [];\n edgeLabelMap[label].push(edge);\n var sourceNode = nodeMap[edge.source];\n\n if (sourceNode) {\n sourceNode.degree++;\n sourceNode.outDegree++;\n }\n\n var targetNode = nodeMap[edge.target];\n\n if (targetNode) {\n targetNode.degree++;\n targetNode.inDegree++;\n }\n });\n return {\n edgeMap: edgeMap,\n edgeLabelMap: edgeLabelMap\n };\n};\n/**\n * 输出最短路径的 map,key 为 sourceNode.id-targetNode.id,value 为这两个节点的最短路径长度\n * @param nodes\n * @param spm\n * @param directed\n */\n\n\nvar getSpmMap = function getSpmMap(nodes, spm, directed) {\n var length = spm.length;\n var map = {};\n spm.forEach(function (row, i) {\n var start = directed ? 0 : i + 1;\n var iId = nodes[i].id;\n\n for (var j = start; j < length; j++) {\n if (i === j) continue;\n var jId = nodes[j].id;\n var dist = row[j];\n map[iId + \"-\" + jId] = dist;\n if (!directed) map[jId + \"-\" + iId] = dist;\n }\n });\n return map;\n};\n/**\n * 计算一对节点(node1,node2)的 NDS 距离\n * @param graph 原图数据\n * @param node1\n * @param node2\n */\n\n\nvar getNDSDist = function getNDSDist(graph, node1, node2, nodeMap, spDist, kNeighborUnits, structure, nodeLabelProp, edgeLabelProp, cachedNDSMap, cachedInterInducedGraph) {\n var _a;\n\n var key = node1.id + \"-\" + node2.id;\n if (cachedNDSMap && cachedNDSMap[key]) return cachedNDSMap[key];\n var interInducedGraph = cachedInterInducedGraph ? cachedInterInducedGraph[key] : undefined; // 若没有缓存相交邻居诱导子图,计算\n\n if (!interInducedGraph) {\n var pairMap = (_a = {}, _a[key] = {\n start: nodeMap[node1.id].idx,\n end: nodeMap[node2.id].idx,\n distance: spDist\n }, _a);\n cachedInterInducedGraph = getIntersectNeighborInducedGraph(pairMap, kNeighborUnits, graph, cachedInterInducedGraph);\n interInducedGraph = cachedInterInducedGraph[key];\n }\n\n return getMatchedCount(interInducedGraph, structure, nodeLabelProp, edgeLabelProp);\n};\n/**\n * 计算 pattern 上绩点的度数并存储到 minPatternNodeLabelDegreeMap\n */\n\n\nvar stashPatternNodeLabelDegreeMap = function stashPatternNodeLabelDegreeMap(minPatternNodeLabelDegreeMap, neighborLabel, patternNodeMap, patternNodeLabelMap) {\n var _a, _b, _c;\n\n var minPatternNodeLabelDegree = (_a = minPatternNodeLabelDegreeMap[neighborLabel]) === null || _a === void 0 ? void 0 : _a.degree;\n var minPatternNodeLabelInDegree = (_b = minPatternNodeLabelDegreeMap[neighborLabel]) === null || _b === void 0 ? void 0 : _b.inDegree;\n var minPatternNodeLabelOutDegree = (_c = minPatternNodeLabelDegreeMap[neighborLabel]) === null || _c === void 0 ? void 0 : _c.outDegree;\n\n if (minPatternNodeLabelDegreeMap[neighborLabel] === undefined) {\n minPatternNodeLabelDegree = Infinity;\n minPatternNodeLabelInDegree = Infinity;\n minPatternNodeLabelOutDegree = Infinity;\n patternNodeLabelMap[neighborLabel].forEach(function (patternNodeWithLabel) {\n var patternNodeDegree = patternNodeMap[patternNodeWithLabel.id].degree;\n if (minPatternNodeLabelDegree > patternNodeDegree) minPatternNodeLabelDegree = patternNodeDegree;\n var patternNodeInDegree = patternNodeMap[patternNodeWithLabel.id].inDegree;\n if (minPatternNodeLabelInDegree > patternNodeInDegree) minPatternNodeLabelInDegree = patternNodeInDegree;\n var patternNodeOutDegree = patternNodeMap[patternNodeWithLabel.id].outDegree;\n if (minPatternNodeLabelOutDegree > patternNodeOutDegree) minPatternNodeLabelOutDegree = patternNodeOutDegree;\n });\n minPatternNodeLabelDegreeMap[neighborLabel] = {\n degree: minPatternNodeLabelDegree,\n inDegree: minPatternNodeLabelInDegree,\n outDegree: minPatternNodeLabelOutDegree\n };\n }\n\n return {\n minPatternNodeLabelDegree: minPatternNodeLabelDegree,\n minPatternNodeLabelInDegree: minPatternNodeLabelInDegree,\n minPatternNodeLabelOutDegree: minPatternNodeLabelOutDegree\n };\n};\n/**\n * GADDI 模式匹配\n * @param graphData 原图数据\n * @param pattern 搜索图(需要在原图上搜索的模式)数据\n * @param directed 是否计算有向图,默认 false\n * @param k 参数 k,表示 k-近邻\n * @param length 参数 length\n * @param nodeLabelProp 节点数据中代表节点标签(分类信息)的属性名。默认为 cluster\n * @param edgeLabelProp 边数据中代表边标签(分类信息)的属性名。默认为 cluster\n */\n\n\nvar gaddi_GADDI = function GADDI(graphData, pattern, directed, k, length, nodeLabelProp, edgeLabelProp) {\n if (directed === void 0) {\n directed = false;\n }\n\n if (nodeLabelProp === void 0) {\n nodeLabelProp = 'cluster';\n }\n\n if (edgeLabelProp === void 0) {\n edgeLabelProp = 'cluster';\n }\n\n if (!graphData || !graphData.nodes) return; // 分为三步:\n // 0. 预计算:节点/边数,邻接矩阵、最短路径矩阵\n // 1. 处理原图 graphData。再分为 1~5 小步\n // 2. 匹配\n // console.log(\"----- stage-pre: preprocessing -------\");\n // -------- 第零步,预计算:节点/边数,邻接矩阵、最短路径矩阵-------\n\n var nodeNum = graphData.nodes.length;\n if (!nodeNum) return; // console.log(\"----- stage-pre.1: calc shortest path matrix for graph -------\");\n\n var spm = es_floydWarshall(graphData, directed); // console.log(\n // \"----- stage-pre.2: calc shortest path matrix for pattern -------\"\n // );\n\n var patternSpm = es_floydWarshall(pattern, directed); // console.log(\n // \"----- stage-pre.3: calc shortest path matrix map for graph -------\"\n // );\n\n var spmMap = getSpmMap(graphData.nodes, spm, directed); // console.log(\n // \"----- stage-pre.4: calc shortest path matrix map for pattern -------\"\n // );\n\n var patternSpmMap = getSpmMap(pattern.nodes, patternSpm, directed); // console.log(\"----- stage-pre.5: establish maps -------\");\n // 节点的 map,以 id 为 id 映射,方便后续快速检索\n\n var _a = getNodeMaps(graphData.nodes, nodeLabelProp),\n nodeMap = _a.nodeMap,\n nodeLabelMap = _a.nodeLabelMap;\n\n var _b = getNodeMaps(pattern.nodes, nodeLabelProp),\n patternNodeMap = _b.nodeMap,\n patternNodeLabelMap = _b.nodeLabelMap; // 计算节点度数\n\n\n gaddi_getEdgeMaps(graphData.edges, edgeLabelProp, nodeMap);\n var patternEdgeLabelMap = gaddi_getEdgeMaps(pattern.edges, edgeLabelProp, patternNodeMap).edgeLabelMap; // 若未指定 length,自动计算 pattern 半径(最短路径最大值)\n\n var patternSpmSpread = [];\n patternSpm === null || patternSpm === void 0 ? void 0 : patternSpm.forEach(function (row) {\n patternSpmSpread = patternSpmSpread.concat(row);\n });\n if (!length) length = Math.max.apply(Math, Object(tslib_es6[\"__spreadArray\"])(Object(tslib_es6[\"__spreadArray\"])([], patternSpmSpread), [2]));\n if (!k) k = length; // console.log(\"params\", directed, length, k);\n // console.log(\"----- stage-pre.6: calc k neighbor units -------\");\n // 计算每个节点的 k 邻元集合\n\n var kNeighborUnits = findKNeighborUnits(graphData, spm, nodeLabelProp, k);\n var patternKNeighborUnits = findKNeighborUnits(pattern, patternSpm, nodeLabelProp, k); // console.log(\n // \"----- stage0: going to processing graph and find intersect neighbor induced graphs -------\"\n // );\n // console.log(\"----- stage0.1: going to select random node pairs -------\");\n // -------- 第一步,处理原图 graphData-------\n // 1.1. 随机选择最多 100 个点对,满足距离小于 Length 和 k\n // 当 graphData 少于 20 个节点,则不能找出 100 个点对,只找出不多于 n(n-1)/2 个点对\n\n var maxNodePairNum = Math.min(100, nodeNum * (nodeNum - 1) / 2);\n var nodePairsMap = findNodePairsRandomly(k, nodeNum, maxNodePairNum, patternKNeighborUnits, spm); // console.log(\n // \"----- stage0.2: going to calculate intersect neighbor induced graphs -------\"\n // );\n // 1.2. 生成上面节点对的相应相交邻居诱导子图。格式为 {'beginNodeIdx-endNodeIdx': {nodes: [], edges: []}}\n\n var intGMap = getIntersectNeighborInducedGraph(nodePairsMap, kNeighborUnits, graphData); // 1.3. 使用 gSpan 算法(frequent graph mining)计算 ISIntG 的前 10 个频率最高的子结构(3-4条边)\n\n var top = 10,\n minSupport = 1,\n minNodeNum = 1,\n maxNodeNum = 4;\n var params = {\n graphs: intGMap,\n nodeLabelProp: nodeLabelProp,\n edgeLabelProp: edgeLabelProp,\n minSupport: minSupport,\n minNodeNum: minNodeNum,\n maxNodeNum: maxNodeNum,\n directed: directed\n }; // console.log(\n // \"----- stage1: (gSpan) going to find frequent structure dsG -------\"\n // );\n // console.log(\"----- stage1.1: going to run gSpan -------\");\n // 暂时假设生成的 sub structure 都只有一条边\n\n var freStructures = gSpan_gSpan(params).slice(0, top); // structureNum 可能小于 top\n\n var structureNum = freStructures.length; // 1.4. 计算上述 10 个子结构在 intGMap 中每个诱导子图的匹配个数\n\n var matchedCountMap = [];\n freStructures.forEach(function (structure, i) {\n matchedCountMap[i] = {};\n Object.keys(intGMap).forEach(function (key) {\n var graph = intGMap[key];\n var subStructureCount = getMatchedCount(graph, structure, nodeLabelProp, edgeLabelProp);\n matchedCountMap[i][key] = subStructureCount;\n });\n }); // console.log(\n // \"----- stage1.1: going to find the most represent strucutre -------\"\n // );\n // 1.5. 对于每个子结构,根据匹配个数为 intGMap 中的诱导子图分组,生成 structureNum 种分组\n // 计算每种分组的类间距和类内间距,找到类间距最大、类内间距最小的一种分组,这种分组对应的子结构被选为唯一代表性子结构 DS(G)\n\n var _c = findRepresentStructure(matchedCountMap, structureNum, freStructures),\n dsG = _c.structure,\n ndsDist = _c.structureCountMap; // -------- 第二步,匹配-------\n // 2.1 从 Q 中的第一个标签的第一个节点开始,寻找 G 中的匹配\n\n\n var beginPNode = pattern.nodes[0];\n var label = beginPNode[nodeLabelProp]; // 2.1.1 找到 G 中标签与之相同的节点\n\n var candidates = nodeLabelMap[label]; // console.log(\"----- stage2: going to find candidates -------\");\n // 全局缓存,避免重复计算\n\n var minPatternNodeLabelDegreeMap = {}; // key 是 label,value 是该 label 节点的最小度数\n\n var patternIntGraphMap = {},\n patternNDSDist = {},\n // key 为 node.id-node.id\n patternNDSDistMap = {}; // key 为 node.id-label2,value nds距离值数组(按从大到小排序,无需关心具体对应哪个 node2)\n // 2.2.2 对于 Q 中的另一个标签的 k 个节点,计算它们到 node 的最短路径以及 NDS 距离\n\n var patternSpDist = {};\n var patternSpDistBack = {};\n Object.keys(patternNodeLabelMap).forEach(function (label2, j) {\n patternSpDist[label2] = [];\n\n if (directed) {\n patternSpDistBack[label2] = [];\n }\n\n var maxDist = -Infinity;\n var patternNodesWithLabel2 = patternNodeLabelMap[label2];\n var patternNodePairMap = {};\n patternNodesWithLabel2.forEach(function (nodeWithLabel2) {\n var dist = patternSpmMap[beginPNode.id + \"-\" + nodeWithLabel2.id];\n dist && patternSpDist[label2].push(dist);\n if (maxDist < dist) maxDist = dist;\n patternNodePairMap[beginPNode.id + \"-\" + nodeWithLabel2.id] = {\n start: 0,\n end: patternNodeMap[nodeWithLabel2.id].idx,\n distance: dist\n };\n\n if (directed) {\n var distBack = patternSpmMap[nodeWithLabel2.id + \"-\" + beginPNode.id];\n distBack && patternSpDistBack[label2].push(distBack);\n }\n }); // spDist[label2] 按照从小到大排序\n\n patternSpDist[label2] = patternSpDist[label2].sort(function (a, b) {\n return a - b;\n });\n if (directed) patternSpDistBack[label2] = patternSpDistBack[label2].sort(function (a, b) {\n return a - b;\n }); // 计算 Q 中所有 label2 节点到 beginPNode 的 NDS 距离\n // 所有 label2 节点到 beginPNode 的邻居相交诱导子图:\n // key: node1.id-node2.id\n\n patternIntGraphMap = getIntersectNeighborInducedGraph(patternNodePairMap, patternKNeighborUnits, pattern, patternIntGraphMap); // pattern 中 beginNode 到当前 label2 节点 的 NDS 距离(数组,无需关心具体对应到哪个节点)\n\n var currentPatternNDSDistArray = [];\n Object.keys(patternNodePairMap).forEach(function (key) {\n if (patternNDSDist[key]) {\n currentPatternNDSDistArray.push(patternNDSDist[key]);\n return; // 缓存过则不需要再次计算\n }\n\n var patternIntGraph = patternIntGraphMap[key];\n patternNDSDist[key] = getMatchedCount(patternIntGraph, dsG, nodeLabelProp, edgeLabelProp);\n currentPatternNDSDistArray.push(patternNDSDist[key]);\n }); // 根据值为 currentPatternNDSDist 从大到小排序\n\n currentPatternNDSDistArray = currentPatternNDSDistArray.sort(function (a, b) {\n return b - a;\n });\n patternNDSDistMap[beginPNode.id + \"-\" + label2] = currentPatternNDSDistArray;\n if (label2 === label) return;\n var candidatesNum = candidates.length;\n\n var _loop_4 = function _loop_4(m) {\n var cNode = candidates[m]; // prune1:若 candidates 中节点 cNode 的 kNeighborUnits 中标签为 label2 的节点个数少于 pattern 中 label2 个数,删去它\n\n var graphNeighborUnit = kNeighborUnits[nodeMap[cNode.id].idx];\n var graphNeighborUnitCountMap = graphNeighborUnit.nodeLabelCountMap[label2];\n var patternLabel2Num = patternNodeLabelMap[label2].length;\n\n if (!graphNeighborUnitCountMap || graphNeighborUnitCountMap.count < patternLabel2Num) {\n candidates.splice(m, 1);\n return \"continue\";\n } // prune2:若 candidates 中节点 cNode 到 kNeighborUnits 中标签为 label2 的节点最短路径大于 patternSpDist[label2],删去它\n // (prune2 规则即:candidate 相关的最短路径的最大 spDist[label2].length 个,按照大小顺序依次和 patternSpDist[label2] 中的值比较,只要遇到一个是 G > Q 的,就删去这个 candidate)\n\n\n var prune2Invalid = false;\n\n for (var n = 0; n < patternLabel2Num; n++) {\n if (graphNeighborUnitCountMap.dists[n] > patternSpDist[label2][n]) {\n prune2Invalid = true;\n break;\n }\n }\n\n if (prune2Invalid) {\n candidates.splice(m, 1);\n return \"continue\";\n } // prune3:若 candidates 中节点 cNode 到 kNeighborUnits 中标签为 label2 的节点 NDS 距离小于 patternNDSDist[beginNode.id-label2],删去它\n // TODO:prune3,currentPatternNDSDistArray 与 currentNDSDist 的比较\n // 计算 G 中所有 label2 节点到 cNode 的 NDS 距离\n // 所有 label2 节点到 cNode 的邻居相交诱导子图:\n\n\n var cNodePairMap = {};\n graphNeighborUnit.neighbors.forEach(function (neighborNode) {\n var dist = spmMap[cNode.id + \"-\" + neighborNode.id];\n cNodePairMap[cNode.id + \"-\" + neighborNode.id] = {\n start: nodeMap[cNode.id].idx,\n end: nodeMap[neighborNode.id].idx,\n distance: dist\n };\n }); // 更新 intGMap\n\n intGMap = getIntersectNeighborInducedGraph(cNodePairMap, kNeighborUnits, graphData, intGMap); // candidate 到它周围 label2 节点的 NDS 距离, key 是 node.id-node.id\n\n var currentNDSDistArray = [];\n Object.keys(cNodePairMap).forEach(function (key) {\n if (ndsDist[key]) {\n currentNDSDistArray.push(ndsDist[key]);\n return; // 缓存过则不需要再次计算\n }\n\n var intGraph = intGMap[key];\n ndsDist[key] = getMatchedCount(intGraph, dsG, nodeLabelProp, edgeLabelProp);\n currentNDSDistArray.push(ndsDist[key]);\n }); // 根据值为 currentNDSDistArray 从大到小排序\n\n currentNDSDistArray = currentNDSDistArray.sort(function (a, b) {\n return b - a;\n });\n var prune3Invalid = false;\n\n for (var n = 0; n < patternLabel2Num; n++) {\n if (currentNDSDistArray[n] < currentPatternNDSDistArray[n]) {\n prune3Invalid = true;\n break;\n }\n }\n\n if (prune3Invalid) {\n candidates.splice(m, 1);\n return \"continue\";\n }\n };\n\n for (var m = candidatesNum - 1; m >= 0; m--) {\n _loop_4(m);\n }\n });\n var candidateGraphs = []; // console.log(\n // \"----- stage3: going to splice neighbors for each candidate graph -------\"\n // );\n // candidates 经过筛选后,以每个 candidate 为中心,生成 Length-neighbor 的邻居诱导子图\n // 并在诱导子图中去除不可能在 Q 上找到匹配的点:在 Q 上不存在的 label,其他 label 到 candidate 的最大最短距离符合 Q、NDS 距离符合 Q\n\n candidates === null || candidates === void 0 ? void 0 : candidates.forEach(function (candidate) {\n var nodeIdx = nodeMap[candidate.id].idx;\n var lengthNeighborUnit = findKNeighborUnit(graphData.nodes, spm[nodeIdx], nodeIdx, nodeLabelProp, length);\n var neighborNodes = lengthNeighborUnit.neighbors; // 删除不可能找到匹配的邻居点\n\n var neighborNum = neighborNodes.length;\n var unmatched = false;\n\n for (var i = neighborNum - 1; i >= 0; i--) {\n // 如果通过裁剪,符合条件的节点数量已过少,说明不能匹配这个 candidate 相关的图\n if (neighborNodes.length + 1 < pattern.nodes.length) {\n unmatched = true;\n return;\n }\n\n var neighborNode = neighborNodes[i];\n var neighborLabel = neighborNode[nodeLabelProp]; // prune1: 若该邻居点的 label 不存在于 pattern 中,移除这个点\n\n if (!patternNodeLabelMap[neighborLabel] || !patternNodeLabelMap[neighborLabel].length) {\n neighborNodes.splice(i, 1);\n continue;\n } // prune2: 若该邻居点到 candidate 的最短路径比和它有相同 label 的节点到 beginPNode 的最大最短路径长度长,移除这个点\n // prune2.1: 如果没有这个标签到 beginPNode 的距离记录,说明 pattern 上(可能 beginPNode 是这个 label)没有其他这个 label 的节点\n\n\n if (!patternSpDist[neighborLabel] || !patternSpDist[neighborLabel].length) {\n neighborNodes.splice(i, 1);\n continue;\n }\n\n var key = candidate.id + \"-\" + neighborNode.id; // prune2.2\n\n var distToCandidate = spmMap[key];\n var idx = patternSpDist[neighborLabel].length - 1;\n var maxDistWithLabelInPattern = patternSpDist[neighborLabel][idx]; // patternSpDist[neighborLabel] 已经按照从小到大排序\n\n if (distToCandidate > maxDistWithLabelInPattern) {\n neighborNodes.splice(i, 1);\n continue;\n }\n\n if (directed) {\n var keyBack = neighborNode.id + \"-\" + candidate.id;\n var distFromCandidate = spmMap[keyBack];\n idx = patternSpDistBack[neighborLabel].length - 1;\n var maxBackDistWithLabelInPattern = patternSpDistBack[neighborLabel][idx];\n\n if (distFromCandidate > maxBackDistWithLabelInPattern) {\n neighborNodes.splice(i, 1);\n continue;\n }\n } // prune3: 若该邻居点到 candidate 的 NDS 距离比和它有相同 label 的节点到 beginPNode 的最小 NDS 距离小,移除这个点\n\n\n var ndsToCandidate = ndsDist[key] ? ndsDist[key] : getNDSDist(graphData, candidate, neighborNode, nodeMap, distToCandidate, kNeighborUnits, dsG, nodeLabelProp, edgeLabelProp, ndsDist, intGMap);\n var patternKey = beginPNode.id + \"-\" + neighborLabel;\n var minNdsWithLabelInPattern = patternNDSDistMap[patternKey][patternNDSDistMap[patternKey].length - 1]; // patternNDSDist[key] 一定存在\n\n if (ndsToCandidate < minNdsWithLabelInPattern) {\n neighborNodes.splice(i, 1);\n continue;\n } // prune4: 若该邻居点的度数小于 pattern 同 label 节点最小度数,删去该点\n\n\n var _a = stashPatternNodeLabelDegreeMap(minPatternNodeLabelDegreeMap, neighborLabel, patternNodeMap, patternNodeLabelMap),\n minPatternNodeLabelDegree = _a.minPatternNodeLabelDegree,\n minPatternNodeLabelInDegree = _a.minPatternNodeLabelInDegree,\n minPatternNodeLabelOutDegree = _a.minPatternNodeLabelOutDegree;\n\n if (nodeMap[neighborNode.id].degree < minPatternNodeLabelDegree) {\n neighborNodes.splice(i, 1);\n continue;\n }\n } // 节点在个数上符合匹配(不少于 pattern 的节点个数),现在筛选相关边\n\n\n if (!unmatched) {\n candidateGraphs.push({\n nodes: [candidate].concat(neighborNodes)\n });\n }\n }); // console.log(\n // \"----- stage4: going to splice edges and neighbors for each candidate graph -------\"\n // );\n\n var undirectedLengthsToBeginPNode = es_dijkstra(pattern, beginPNode.id, false).length;\n var undirectedLengthsToBeginPNodeLabelMap = {};\n\n if (directed) {\n Object.keys(undirectedLengthsToBeginPNode).forEach(function (nodeId) {\n var nodeLabel = patternNodeMap[nodeId].node[nodeLabelProp];\n if (!undirectedLengthsToBeginPNodeLabelMap[nodeLabel]) undirectedLengthsToBeginPNodeLabelMap[nodeLabel] = [undirectedLengthsToBeginPNode[nodeId]];else undirectedLengthsToBeginPNodeLabelMap[nodeLabel].push(undirectedLengthsToBeginPNode[nodeId]);\n });\n Object.keys(undirectedLengthsToBeginPNodeLabelMap).forEach(function (pLabel) {\n undirectedLengthsToBeginPNodeLabelMap[pLabel].sort(function (a, b) {\n return a - b;\n });\n });\n } else {\n undirectedLengthsToBeginPNodeLabelMap = patternSpDist;\n } // 现在 candidateGraphs 里面只有节点,进行边的筛选\n\n\n var candidateGraphNum = candidateGraphs.length;\n\n var _loop_2 = function _loop_2(i) {\n var candidateGraph = candidateGraphs[i];\n var candidate = candidateGraph.nodes[0];\n var candidateNodeLabelCountMap = {};\n var candidateNodeMap = {};\n candidateGraph.nodes.forEach(function (node, q) {\n candidateNodeMap[node.id] = {\n idx: q,\n node: node,\n degree: 0,\n inDegree: 0,\n outDegree: 0\n };\n var cNodeLabel = node[nodeLabelProp];\n if (!candidateNodeLabelCountMap[cNodeLabel]) candidateNodeLabelCountMap[cNodeLabel] = 1;else candidateNodeLabelCountMap[cNodeLabel]++;\n }); // 根据 candidate 和 neighborNodes 中的节点生成 G 的诱导子图\n // 即,将 graphData 上两端都在 candidateGraph.nodes 中的边放入 candidateEdges\n\n var candidateEdges = [];\n var edgeLabelCountMap = {};\n graphData.edges.forEach(function (edge) {\n if (candidateNodeMap[edge.source] && candidateNodeMap[edge.target]) {\n candidateEdges.push(edge);\n if (!edgeLabelCountMap[edge[edgeLabelProp]]) edgeLabelCountMap[edge[edgeLabelProp]] = 1;else edgeLabelCountMap[edge[edgeLabelProp]]++;\n candidateNodeMap[edge.source].degree++;\n candidateNodeMap[edge.target].degree++;\n candidateNodeMap[edge.source].outDegree++;\n candidateNodeMap[edge.target].inDegree++;\n }\n }); // prune:若有一个 edgeLabel 在 candidateGraph 上的个数少于 pattern,去除该图\n\n var pattenrEdgeLabelNum = Object.keys(patternEdgeLabelMap).length;\n var prunedByEdgeLabel = false;\n\n for (var e = 0; e < pattenrEdgeLabelNum; e++) {\n var label_1 = Object.keys(patternEdgeLabelMap)[e];\n\n if (!edgeLabelCountMap[label_1] || edgeLabelCountMap[label_1] < patternEdgeLabelMap[label_1].length) {\n prunedByEdgeLabel = true;\n break;\n }\n }\n\n if (prunedByEdgeLabel) {\n candidateGraphs.splice(i, 1);\n return \"continue\";\n } // 遍历 candidateEdges,进行边的筛选\n\n\n var candidateEdgeNum = candidateEdges.length; // prune:若边数过少,去除该图\n\n if (candidateEdgeNum < pattern.edges.length) {\n candidateGraphs.splice(i, 1);\n return \"break\";\n }\n\n var candidateGraphInvalid = false;\n\n var _loop_5 = function _loop_5(e) {\n var edge = candidateEdges[e];\n var edgeLabel = edge[edgeLabelProp];\n var patternEdgesWithLabel = patternEdgeLabelMap[edgeLabel]; // prune 1: 若边的 label 不存在于 pattern 边 label 中,去除该边\n\n if (!patternEdgesWithLabel || !patternEdgesWithLabel.length) {\n edgeLabelCountMap[edgeLabel]--; // 若这个 label 的 count 减少之后,该 label 的边数不足,去除该图\n\n if (patternEdgesWithLabel && edgeLabelCountMap[edgeLabel] < patternEdgesWithLabel.length) {\n candidateGraphInvalid = true;\n return \"break\";\n }\n\n candidateEdges.splice(e, 1);\n candidateNodeMap[edge.source].degree--;\n candidateNodeMap[edge.target].degree--;\n candidateNodeMap[edge.source].outDegree--;\n candidateNodeMap[edge.target].inDegree--;\n return \"continue\";\n } // prune 2: 若边的 label +两端 label 的三元组关系不能在 pattern 中找到,去除该边\n\n\n var sourceLabel = candidateNodeMap[edge.source].node[nodeLabelProp];\n var targetLabel = candidateNodeMap[edge.target].node[nodeLabelProp];\n var edgeMatched = false;\n patternEdgesWithLabel.forEach(function (patternEdge) {\n var patternSource = patternNodeMap[patternEdge.source].node;\n var patternTarget = patternNodeMap[patternEdge.target].node;\n if (patternSource[nodeLabelProp] === sourceLabel && patternTarget[nodeLabelProp] === targetLabel) edgeMatched = true;\n if (!directed && patternSource[nodeLabelProp] === targetLabel && patternTarget[nodeLabelProp] === sourceLabel) edgeMatched = true;\n });\n\n if (!edgeMatched) {\n edgeLabelCountMap[edgeLabel]--; // 若这个 label 的 count 减少之后,该 label 的边数不足,去除该图\n\n if (patternEdgesWithLabel && edgeLabelCountMap[edgeLabel] < patternEdgesWithLabel.length) {\n candidateGraphInvalid = true;\n return \"break\";\n }\n\n candidateEdges.splice(e, 1);\n candidateNodeMap[edge.source].degree--;\n candidateNodeMap[edge.target].degree--;\n candidateNodeMap[edge.source].outDegree--;\n candidateNodeMap[edge.target].inDegree--;\n return \"continue\";\n }\n };\n\n for (var e = candidateEdgeNum - 1; e >= 0; e--) {\n var state_2 = _loop_5(e);\n\n if (state_2 === \"break\") break;\n } // prune2: 删除边的过程中,发现边数过少/边 label 数过少时,去除该图\n\n\n if (candidateGraphInvalid) {\n candidateGraphs.splice(i, 1);\n return \"continue\";\n }\n\n candidateGraph.edges = candidateEdges;\n var lengthsToCandidate = es_dijkstra(candidateGraph, candidateGraph.nodes[0].id, false).length;\n Object.keys(lengthsToCandidate).reverse().forEach(function (targetId) {\n if (targetId === candidateGraph.nodes[0].id || candidateGraphInvalid) return; // prune4: 通过上述裁剪,可能导致该邻居子图变为不连通。裁剪掉目前在这个邻居子图中和 candidate(第一个节点)不连通的节点\n\n if (lengthsToCandidate[targetId] === Infinity) {\n var targetNodeLabel = candidateNodeMap[targetId].node[nodeLabelProp];\n candidateNodeLabelCountMap[targetNodeLabel]--;\n\n if (candidateNodeLabelCountMap[targetNodeLabel] < patternNodeLabelMap[targetNodeLabel].length) {\n candidateGraphInvalid = true;\n return;\n }\n\n var idx = candidateGraph.nodes.indexOf(candidateNodeMap[targetId].node);\n candidateGraph.nodes.splice(idx, 1);\n candidateNodeMap[targetId] = undefined;\n return;\n } // prune5: 经过边裁剪后,可能又出现了最短路径过长的节点 (比 pattern 中同 label 的节点到 beginNode 最大最短距离远),删去这些节点\n\n\n var nLabel = nodeMap[targetId].node[nodeLabelProp];\n\n if (!undirectedLengthsToBeginPNodeLabelMap[nLabel] || !undirectedLengthsToBeginPNodeLabelMap[nLabel].length || lengthsToCandidate[targetId] > undirectedLengthsToBeginPNodeLabelMap[nLabel][undirectedLengthsToBeginPNodeLabelMap[nLabel].length - 1]) {\n var targetNodeLabel = candidateNodeMap[targetId].node[nodeLabelProp];\n candidateNodeLabelCountMap[targetNodeLabel]--;\n\n if (candidateNodeLabelCountMap[targetNodeLabel] < patternNodeLabelMap[targetNodeLabel].length) {\n candidateGraphInvalid = true;\n return;\n }\n\n var idx = candidateGraph.nodes.indexOf(candidateNodeMap[targetId].node);\n candidateGraph.nodes.splice(idx, 1);\n candidateNodeMap[targetId] = undefined;\n }\n });\n\n if (candidateGraphInvalid) {\n candidateGraphs.splice(i, 1);\n return \"continue\";\n }\n\n var degreeChanged = true;\n var loopCount = 0;\n\n while (degreeChanged && !candidateGraphInvalid) {\n degreeChanged = false; // candidate 度数不足,删去该图\n\n var condition = directed ? candidateNodeMap[candidate.id].degree < patternNodeMap[beginPNode.id].degree || candidateNodeMap[candidate.id].inDegree < patternNodeMap[beginPNode.id].inDegree || candidateNodeMap[candidate.id].outDegree < patternNodeMap[beginPNode.id].outDegree : candidateNodeMap[candidate.id].degree < patternNodeMap[beginPNode.id].degree;\n\n if (condition) {\n candidateGraphInvalid = true;\n break;\n } // candidate label 个数不足,删去该图\n\n\n if (candidateNodeLabelCountMap[candidate[nodeLabelProp]] < patternNodeLabelMap[candidate[nodeLabelProp]].length) {\n candidateGraphInvalid = true;\n break;\n } // prune6:去除度数过小的节点\n\n\n var currentCandidateNodeNum = candidateGraph.nodes.length;\n\n for (var o = currentCandidateNodeNum - 1; o >= 0; o--) {\n var cgNode = candidateGraph.nodes[o];\n var nodeDegree = candidateNodeMap[cgNode.id].degree;\n var nodeInDegree = candidateNodeMap[cgNode.id].inDegree;\n var nodeOutDegree = candidateNodeMap[cgNode.id].outDegree;\n var cNodeLabel = cgNode[nodeLabelProp];\n\n var _d = stashPatternNodeLabelDegreeMap(minPatternNodeLabelDegreeMap, cNodeLabel, patternNodeMap, patternNodeLabelMap),\n minPatternNodeLabelDegree = _d.minPatternNodeLabelDegree,\n minPatternNodeLabelInDegree = _d.minPatternNodeLabelInDegree,\n minPatternNodeLabelOutDegree = _d.minPatternNodeLabelOutDegree;\n\n var deleteCondition = directed ? nodeDegree < minPatternNodeLabelDegree || nodeInDegree < minPatternNodeLabelInDegree || nodeOutDegree < minPatternNodeLabelOutDegree : nodeDegree < minPatternNodeLabelDegree;\n\n if (deleteCondition) {\n candidateNodeLabelCountMap[cgNode[nodeLabelProp]]--; // 节点 label 个数不足\n\n if (candidateNodeLabelCountMap[cgNode[nodeLabelProp]] < patternNodeLabelMap[cgNode[nodeLabelProp]].length) {\n candidateGraphInvalid = true;\n break;\n }\n\n candidateGraph.nodes.splice(o, 1);\n candidateNodeMap[cgNode.id] = undefined;\n degreeChanged = true;\n }\n }\n\n if (candidateGraphInvalid || !degreeChanged && loopCount !== 0) break; // 经过 prune5 节点裁剪,删去端点已经不在 candidateGraph 中的边\n\n candidateEdgeNum = candidateEdges.length;\n\n for (var y = candidateEdgeNum - 1; y >= 0; y--) {\n var cedge = candidateEdges[y];\n\n if (!candidateNodeMap[cedge.source] || !candidateNodeMap[cedge.target]) {\n candidateEdges.splice(y, 1);\n var edgeLabel = cedge[edgeLabelProp];\n edgeLabelCountMap[edgeLabel]--;\n\n if (candidateNodeMap[cedge.source]) {\n candidateNodeMap[cedge.source].degree--;\n candidateNodeMap[cedge.source].outDegree--;\n }\n\n if (candidateNodeMap[cedge.target]) {\n candidateNodeMap[cedge.target].degree--;\n candidateNodeMap[cedge.target].inDegree--;\n } // 边 label 数量不足\n\n\n if (patternEdgeLabelMap[edgeLabel] && edgeLabelCountMap[edgeLabel] < patternEdgeLabelMap[edgeLabel].length) {\n candidateGraphInvalid = true;\n break;\n }\n\n degreeChanged = true;\n }\n }\n\n loopCount++;\n }\n\n if (candidateGraphInvalid) {\n candidateGraphs.splice(i, 1);\n return \"continue\";\n } // prune: 若节点/边数过少,节点/边 label 过少,去掉这个图\n\n\n if (candidateGraphInvalid || candidateGraph.nodes.length < pattern.nodes.length || candidateEdges.length < pattern.edges.length) {\n candidateGraphs.splice(i, 1);\n return \"continue\";\n }\n };\n\n for (var i = candidateGraphNum - 1; i >= 0; i--) {\n var state_1 = _loop_2(i);\n\n if (state_1 === \"break\") break;\n } // 此时已经生成的多个 candidateGraphs,可能有重复\n // console.log(\n // \"----- stage5: going to splice dulplicated candidate graphs -------\"\n // );\n // 删去 candidateGraphs 中一模一样的子图,通过边的 node-node-edgeLabel 作为 key,这类边个数作为 value,进行匹配\n\n\n var currentLength = candidateGraphs.length;\n\n var _loop_3 = function _loop_3(i) {\n var cg1 = candidateGraphs[i];\n var cg1EdgeMap = {}; // [node1.id-node2.id-edge.label]: count\n\n cg1.edges.forEach(function (edge) {\n var key = edge.source + \"-\" + edge.target + \"-\" + edge.label;\n if (!cg1EdgeMap[key]) cg1EdgeMap[key] = 1;else cg1EdgeMap[key]++;\n });\n\n var _loop_6 = function _loop_6(j) {\n var cg2 = candidateGraphs[j];\n var cg2EdgeMap = {}; // [node1.id-node2.id-edge.label]: count\n\n cg2.edges.forEach(function (edge) {\n var key = edge.source + \"-\" + edge.target + \"-\" + edge.label;\n if (!cg2EdgeMap[key]) cg2EdgeMap[key] = 1;else cg2EdgeMap[key]++;\n });\n var same = true;\n\n if (Object.keys(cg2EdgeMap).length !== Object.keys(cg1EdgeMap).length) {\n same = false;\n } else {\n Object.keys(cg1EdgeMap).forEach(function (key) {\n if (cg2EdgeMap[key] !== cg1EdgeMap[key]) same = false;\n });\n }\n\n if (same) {\n candidateGraphs.splice(j, 1);\n }\n };\n\n for (var j = currentLength - 1; j > i; j--) {\n _loop_6(j);\n }\n\n currentLength = candidateGraphs.length;\n };\n\n for (var i = 0; i <= currentLength - 1; i++) {\n _loop_3(i);\n }\n\n return candidateGraphs;\n};\n\n/* harmony default export */ var gaddi = (gaddi_GADDI);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/structs/stack.js\n\n\nvar stack_Stack =\n/** @class */\nfunction () {\n function Stack(maxStep) {\n if (maxStep === void 0) {\n maxStep = 10;\n }\n\n this.linkedList = new linked_list();\n this.maxStep = maxStep;\n }\n\n Object.defineProperty(Stack.prototype, \"length\", {\n get: function get() {\n return this.linkedList.toArray().length;\n },\n enumerable: false,\n configurable: true\n });\n /**\n * 判断栈是否为空,如果链表中没有头部元素,则栈为空\n */\n\n Stack.prototype.isEmpty = function () {\n return !this.linkedList.head;\n };\n /**\n * 是否到定义的栈的最大长度,如果达到最大长度后,不再允许入栈\n */\n\n\n Stack.prototype.isMaxStack = function () {\n return this.toArray().length >= this.maxStep;\n };\n /**\n * 访问顶端元素\n */\n\n\n Stack.prototype.peek = function () {\n if (this.isEmpty()) {\n return null;\n } // 返回头部元素,不删除元素\n\n\n return this.linkedList.head.value;\n };\n\n Stack.prototype.push = function (value) {\n this.linkedList.prepend(value);\n\n if (this.length > this.maxStep) {\n this.linkedList.deleteTail();\n }\n };\n\n Stack.prototype.pop = function () {\n var removeHead = this.linkedList.deleteHead();\n return removeHead ? removeHead.value : null;\n };\n\n Stack.prototype.toArray = function () {\n return this.linkedList.toArray().map(function (node) {\n return node.value;\n });\n };\n\n Stack.prototype.clear = function () {\n while (!this.isEmpty()) {\n this.pop();\n }\n };\n\n return Stack;\n}();\n\n/* harmony default export */ var structs_stack = (stack_Stack);\n// CONCATENATED MODULE: ./node_modules/@antv/algorithm/es/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar es_detectDirectedCycle = detect_cycle;\n\n/* harmony default export */ var es = ({\n getAdjMatrix: adjacent_matrix,\n breadthFirstSearch: bfs,\n connectedComponent: getConnectedComponents,\n getDegree: es_degree,\n getInDegree: getInDegree,\n getOutDegree: getOutDegree,\n detectCycle: detect_cycle,\n detectDirectedCycle: es_detectDirectedCycle,\n detectAllCycles: detectAllCycles,\n detectAllDirectedCycle: detect_cycle_detectAllDirectedCycle,\n detectAllUndirectedCycle: detect_cycle_detectAllUndirectedCycle,\n depthFirstSearch: depthFirstSearch,\n dijkstra: es_dijkstra,\n findAllPath: find_path_findAllPath,\n findShortestPath: find_path_findShortestPath,\n floydWarshall: es_floydWarshall,\n labelPropagation: label_propagation,\n louvain: es_louvain,\n minimumSpanningTree: mts,\n pageRank: es_pageRank,\n getNeighbors: getNeighbors,\n Stack: structs_stack,\n GADDI: gaddi\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/math.js\n\n\nvar math_transform = matrix_util_esm[\"ext\"].transform;\n/**\n * 对比对象,用于对象数组排序\n * @param {string} attributeName 排序依据的字段名称\n * @param {number} min 最小值\n * @param {number} max 最大值\n * @return {boolean} bool 布尔\n */\n\nvar compare = function compare(attributeName) {\n return function (m, n) {\n return m[attributeName] - n[attributeName];\n };\n};\n/**\n * 是否在区间内\n * @param {number} value 值\n * @param {number} min 最小值\n * @param {number} max 最大值\n * @return {boolean} bool 布尔\n */\n\nvar isBetween = function isBetween(value, min, max) {\n return value >= min && value <= max;\n};\n/**\n * 获取两条线段的交点\n * @param {Point} p0 第一条线段起点\n * @param {Point} p1 第一条线段终点\n * @param {Point} p2 第二条线段起点\n * @param {Point} p3 第二条线段终点\n * @return {Point} 交点\n */\n\n\nvar getLineIntersect = function getLineIntersect(p0, p1, p2, p3) {\n var tolerance = 0.0001;\n var E = {\n x: p2.x - p0.x,\n y: p2.y - p0.y\n };\n var D0 = {\n x: p1.x - p0.x,\n y: p1.y - p0.y\n };\n var D1 = {\n x: p3.x - p2.x,\n y: p3.y - p2.y\n };\n var kross = D0.x * D1.y - D0.y * D1.x;\n var sqrKross = kross * kross;\n var invertKross = 1 / kross;\n var sqrLen0 = D0.x * D0.x + D0.y * D0.y;\n var sqrLen1 = D1.x * D1.x + D1.y * D1.y;\n\n if (sqrKross > tolerance * sqrLen0 * sqrLen1) {\n var s = (E.x * D1.y - E.y * D1.x) * invertKross;\n var t = (E.x * D0.y - E.y * D0.x) * invertKross;\n if (!isBetween(s, 0, 1) || !isBetween(t, 0, 1)) return null;\n return {\n x: p0.x + s * D0.x,\n y: p0.y + s * D0.y\n };\n }\n\n return null;\n};\n/**\n * point and rectangular intersection point\n * @param {IRect} rect rect\n * @param {Point} point point\n * @return {PointPoint} rst;\n */\n\nvar getRectIntersectByPoint = function getRectIntersectByPoint(rect, point) {\n var x = rect.x,\n y = rect.y,\n width = rect.width,\n height = rect.height;\n var cx = x + width / 2;\n var cy = y + height / 2;\n var points = [];\n var center = {\n x: cx,\n y: cy\n };\n points.push({\n x: x,\n y: y\n });\n points.push({\n x: x + width,\n y: y\n });\n points.push({\n x: x + width,\n y: y + height\n });\n points.push({\n x: x,\n y: y + height\n });\n points.push({\n x: x,\n y: y\n });\n var rst = null;\n\n for (var i = 1; i < points.length; i++) {\n rst = getLineIntersect(points[i - 1], points[i], center, point);\n\n if (rst) {\n break;\n }\n }\n\n return rst;\n};\n/**\n * get point and circle inIntersect\n * @param {ICircle} circle 圆点,x,y,r\n * @param {Point} point 点 x,y\n * @return {Point} applied point\n */\n\nvar getCircleIntersectByPoint = function getCircleIntersectByPoint(circle, point) {\n var cx = circle.x,\n cy = circle.y,\n r = circle.r;\n var x = point.x,\n y = point.y;\n var dx = x - cx;\n var dy = y - cy;\n\n if (dx * dx + dy * dy < r * r) {\n return null;\n }\n\n var angle = Math.atan(dy / dx);\n return {\n x: cx + Math.abs(r * Math.cos(angle)) * Math.sign(dx),\n y: cy + Math.abs(r * Math.sin(angle)) * Math.sign(dy)\n };\n};\n/**\n * get point and ellipse inIntersect\n * @param {Object} ellipse 椭圆 x,y,rx,ry\n * @param {Object} point 点 x,y\n * @return {object} applied point\n */\n\nvar getEllipseIntersectByPoint = function getEllipseIntersectByPoint(ellipse, point) {\n var a = ellipse.rx;\n var b = ellipse.ry;\n var cx = ellipse.x;\n var cy = ellipse.y;\n var dx = point.x - cx;\n var dy = point.y - cy; // 直接通过 x,y 求夹角,求出来的范围是 -PI, PI\n\n var angle = Math.atan2(dy / b, dx / a);\n\n if (angle < 0) {\n angle += 2 * Math.PI; // 转换到 0,2PI\n }\n\n return {\n x: cx + a * Math.cos(angle),\n y: cy + b * Math.sin(angle)\n };\n};\n/**\n * coordinate matrix transformation\n * @param {number} point coordinate\n * @param {Matrix} matrix matrix\n * @param {number} tag could be 0 or 1\n * @return {Point} transformed point\n */\n\nvar math_applyMatrix = function applyMatrix(point, matrix, tag) {\n if (tag === void 0) {\n tag = 1;\n }\n\n var vector = [point.x, point.y, tag];\n\n if (!matrix || isNaN(matrix[0])) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n matrix_util_esm[\"vec3\"].transformMat3(vector, vector, matrix);\n return {\n x: vector[0],\n y: vector[1]\n };\n};\n/**\n * coordinate matrix invert transformation\n * @param {number} point coordinate\n * @param {number} matrix matrix\n * @param {number} tag could be 0 or 1\n * @return {object} transformed point\n */\n\nvar math_invertMatrix = function invertMatrix(point, matrix, tag) {\n if (tag === void 0) {\n tag = 1;\n }\n\n if (!matrix || isNaN(matrix[0])) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n var inversedMatrix = matrix_util_esm[\"mat3\"].invert([1, 0, 0, 0, 1, 0, 0, 0, 1], matrix);\n\n if (!inversedMatrix) {\n inversedMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n var vector = [point.x, point.y, tag];\n matrix_util_esm[\"vec3\"].transformMat3(vector, vector, inversedMatrix);\n return {\n x: vector[0],\n y: vector[1]\n };\n};\n/**\n *\n * @param p1 First coordinate\n * @param p2 second coordinate\n * @param p3 three coordinate\n */\n\nvar getCircleCenterByPoints = function getCircleCenterByPoints(p1, p2, p3) {\n var a = p1.x - p2.x;\n var b = p1.y - p2.y;\n var c = p1.x - p3.x;\n var d = p1.y - p3.y;\n var e = (p1.x * p1.x - p2.x * p2.x - p2.y * p2.y + p1.y * p1.y) / 2;\n var f = (p1.x * p1.x - p3.x * p3.x - p3.y * p3.y + p1.y * p1.y) / 2;\n var denominator = b * c - a * d;\n return {\n x: -(d * e - b * f) / denominator,\n y: -(a * f - c * e) / denominator\n };\n};\n/**\n * get distance by two points\n * @param p1 first point\n * @param p2 second point\n */\n\nvar math_distance = function distance(p1, p2) {\n var vx = p1.x - p2.x;\n var vy = p1.y - p2.y;\n return Math.sqrt(vx * vx + vy * vy);\n};\n/**\n * scale matrix\n * @param matrix [ [], [], [] ]\n * @param ratio\n */\n\nvar scaleMatrix = function scaleMatrix(matrix, ratio) {\n var result = [];\n matrix.forEach(function (row) {\n var newRow = [];\n row.forEach(function (v) {\n newRow.push(v * ratio);\n });\n result.push(newRow);\n });\n return result;\n};\n/**\n * Floyd Warshall algorithm for shortest path distances matrix\n * @param {array} adjMatrix adjacency matrix\n * @return {array} distances shortest path distances matrix\n */\n\nvar math_floydWarshall = function floydWarshall(adjMatrix) {\n // initialize\n var dist = [];\n var size = adjMatrix.length;\n\n for (var i = 0; i < size; i += 1) {\n dist[i] = [];\n\n for (var j = 0; j < size; j += 1) {\n if (i === j) {\n dist[i][j] = 0;\n } else if (adjMatrix[i][j] === 0 || !adjMatrix[i][j]) {\n dist[i][j] = Infinity;\n } else {\n dist[i][j] = adjMatrix[i][j];\n }\n }\n } // floyd\n\n\n for (var k = 0; k < size; k += 1) {\n for (var i = 0; i < size; i += 1) {\n for (var j = 0; j < size; j += 1) {\n if (dist[i][j] > dist[i][k] + dist[k][j]) {\n dist[i][j] = dist[i][k] + dist[k][j];\n }\n }\n }\n }\n\n return dist;\n};\n/**\n * get adjacency matrix\n * @param data graph data\n * @param directed whether it's a directed graph\n */\n\nvar getAdjMatrix = function getAdjMatrix(data, directed) {\n var nodes = data.nodes,\n edges = data.edges;\n var matrix = []; // map node with index in data.nodes\n\n var nodeMap = {};\n\n if (!nodes) {\n throw new Error('invalid nodes data!');\n }\n\n if (nodes) {\n nodes.forEach(function (node, i) {\n nodeMap[node.id] = i;\n var row = [];\n matrix.push(row);\n });\n }\n\n if (edges) {\n edges.forEach(function (e) {\n var source = e.source,\n target = e.target;\n var sIndex = nodeMap[source];\n var tIndex = nodeMap[target];\n matrix[sIndex][tIndex] = 1;\n\n if (!directed) {\n matrix[tIndex][sIndex] = 1;\n }\n });\n }\n\n return matrix;\n};\n/**\n * 平移group\n * @param group Group 实例\n * @param vec 移动向量\n */\n\nvar translate = function translate(group, vec) {\n group.translate(vec.x, vec.y);\n};\n/**\n * 移动到指定坐标点\n * @param group Group 实例\n * @param point 移动到的坐标点\n */\n\nvar move = function move(group, point, animate, animateCfg) {\n if (animateCfg === void 0) {\n animateCfg = {\n duration: 500\n };\n }\n\n var matrix = group.getMatrix();\n\n if (!matrix) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n var bbox = group.getCanvasBBox();\n var vx = point.x - bbox.minX;\n var vy = point.y - bbox.minY;\n\n if (animate) {\n var dx_1 = vx * matrix[0];\n var dy_1 = vy * matrix[4];\n var lastX_1 = 0;\n var lastY_1 = 0;\n var newX_1 = 0;\n var newY_1 = 0;\n group.animate(function (ratio) {\n newX_1 = dx_1 * ratio;\n newY_1 = dy_1 * ratio;\n matrix = math_transform(matrix, [['t', newX_1 - lastX_1, newY_1 - lastY_1]]);\n lastX_1 = newX_1;\n lastY_1 = newY_1;\n return {\n matrix: matrix\n };\n }, animateCfg);\n } else {\n var movedMatrix = math_transform(matrix, [['t', vx, vy]]);\n group.setMatrix(movedMatrix);\n }\n};\n/**\n * 缩放 group\n * @param group Group 实例\n * @param point 在x 和 y 方向上的缩放比例\n */\n\nvar math_scale = function scale(group, ratio) {\n var matrix = group.getMatrix();\n\n if (!matrix) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n var scaleXY = ratio;\n\n if (!Object(esm[\"isArray\"])(ratio)) {\n scaleXY = [ratio, ratio];\n }\n\n if (Object(esm[\"isArray\"])(ratio) && ratio.length === 1) {\n scaleXY = [ratio[0], ratio[0]];\n }\n\n matrix = math_transform(matrix, [['s', scaleXY[0], scaleXY[1]]]);\n group.setMatrix(matrix);\n};\n/**\n *\n * @param group Group 实例\n * @param ratio 选择角度\n */\n\nvar math_rotate = function rotate(group, angle) {\n var matrix = group.getMatrix();\n\n if (!matrix) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n matrix = math_transform(matrix, [['r', angle]]);\n group.setMatrix(matrix);\n};\nvar getDegree = function getDegree(n, nodeIdxMap, edges) {\n var degrees = [];\n\n for (var i = 0; i < n; i++) {\n degrees[i] = 0;\n }\n\n edges.forEach(function (e) {\n if (e.source) {\n degrees[nodeIdxMap[e.source]] += 1;\n }\n\n if (e.target) {\n degrees[nodeIdxMap[e.target]] += 1;\n }\n });\n return degrees;\n}; // 判断点Q是否在p1和p2的线段上\n\nfunction onSegment(p1, p2, q) {\n if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) && Math.min(p1[0], p2[0]) <= q[0] && q[0] <= Math.max(p1[0], p2[0]) && Math.min(p1[1], p2[1]) <= q[1] && q[1] <= Math.max(p1[1], p2[1])) {\n return true;\n }\n\n return false;\n}\n/**\n * 判断点P在多边形内-射线法. Borrow from https://github.com/antvis/util/blob/master/packages/path-util/src/point-in-polygon.ts\n * @param points\n * @param x\n * @param y\n */\n\n\nvar isPointInPolygon = function isPointInPolygon(points, x, y) {\n var isHit = false;\n var n = points.length; // 判断两个double在eps精度下的大小关系\n\n var tolerance = 1e-6;\n\n function dcmp(xValue) {\n if (Math.abs(xValue) < tolerance) {\n return 0;\n }\n\n return xValue < 0 ? -1 : 1;\n }\n\n if (n <= 2) {\n // svg 中点小于 3 个时,不显示,也无法被拾取\n return false;\n }\n\n for (var i = 0; i < n; i++) {\n var p1 = points[i];\n var p2 = points[(i + 1) % n];\n\n if (onSegment(p1, p2, [x, y])) {\n // 点在多边形一条边上\n return true;\n } // 前一个判断min(p1[1],p2[1]) 0 !== dcmp(p2[1] - y) > 0 && dcmp(x - (y - p1[1]) * (p1[0] - p2[0]) / (p1[1] - p2[1]) - p1[0]) < 0) {\n isHit = !isHit;\n }\n }\n\n return isHit;\n}; // 判断两个BBox是否相交\n\nvar intersectBBox = function intersectBBox(box1, box2) {\n return !(box2.minX > box1.maxX || box2.maxX < box1.minX || box2.minY > box1.maxY || box2.maxY < box1.minY);\n};\n\nvar math_lineIntersectPolygon = function lineIntersectPolygon(lines, line) {\n var isIntersect = false;\n Object(esm[\"each\"])(lines, function (l) {\n if (getLineIntersect(l.from, l.to, line.from, line.to)) {\n isIntersect = true;\n return false;\n }\n });\n return isIntersect;\n};\n/**\n * 判断两个polygon是否相交。\n * borrow from @antv/path-util\n * @param points1 polygon1的顶点数组\n * @param points2 polygon2的顶点数组\n */\n\n\nvar math_isPolygonsIntersect = function isPolygonsIntersect(points1, points2) {\n var getBBox = function getBBox(points) {\n var xArr = points.map(function (p) {\n return p[0];\n });\n var yArr = points.map(function (p) {\n return p[1];\n });\n return {\n minX: Math.min.apply(null, xArr),\n maxX: Math.max.apply(null, xArr),\n minY: Math.min.apply(null, yArr),\n maxY: Math.max.apply(null, yArr)\n };\n };\n\n var parseToLines = function parseToLines(points) {\n var lines = [];\n var count = points.length;\n\n for (var i = 0; i < count - 1; i++) {\n var point = points[i];\n var next = points[i + 1];\n lines.push({\n from: {\n x: point[0],\n y: point[1]\n },\n to: {\n x: next[0],\n y: next[1]\n }\n });\n }\n\n if (lines.length > 1) {\n var first = points[0];\n var last = points[count - 1];\n lines.push({\n from: {\n x: last[0],\n y: last[1]\n },\n to: {\n x: first[0],\n y: first[1]\n }\n });\n }\n\n return lines;\n }; // 空数组,或者一个点返回 false\n\n\n if (points1.length < 2 || points2.length < 2) {\n return false;\n }\n\n var bbox1 = getBBox(points1);\n var bbox2 = getBBox(points2); // 判定包围盒是否相交,比判定点是否在多边形内要快的多,可以筛选掉大多数情况\n\n if (!intersectBBox(bbox1, bbox2)) {\n return false;\n }\n\n var isIn = false; // 判定点是否在多边形内部,一旦有一个点在另一个多边形内,则返回\n\n Object(esm[\"each\"])(points2, function (point) {\n if (isPointInPolygon(points1, point[0], point[1])) {\n isIn = true;\n return false;\n }\n });\n\n if (isIn) {\n return true;\n }\n\n Object(esm[\"each\"])(points1, function (point) {\n if (isPointInPolygon(points2, point[0], point[1])) {\n isIn = true;\n return false;\n }\n });\n\n if (isIn) {\n return true;\n }\n\n var lines1 = parseToLines(points1);\n var lines2 = parseToLines(points2);\n var isIntersect = false;\n Object(esm[\"each\"])(lines2, function (line) {\n if (math_lineIntersectPolygon(lines1, line)) {\n isIntersect = true;\n return false;\n }\n });\n return isIntersect;\n};\n\nvar math_Line =\n/** @class */\nfunction () {\n function Line(x1, y1, x2, y2) {\n this.x1 = x1;\n this.y1 = y1;\n this.x2 = x2;\n this.y2 = y2;\n }\n\n Line.prototype.getBBox = function () {\n var minX = Math.min(this.x1, this.x2);\n var minY = Math.min(this.y1, this.y2);\n var maxX = Math.max(this.x1, this.x2);\n var maxY = Math.max(this.y1, this.y2);\n var res = {\n x: minX,\n y: minY,\n minX: minX,\n minY: minY,\n maxX: maxX,\n maxY: maxY,\n width: maxX - minX,\n height: maxY - minY\n };\n return res;\n };\n\n return Line;\n}();\n\n\nvar getBBoxBoundLine = function getBBoxBoundLine(bbox, direction) {\n var bounds = {\n top: [bbox.minX, bbox.minY, bbox.maxX, bbox.minY],\n left: [bbox.minX, bbox.minY, bbox.minX, bbox.maxY],\n bottom: [bbox.minX, bbox.maxY, bbox.maxX, bbox.maxY],\n right: [bbox.maxX, bbox.minY, bbox.maxX, bbox.maxY]\n };\n return bounds[direction];\n};\n/**\n * 计算两条线段相交时,相交点对第一条线段上的分割比例\n */\n\nvar fractionAlongLineA = function fractionAlongLineA(la, lb) {\n var uaT = (lb.x2 - lb.x1) * (la.y1 - lb.y1) - (lb.y2 - lb.y1) * (la.x1 - lb.x1);\n var ubT = (la.x2 - la.x1) * (la.y1 - lb.y1) - (la.y2 - la.y1) * (la.x1 - lb.x1);\n var uB = (lb.y2 - lb.y1) * (la.x2 - la.x1) - (lb.x2 - lb.x1) * (la.y2 - la.y1);\n\n if (uB) {\n var ua = uaT / uB;\n var ub = ubT / uB;\n\n if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {\n return ua;\n }\n }\n\n return Number.POSITIVE_INFINITY;\n};\n\nvar itemIntersectByLine = function itemIntersectByLine(item, line) {\n var directions = ['top', 'left', 'bottom', 'right'];\n var bbox = item.getBBox();\n var countIntersections = 0;\n var intersections = [];\n\n for (var i = 0; i < 4; i++) {\n var _a = getBBoxBoundLine(bbox, directions[i]),\n x1 = _a[0],\n y1 = _a[1],\n x2 = _a[2],\n y2 = _a[3];\n\n intersections[i] = getLineIntersect({\n x: line.x1,\n y: line.y1\n }, {\n x: line.x2,\n y: line.y2\n }, {\n x: x1,\n y: y1\n }, {\n x: x2,\n y: y2\n });\n\n if (intersections[i]) {\n countIntersections += 1;\n }\n }\n\n return [intersections, countIntersections];\n};\nvar fractionToLine = function fractionToLine(item, line) {\n var directions = ['top', 'left', 'bottom', 'right'];\n var bbox = item.getBBox();\n var minDistance = Number.POSITIVE_INFINITY;\n var countIntersections = 0;\n\n for (var i = 0; i < 4; i++) {\n var _a = getBBoxBoundLine(bbox, directions[i]),\n x1 = _a[0],\n y1 = _a[1],\n x2 = _a[2],\n y2 = _a[3];\n\n var testDistance = fractionAlongLineA(line, new math_Line(x1, y1, x2, y2));\n testDistance = Math.abs(testDistance - 0.5);\n\n if (testDistance >= 0 && testDistance <= 1) {\n countIntersections += 1;\n minDistance = testDistance < minDistance ? testDistance : minDistance;\n }\n }\n\n if (countIntersections === 0) return -1;\n return minDistance;\n};\nvar getPointsCenter = function getPointsCenter(points) {\n var centerX = 0;\n var centerY = 0;\n\n if (points.length > 0) {\n for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {\n var point = points_1[_i];\n centerX += point.x;\n centerY += point.y;\n }\n\n centerX /= points.length;\n centerY /= points.length;\n }\n\n return {\n x: centerX,\n y: centerY\n };\n};\nvar squareDist = function squareDist(a, b) {\n return Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2);\n};\nvar pointLineSquareDist = function pointLineSquareDist(point, line) {\n var x1 = line.x1;\n var y1 = line.y1;\n var x2 = line.x2 - x1;\n var y2 = line.y2 - y1;\n var px = point.x - x1;\n var py = point.y - y1;\n var dotprod = px * x2 + py * y2;\n var projlenSq;\n\n if (dotprod <= 0) {\n projlenSq = 0;\n } else {\n px = x2 - px;\n py = y2 - py;\n dotprod = px * x2 + py * y2;\n\n if (dotprod <= 0) {\n projlenSq = 0;\n } else {\n projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);\n }\n }\n\n var lenSq = px * px + py * py - projlenSq;\n\n if (lenSq < 0) {\n lenSq = 0;\n }\n\n return lenSq;\n};\nvar isPointsOverlap = function isPointsOverlap(p1, p2, e) {\n if (e === void 0) {\n e = 1e-3;\n }\n\n return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2) < Math.pow(e, 2);\n};\n/**\n * 点到矩形的距离的平方:矩形内部点视作距离为0,外部的点若投影落在矩形边上则为点到矩形边的最近的垂直距离,否则为点到矩形顶点的距离,\n * @param point IPoint\n * @param rect IRect\n */\n\nvar pointRectSquareDist = function pointRectSquareDist(point, rect) {\n var isLeft = point.x < rect.x;\n var isRight = point.x > rect.x + rect.width;\n var isTop = point.y > rect.y + rect.height;\n var isBottom = point.y < rect.y;\n var isPointOutside = isLeft || isRight || isTop || isBottom;\n\n if (!isPointOutside) {\n return 0;\n }\n\n if (isTop && !isLeft && !isRight) {\n return Math.pow(rect.y + rect.height - point.y, 2);\n }\n\n if (isBottom && !isLeft && !isRight) {\n return Math.pow(point.y - rect.y, 2);\n }\n\n if (isLeft && !isTop && !isBottom) {\n return Math.pow(rect.x - point.x, 2);\n }\n\n if (isRight && !isTop && !isBottom) {\n return Math.pow(rect.x + rect.width - point.x, 2);\n }\n\n var dx = Math.min(Math.abs(rect.x - point.x), Math.abs(rect.x + rect.width - point.x));\n var dy = Math.min(Math.abs(rect.y - point.y), Math.abs(rect.y + rect.height - point.y));\n return dx * dx + dy * dy;\n};\n/**\n * point to line distance\n * @param {array} line 线的四个顶点 [x1, y1, x2, y2]\n * @param {object} point 坐标点 {x, y}\n * @return {Number|NaN} distance\n */\n\nvar math_pointLineDistance = function pointLineDistance(line, point) {\n var x1 = line[0],\n y1 = line[1],\n x2 = line[2],\n y2 = line[3];\n var x = point.x,\n y = point.y;\n var d = [x2 - x1, y2 - y1];\n\n if (matrix_util_esm[\"vec2\"].exactEquals(d, [0, 0])) {\n return NaN;\n }\n\n var u = [-d[1], d[0]]; // @ts-ignore\n\n matrix_util_esm[\"vec2\"].normalize(u, u);\n var a = [x - x1, y - y1]; // @ts-ignore\n\n return Math.abs(matrix_util_esm[\"vec2\"].dot(a, u));\n};\n/**\n * Linearly interpolate between start and end, where alpha is the percent distance along the line.\n * alpha = 0 will be start, and alpha = 1 will be end.\n * @param {Number} start\n * @param {Number} end\n * @param {Number} alpha interpolation factor, typically in the closed interval [0, 1]\n * @returns\n */\n\nvar lerp = function lerp(start, end, alpha) {\n return start + (end - start) * alpha;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/global.js\nvar global_subjectColor = 'rgb(95, 149, 255)';\nvar global_backColor = 'rgb(255, 255, 255)';\nvar global_textColor = 'rgb(0, 0, 0)';\nvar activeFill = 'rgb(247, 250, 255)';\nvar nodeMainFill = 'rgb(239, 244, 255)';\nvar comboFill = 'rgb(253, 253, 253)';\nvar disabledFill = 'rgb(250, 250, 250)';\nvar edgeMainStroke = 'rgb(224, 224, 224)';\nvar edgeInactiveStroke = 'rgb(234, 234, 234)';\nvar edgeDisablesStroke = 'rgb(245, 245, 245)';\nvar inactiveStroke = 'rgb(191, 213, 255)';\nvar highlightStroke = '#4572d9';\nvar highlightFill = 'rgb(223, 234, 255)';\nvar colorSet = {\n // for nodes\n mainStroke: global_subjectColor,\n mainFill: nodeMainFill,\n activeStroke: global_subjectColor,\n activeFill: activeFill,\n inactiveStroke: inactiveStroke,\n inactiveFill: activeFill,\n selectedStroke: global_subjectColor,\n selectedFill: global_backColor,\n highlightStroke: highlightStroke,\n highlightFill: highlightFill,\n disableStroke: edgeMainStroke,\n disableFill: disabledFill,\n // for edges\n edgeMainStroke: edgeMainStroke,\n edgeActiveStroke: global_subjectColor,\n edgeInactiveStroke: edgeInactiveStroke,\n edgeSelectedStroke: global_subjectColor,\n edgeHighlightStroke: global_subjectColor,\n edgeDisableStroke: edgeDisablesStroke,\n // for combos\n comboMainStroke: edgeMainStroke,\n comboMainFill: comboFill,\n comboActiveStroke: global_subjectColor,\n comboActiveFill: activeFill,\n comboInactiveStroke: edgeMainStroke,\n comboInactiveFill: comboFill,\n comboSelectedStroke: global_subjectColor,\n comboSelectedFill: comboFill,\n comboHighlightStroke: highlightStroke,\n comboHighlightFill: comboFill,\n comboDisableStroke: edgeInactiveStroke,\n comboDisableFill: disabledFill\n};\n/* harmony default export */ var global = ({\n version: '0.4.1',\n rootContainerClassName: 'root-container',\n nodeContainerClassName: 'node-container',\n edgeContainerClassName: 'edge-container',\n comboContainerClassName: 'combo-container',\n delegateContainerClassName: 'delegate-container',\n defaultLoopPosition: 'top',\n nodeLabel: {\n style: {\n fill: '#000',\n fontSize: 12,\n textAlign: 'center',\n textBaseline: 'middle'\n },\n offset: 4 // 节点的默认文本不居中时的偏移量\n\n },\n defaultNode: {\n type: 'circle',\n style: {\n lineWidth: 1,\n stroke: colorSet.mainStroke,\n fill: nodeMainFill\n },\n size: 20,\n color: colorSet.mainStroke,\n linkPoints: {\n size: 8,\n lineWidth: 1,\n fill: colorSet.activeFill,\n stroke: colorSet.activeStroke\n }\n },\n // 节点应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展\n nodeStateStyles: {\n active: {\n fill: colorSet.activeFill,\n stroke: colorSet.activeStroke,\n lineWidth: 2,\n shadowColor: colorSet.mainStroke,\n shadowBlur: 10\n },\n selected: {\n fill: colorSet.selectedFill,\n stroke: colorSet.selectedStroke,\n lineWidth: 4,\n shadowColor: colorSet.selectedStroke,\n shadowBlur: 10,\n 'text-shape': {\n fontWeight: 500\n }\n },\n highlight: {\n fill: colorSet.highlightFill,\n stroke: colorSet.highlightStroke,\n lineWidth: 2,\n 'text-shape': {\n fontWeight: 500\n }\n },\n inactive: {\n fill: colorSet.inactiveFill,\n stroke: colorSet.inactiveStroke,\n lineWidth: 1\n },\n disable: {\n fill: colorSet.disableFill,\n stroke: colorSet.disableStroke,\n lineWidth: 1\n }\n },\n edgeLabel: {\n style: {\n fill: global_textColor,\n textAlign: 'center',\n textBaseline: 'middle',\n fontSize: 12\n }\n },\n defaultEdge: {\n type: 'line',\n size: 1,\n style: {\n stroke: colorSet.edgeMainStroke,\n lineAppendWidth: 2\n },\n color: colorSet.edgeMainStroke\n },\n // 边应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展\n edgeStateStyles: {\n active: {\n stroke: colorSet.edgeActiveStroke,\n lineWidth: 1\n },\n selected: {\n stroke: colorSet.edgeSelectedStroke,\n lineWidth: 2,\n shadowColor: colorSet.edgeSelectedStroke,\n shadowBlur: 10,\n 'text-shape': {\n fontWeight: 500\n }\n },\n highlight: {\n stroke: colorSet.edgeHighlightStroke,\n lineWidth: 2,\n 'text-shape': {\n fontWeight: 500\n }\n },\n inactive: {\n stroke: colorSet.edgeInactiveStroke,\n lineWidth: 1\n },\n disable: {\n stroke: colorSet.edgeDisableStroke,\n lineWidth: 1\n }\n },\n comboLabel: {\n style: {\n fill: global_textColor,\n // textAlign: 'center',\n textBaseline: 'middle',\n fontSize: 12\n },\n refY: 10,\n refX: 10 // Combo 的默认文本不居中时的偏移量\n\n },\n defaultCombo: {\n type: 'circle',\n style: {\n fill: colorSet.comboMainFill,\n lineWidth: 1,\n stroke: colorSet.comboMainStroke,\n r: 5,\n width: 20,\n height: 10\n },\n size: [20, 5],\n color: colorSet.comboMainStroke,\n padding: [25, 20, 15, 20]\n },\n // combo 应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展\n comboStateStyles: {\n active: {\n stroke: colorSet.comboActiveStroke,\n lineWidth: 1,\n fill: colorSet.comboActiveFill\n },\n selected: {\n stroke: colorSet.comboSelectedStroke,\n lineWidth: 2,\n fill: colorSet.comboSelectedFill,\n shadowColor: colorSet.comboSelectedStroke,\n shadowBlur: 10,\n 'text-shape': {\n fontWeight: 500\n }\n },\n highlight: {\n stroke: colorSet.comboHighlightStroke,\n lineWidth: 2,\n fill: colorSet.comboHighlightFill,\n 'text-shape': {\n fontWeight: 500\n }\n },\n inactive: {\n stroke: colorSet.comboInactiveStroke,\n fill: colorSet.comboInactiveFill,\n lineWidth: 1\n },\n disable: {\n stroke: colorSet.comboDisableStroke,\n fill: colorSet.comboDisableFill,\n lineWidth: 1\n }\n },\n delegateStyle: {\n fill: '#F3F9FF',\n fillOpacity: 0.5,\n stroke: '#1890FF',\n strokeOpacity: 0.9,\n lineDash: [5, 5]\n },\n windowFontFamily: typeof window !== 'undefined' && window.getComputedStyle ? window.getComputedStyle(document.body, null).getPropertyValue('font-family') || 'Arial, sans-serif' : 'Arial, sans-serif'\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/letterAspectRatio.js\n/* harmony default export */ var letterAspectRatio = ({\n ' ': 0.3329986572265625,\n a: 0.5589996337890625,\n A: 0.6569992065429687,\n b: 0.58599853515625,\n B: 0.6769989013671875,\n c: 0.5469985961914062,\n C: 0.7279998779296875,\n d: 0.58599853515625,\n D: 0.705999755859375,\n e: 0.554998779296875,\n E: 0.63699951171875,\n f: 0.37299957275390627,\n F: 0.5769989013671875,\n g: 0.5909988403320312,\n G: 0.7479995727539063,\n h: 0.555999755859375,\n H: 0.7199996948242188,\n i: 0.255999755859375,\n I: 0.23699951171875,\n j: 0.26699981689453123,\n J: 0.5169998168945312,\n k: 0.5289993286132812,\n K: 0.6899993896484375,\n l: 0.23499908447265624,\n L: 0.5879989624023437,\n m: 0.854998779296875,\n M: 0.8819992065429687,\n n: 0.5589996337890625,\n N: 0.7189987182617188,\n o: 0.58599853515625,\n O: 0.7669998168945312,\n p: 0.58599853515625,\n P: 0.6419998168945312,\n q: 0.58599853515625,\n Q: 0.7669998168945312,\n r: 0.3649993896484375,\n R: 0.6759994506835938,\n s: 0.504998779296875,\n S: 0.6319992065429687,\n t: 0.354998779296875,\n T: 0.6189987182617187,\n u: 0.5599990844726562,\n U: 0.7139999389648437,\n v: 0.48199920654296874,\n V: 0.6389999389648438,\n w: 0.754998779296875,\n W: 0.929998779296875,\n x: 0.5089996337890625,\n X: 0.63699951171875,\n y: 0.4959991455078125,\n Y: 0.66199951171875,\n z: 0.48699951171875,\n Z: 0.6239990234375,\n '0': 0.6,\n '1': 0.40099945068359377,\n '2': 0.6,\n '3': 0.6,\n '4': 0.6,\n '5': 0.6,\n '6': 0.6,\n '7': 0.5469985961914062,\n '8': 0.6,\n '9': 0.6,\n '[': 0.3329986572265625,\n ']': 0.3329986572265625,\n ',': 0.26399993896484375,\n '.': 0.26399993896484375,\n ';': 0.26399993896484375,\n ':': 0.26399993896484375,\n '{': 0.3329986572265625,\n '}': 0.3329986572265625,\n '\\\\': 0.5,\n '|': 0.19499969482421875,\n '=': 0.604998779296875,\n '+': 0.604998779296875,\n '-': 0.604998779296875,\n _: 0.5,\n '`': 0.3329986572265625,\n ' ~': 0.8329986572265625,\n '!': 0.3329986572265625,\n '@': 0.8579986572265625,\n '#': 0.6,\n $: 0.6,\n '%': 0.9699996948242188,\n '^': 0.517999267578125,\n '&': 0.7259994506835937,\n '*': 0.505999755859375,\n '(': 0.3329986572265625,\n ')': 0.3329986572265625,\n '<': 0.604998779296875,\n '>': 0.604998779296875,\n '/': 0.5,\n '?': 0.53699951171875\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/graphic.js\n\n\n\n\n\n\nvar PI = Math.PI,\n sin = Math.sin,\n cos = Math.cos; // 一共支持8个方向的自环,每个环占的角度是45度,在计算时再二分,为22.5度\n\nvar SELF_LINK_SIN = sin(PI / 8);\nvar SELF_LINK_COS = cos(PI / 8);\nvar graphic_getBBox = function getBBox(element, group) {\n var bbox = element.getBBox();\n var leftTop = {\n x: bbox.minX,\n y: bbox.minY\n };\n var rightBottom = {\n x: bbox.maxX,\n y: bbox.maxY\n }; // 根据父元素变换矩阵\n\n if (group) {\n var matrix = group.getMatrix();\n\n if (!matrix) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n leftTop = math_applyMatrix(leftTop, matrix);\n rightBottom = math_applyMatrix(rightBottom, matrix);\n }\n\n var lx = leftTop.x,\n ly = leftTop.y;\n var rx = rightBottom.x,\n ry = rightBottom.y;\n return {\n x: lx,\n y: ly,\n minX: lx,\n minY: ly,\n maxX: rx,\n maxY: ry,\n width: rx - lx,\n height: ry - ly\n };\n};\n/**\n * get loop edge config\n * @param cfg edge config\n */\n\nvar graphic_getLoopCfgs = function getLoopCfgs(cfg) {\n var item = cfg.sourceNode || cfg.targetNode;\n var container = item.get('group');\n var containerMatrix = container.getMatrix();\n if (!containerMatrix) containerMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n var keyShape = item.getKeyShape();\n var bbox = keyShape.getBBox();\n var loopCfg = cfg.loopCfg || {}; // 距离keyShape边的最高距离\n\n var dist = loopCfg.dist || Math.max(bbox.width, bbox.height) * 2; // 自环边与keyShape的相对位置关系\n\n var position = loopCfg.position || global.defaultLoopPosition; // 中心取group上真实位置\n\n var center = [containerMatrix[6], containerMatrix[7]];\n var startPoint = [cfg.startPoint.x, cfg.startPoint.y];\n var endPoint = [cfg.endPoint.x, cfg.endPoint.y];\n var rstart = bbox.height / 2;\n var rend = bbox.height / 2;\n var sinDeltaStart = rstart * SELF_LINK_SIN;\n var cosDeltaStart = rstart * SELF_LINK_COS;\n var sinDeltaEnd = rend * SELF_LINK_SIN;\n var cosDeltaEnd = rend * SELF_LINK_COS; // 如果定义了锚点的,直接用锚点坐标,否则,根据自环的 cfg 计算\n\n if (startPoint[0] === endPoint[0] && startPoint[1] === endPoint[1]) {\n switch (position) {\n case 'top':\n startPoint = [center[0] - sinDeltaStart, center[1] - cosDeltaStart];\n endPoint = [center[0] + sinDeltaEnd, center[1] - cosDeltaEnd];\n break;\n\n case 'top-right':\n rstart = bbox.height / 2;\n rend = bbox.width / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] + sinDeltaStart, center[1] - cosDeltaStart];\n endPoint = [center[0] + cosDeltaEnd, center[1] - sinDeltaEnd];\n break;\n\n case 'right':\n rstart = bbox.width / 2;\n rend = bbox.width / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] + cosDeltaStart, center[1] - sinDeltaStart];\n endPoint = [center[0] + cosDeltaEnd, center[1] + sinDeltaEnd];\n break;\n\n case 'bottom-right':\n rstart = bbox.width / 2;\n rend = bbox.height / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] + cosDeltaStart, center[1] + sinDeltaStart];\n endPoint = [center[0] + sinDeltaEnd, center[1] + cosDeltaEnd];\n break;\n\n case 'bottom':\n rstart = bbox.height / 2;\n rend = bbox.height / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] + sinDeltaStart, center[1] + cosDeltaStart];\n endPoint = [center[0] - sinDeltaEnd, center[1] + cosDeltaEnd];\n break;\n\n case 'bottom-left':\n rstart = bbox.height / 2;\n rend = bbox.width / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] - sinDeltaStart, center[1] + cosDeltaStart];\n endPoint = [center[0] - cosDeltaEnd, center[1] + sinDeltaEnd];\n break;\n\n case 'left':\n rstart = bbox.width / 2;\n rend = bbox.width / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] - cosDeltaStart, center[1] + sinDeltaStart];\n endPoint = [center[0] - cosDeltaEnd, center[1] - sinDeltaEnd];\n break;\n\n case 'top-left':\n rstart = bbox.width / 2;\n rend = bbox.height / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] - cosDeltaStart, center[1] - sinDeltaStart];\n endPoint = [center[0] - sinDeltaEnd, center[1] - cosDeltaEnd];\n break;\n\n default:\n rstart = bbox.width / 2;\n rend = bbox.width / 2;\n sinDeltaStart = rstart * SELF_LINK_SIN;\n cosDeltaStart = rstart * SELF_LINK_COS;\n sinDeltaEnd = rend * SELF_LINK_SIN;\n cosDeltaEnd = rend * SELF_LINK_COS;\n startPoint = [center[0] - sinDeltaStart, center[1] - cosDeltaStart];\n endPoint = [center[0] + sinDeltaEnd, center[1] - cosDeltaEnd];\n } // 如果逆时针画,交换起点和终点\n\n\n if (loopCfg.clockwise === false) {\n var swap = [startPoint[0], startPoint[1]];\n startPoint = [endPoint[0], endPoint[1]];\n endPoint = [swap[0], swap[1]];\n }\n }\n\n var startVec = [startPoint[0] - center[0], startPoint[1] - center[1]];\n var scaleRateStart = (rstart + dist) / rstart;\n var scaleRateEnd = (rend + dist) / rend;\n\n if (loopCfg.clockwise === false) {\n scaleRateStart = (rend + dist) / rend;\n scaleRateEnd = (rstart + dist) / rstart;\n }\n\n var startExtendVec = matrix_util_esm[\"vec2\"].scale([0, 0], startVec, scaleRateStart);\n var controlPoint1 = [center[0] + startExtendVec[0], center[1] + startExtendVec[1]];\n var endVec = [endPoint[0] - center[0], endPoint[1] - center[1]];\n var endExtendVec = matrix_util_esm[\"vec2\"].scale([0, 0], endVec, scaleRateEnd);\n var controlPoint2 = [center[0] + endExtendVec[0], center[1] + endExtendVec[1]];\n cfg.startPoint = {\n x: startPoint[0],\n y: startPoint[1]\n };\n cfg.endPoint = {\n x: endPoint[0],\n y: endPoint[1]\n };\n cfg.controlPoints = [{\n x: controlPoint1[0],\n y: controlPoint1[1]\n }, {\n x: controlPoint2[0],\n y: controlPoint2[1]\n }];\n return cfg;\n};\n/**\n * 根据 label 所在线条的位置百分比,计算 label 坐标\n * @param {object} pathShape G 的 path 实例,一般是 Edge 实例的 keyShape\n * @param {number} percent 范围 0 - 1 的线条百分比\n * @param {number} refX x 轴正方向为基准的 label 偏移\n * @param {number} refY y 轴正方向为基准的 label 偏移\n * @param {boolean} rotate 是否根据线条斜率旋转文本\n * @return {object} 文本的 x, y, 文本的旋转角度\n */\n\nvar graphic_getLabelPosition = function getLabelPosition(pathShape, percent, refX, refY, rotate) {\n var TAN_OFFSET = 0.0001;\n var vector = [];\n var point = pathShape === null || pathShape === void 0 ? void 0 : pathShape.getPoint(percent);\n\n if (!point) {\n return {\n x: 0,\n y: 0,\n angle: 0\n };\n } // 头尾最可能,放在最前面,使用 g path 上封装的方法\n\n\n if (percent < TAN_OFFSET) {\n vector = pathShape.getStartTangent().reverse();\n } else if (percent > 1 - TAN_OFFSET) {\n vector = pathShape.getEndTangent();\n } else {\n // 否则取指定位置的点,与少量偏移的点,做微分向量\n var offsetPoint = pathShape === null || pathShape === void 0 ? void 0 : pathShape.getPoint(percent + TAN_OFFSET);\n vector.push([point.x, point.y]);\n vector.push([offsetPoint.x, offsetPoint.y]);\n }\n\n var rad = Math.atan2(vector[1][1] - vector[0][1], vector[1][0] - vector[0][0]);\n\n if (rad < 0) {\n rad += PI * 2;\n }\n\n if (refX) {\n point.x += cos(rad) * refX;\n point.y += sin(rad) * refX;\n }\n\n if (refY) {\n // 默认方向是 x 轴正方向,法线是 求出角度 - 90°\n var normal = rad - PI / 2; // 若法线角度在 y 轴负方向,切到正方向,保证 refY 相对于 y 轴正方向\n\n if (rad > 1 / 2 * PI && rad < 3 * 1 / 2 * PI) {\n normal -= PI;\n }\n\n point.x += cos(normal) * refY;\n point.y += sin(normal) * refY;\n }\n\n var result = {\n x: point.x,\n y: point.y,\n angle: rad\n };\n\n if (rotate) {\n if (rad > 0.5 * PI && rad < 1.5 * PI) {\n rad -= PI;\n }\n\n return Object(tslib_es6[\"__assign\"])({\n rotate: rad\n }, result);\n }\n\n return result;\n};\n/**\n * depth first traverse, from root to leaves, children in inverse order\n * if the fn returns false, terminate the traverse\n */\n\nvar graphic_traverse = function traverse(data, fn) {\n if (fn(data) === false) {\n return false;\n }\n\n if (data && data.children) {\n for (var i = data.children.length - 1; i >= 0; i--) {\n if (!traverse(data.children[i], fn)) return false;\n }\n }\n\n return true;\n};\n/**\n * depth first traverse, from leaves to root, children in inverse order\n * if the fn returns false, terminate the traverse\n */\n\n\nvar traverseUp = function traverseUp(data, fn) {\n if (data && data.children) {\n for (var i = data.children.length - 1; i >= 0; i--) {\n if (!traverseUp(data.children[i], fn)) return;\n }\n }\n\n if (fn(data) === false) {\n return false;\n }\n\n return true;\n};\n/**\n * depth first traverse, from root to leaves, children in inverse order\n * if the fn returns false, terminate the traverse\n */\n\n\nvar traverseTree = function traverseTree(data, fn) {\n if (typeof fn !== 'function') {\n return;\n }\n\n graphic_traverse(data, fn);\n};\n/**\n * depth first traverse, from leaves to root, children in inverse order\n * if the fn returns false, terminate the traverse\n */\n\nvar traverseTreeUp = function traverseTreeUp(data, fn) {\n if (typeof fn !== 'function') {\n return;\n }\n\n traverseUp(data, fn);\n};\n/**\n *\n * @param letter the letter\n * @param fontSize\n * @return the letter's width\n */\n\nvar graphic_getLetterWidth = function getLetterWidth(letter, fontSize) {\n return fontSize * (letterAspectRatio[letter] || 1);\n};\n/**\n *\n * @param text the text\n * @param fontSize\n * @return the text's size\n */\n\nvar getTextSize = function getTextSize(text, fontSize) {\n var width = 0;\n var pattern = new RegExp(\"[\\u4E00-\\u9FA5]+\");\n text.split('').forEach(function (letter) {\n if (pattern.test(letter)) {\n // 中文字符\n width += fontSize;\n } else {\n width += graphic_getLetterWidth(letter, fontSize);\n }\n });\n return [width, fontSize];\n};\n/**\n * construct the trees from combos data\n * @param array the combos array\n * @param nodes the nodes array\n * @return the tree\n */\n\nvar graphic_plainCombosToTrees = function plainCombosToTrees(array, nodes) {\n var result = [];\n var addedMap = {};\n var modelMap = {};\n array.forEach(function (d) {\n modelMap[d.id] = d;\n });\n array.forEach(function (d, i) {\n var cd = Object(esm[\"clone\"])(d);\n cd.itemType = 'combo';\n cd.children = undefined;\n\n if (cd.parentId === cd.id) {\n console.warn(\"The parentId for combo \" + cd.id + \" can not be the same as the combo's id\");\n delete cd.parentId;\n } else if (cd.parentId && !modelMap[cd.parentId]) {\n console.warn(\"The parent combo for combo \" + cd.id + \" does not exist!\");\n delete cd.parentId;\n }\n\n var mappedObj = addedMap[cd.id];\n\n if (mappedObj) {\n cd.children = mappedObj.children;\n addedMap[cd.id] = cd;\n mappedObj = cd;\n\n if (!mappedObj.parentId) {\n result.push(mappedObj);\n return;\n }\n\n var mappedParent = addedMap[mappedObj.parentId];\n\n if (mappedParent) {\n if (mappedParent.children) mappedParent.children.push(cd);else mappedParent.children = [cd];\n } else {\n var parent_1 = {\n id: mappedObj.parentId,\n children: [mappedObj]\n };\n addedMap[mappedObj.parentId] = parent_1;\n addedMap[cd.id] = cd;\n }\n\n return;\n }\n\n if (Object(esm[\"isString\"])(d.parentId)) {\n var parent_2 = addedMap[d.parentId];\n\n if (parent_2) {\n if (parent_2.children) parent_2.children.push(cd);else parent_2.children = [cd];\n addedMap[cd.id] = cd;\n } else {\n var pa = {\n id: d.parentId,\n children: [cd]\n };\n addedMap[pa.id] = pa;\n addedMap[cd.id] = cd;\n }\n } else {\n result.push(cd);\n addedMap[cd.id] = cd;\n }\n }); // proccess the nodes\n\n var nodeMap = {};\n (nodes || []).forEach(function (node) {\n nodeMap[node.id] = node;\n var combo = addedMap[node.comboId];\n\n if (combo) {\n var cnode = {\n id: node.id,\n comboId: node.comboId\n };\n if (combo.children) combo.children.push(cnode);else combo.children = [cnode];\n cnode.itemType = 'node';\n addedMap[node.id] = cnode;\n }\n }); // assign the depth for each element\n\n var maxDepth = 0;\n result.forEach(function (tree) {\n tree.depth = maxDepth + 10;\n graphic_traverse(tree, function (child) {\n var parent;\n var itemType = addedMap[child.id].itemType;\n\n if (itemType === 'node') {\n parent = addedMap[child.comboId];\n } else {\n parent = addedMap[child.parentId];\n }\n\n if (parent) {\n if (itemType === 'node') child.depth = maxDepth + 1;else child.depth = maxDepth + 10;\n } else {\n child.depth = maxDepth + 10;\n }\n\n if (maxDepth < child.depth) maxDepth = child.depth;\n var oriNodeModel = nodeMap[child.id];\n\n if (oriNodeModel) {\n oriNodeModel.depth = child.depth;\n }\n\n return true;\n });\n });\n return result;\n};\nvar reconstructTree = function reconstructTree(trees, subtreeId, newParentId) {\n var brothers = trees;\n var subtree;\n var comboChildsMap = {\n root: {\n children: trees\n }\n };\n var foundSubTree = false;\n var oldParentId = 'root';\n (trees || []).forEach(function (tree) {\n if (foundSubTree) return;\n\n if (tree.id === subtreeId) {\n subtree = tree;\n\n if (tree.itemType === 'combo') {\n subtree.parentId = newParentId;\n } else {\n subtree.comboId = newParentId;\n }\n\n foundSubTree = true;\n return;\n }\n\n traverseTree(tree, function (child) {\n comboChildsMap[child.id] = {\n children: child.children\n }; // store the old parent id to delete the subtree from the old parent's children in next recursion\n\n brothers = comboChildsMap[child.parentId || child.comboId || 'root'].children;\n\n if (child && (child.removed || subtreeId === child.id) && brothers) {\n oldParentId = child.parentId || child.comboId || 'root';\n subtree = child; // re-assign the parentId or comboId for the moved subtree\n\n if (child.itemType === 'combo') {\n subtree.parentId = newParentId;\n } else {\n subtree.comboId = newParentId;\n }\n\n foundSubTree = true;\n return false;\n }\n\n return true;\n });\n });\n brothers = comboChildsMap[oldParentId].children;\n var index = brothers ? brothers.indexOf(subtree) : -1;\n if (index > -1) brothers.splice(index, 1); // 如果遍历完整棵树还没有找到,说明之前就不在树中\n\n if (!foundSubTree) {\n subtree = {\n id: subtreeId,\n itemType: 'node',\n comboId: newParentId\n };\n comboChildsMap[subtreeId] = {\n children: undefined\n };\n } // append to new parent\n\n\n if (subtreeId) {\n var found_1 = false; // newParentId is undefined means the subtree will have no parent\n\n if (newParentId) {\n var newParentDepth_1 = 0;\n (trees || []).forEach(function (tree) {\n if (found_1) return; // terminate\n\n traverseTree(tree, function (child) {\n // append subtree to the new parent ans assign the depth to the subtree\n if (newParentId === child.id) {\n found_1 = true;\n if (child.children) child.children.push(subtree);else child.children = [subtree];\n newParentDepth_1 = child.depth;\n if (subtree.itemType === 'node') subtree.depth = newParentDepth_1 + 2;else subtree.depth = newParentDepth_1 + 1;\n return false; // terminate\n }\n\n return true;\n });\n });\n } else if ((!newParentId || !found_1) && subtree.itemType !== 'node') {\n // if the newParentId is undefined or it is not found in the tree, add the subTree to the root\n trees.push(subtree);\n } // update the depth of the subtree and its children from the subtree\n\n\n var currentDepth_1 = subtree.depth;\n traverseTree(subtree, function (child) {\n if (child.itemType === 'node') currentDepth_1 += 2;else currentDepth_1 += 1;\n child.depth = currentDepth_1;\n return true;\n });\n }\n\n return trees;\n};\nvar getComboBBox = function getComboBBox(children, graph) {\n var comboBBox = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n x: undefined,\n y: undefined,\n width: undefined,\n height: undefined,\n centerX: undefined,\n centerY: undefined\n };\n\n if (!children || children.length === 0) {\n return comboBBox;\n }\n\n children.forEach(function (child) {\n var childItem = graph.findById(child.id);\n if (!childItem || !childItem.isVisible()) return; // ignore hidden children\n\n childItem.set('bboxCanvasCache', undefined);\n var childBBox = childItem.getCanvasBBox();\n if (childBBox.x && comboBBox.minX > childBBox.minX) comboBBox.minX = childBBox.minX;\n if (childBBox.y && comboBBox.minY > childBBox.minY) comboBBox.minY = childBBox.minY;\n if (childBBox.x && comboBBox.maxX < childBBox.maxX) comboBBox.maxX = childBBox.maxX;\n if (childBBox.y && comboBBox.maxY < childBBox.maxY) comboBBox.maxY = childBBox.maxY;\n });\n comboBBox.x = (comboBBox.minX + comboBBox.maxX) / 2;\n comboBBox.y = (comboBBox.minY + comboBBox.maxY) / 2;\n comboBBox.width = comboBBox.maxX - comboBBox.minX;\n comboBBox.height = comboBBox.maxY - comboBBox.minY;\n comboBBox.centerX = (comboBBox.minX + comboBBox.maxX) / 2;\n comboBBox.centerY = (comboBBox.minY + comboBBox.maxY) / 2;\n Object.keys(comboBBox).forEach(function (key) {\n if (comboBBox[key] === Infinity || comboBBox[key] === -Infinity) {\n comboBBox[key] = undefined;\n }\n });\n return comboBBox;\n};\nvar graphic_shouldRefreshEdge = function shouldRefreshEdge(cfg) {\n var refreshEdge = Object(esm[\"isNumber\"])(cfg.x) || Object(esm[\"isNumber\"])(cfg.y) || cfg.type || cfg.anchorPoints || cfg.size;\n if (cfg.style) refreshEdge = refreshEdge || Object(esm[\"isNumber\"])(cfg.style.r) || Object(esm[\"isNumber\"])(cfg.style.width) || Object(esm[\"isNumber\"])(cfg.style.height) || Object(esm[\"isNumber\"])(cfg.style.rx) || Object(esm[\"isNumber\"])(cfg.style.ry);\n return refreshEdge;\n};\nvar graphic_cloneBesidesImg = function cloneBesidesImg(obj) {\n var clonedObj = {};\n Object.keys(obj).forEach(function (key1) {\n var obj2 = obj[key1];\n\n if (Object(esm[\"isObject\"])(obj2) && !Object(esm[\"isArray\"])(obj2)) {\n var clonedObj2_1 = {};\n Object.keys(obj2).forEach(function (key2) {\n var v = obj2[key2];\n if (key2 === 'img' && !Object(esm[\"isString\"])(v)) return;\n clonedObj2_1[key2] = Object(esm[\"clone\"])(v);\n });\n clonedObj[key1] = clonedObj2_1;\n } else {\n clonedObj[key1] = Object(esm[\"clone\"])(obj2);\n }\n });\n return clonedObj;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/validation.js\n\n\n\n/**\n * 验证关系图或树图数据的合法性,必须符合以下规则才会渲染图:\n * 1. 必须传入数据\n * 2. 节点的 ID 必须为字符串,暂不支持数字类型,如果支持数字类型,会出现类似 123 与 '123' 是否相等的问题\n * 3. 边的 source 和 target 值必须在节点 ID 中存在\n * @param data 关系图或树图数据\n * @return boolean 全部验证通过返回 true,否则返回 false\n */\n\nvar validation_dataValidation = function dataValidation(data) {\n var _a; // 1. 必须传入数据\n\n\n if (!data) {\n console.error('G6 Error Tips: the data must be defined');\n return false;\n } // 2. 节点的 ID 必须为字符串或数字类型\n\n\n var nodes = data.nodes,\n edges = data.edges,\n _b = data.combos,\n combos = _b === void 0 ? [] : _b;\n\n if (!nodes && !edges) {\n var validated_1 = true; // 不存在 nodes 和 edges,则说明是 TreeGraphData,按 TreeGraphData 规则验证\n\n traverseTree(data, function (param) {\n if (!Object(esm[\"isString\"])(param.id)) {\n validated_1 = false;\n return false;\n }\n\n return true;\n });\n return validated_1;\n }\n\n var nonNode = (nodes || []).find(function (node) {\n return !Object(esm[\"isString\"])(node.id);\n });\n\n if (nonNode) {\n console.warn(\"G6 Warning Tips: missing 'id' property, or %c\" + nonNode.id + \"%c is not a string.\", 'font-size: 20px; color: red;', '');\n return false;\n } // 3. 边的 source 和 target 必须存在于节点 或 Combo中\n\n\n var nodeIds = (nodes || []).map(function (node) {\n return node.id;\n });\n var comboIds = (_a = combos) === null || _a === void 0 ? void 0 : _a.map(function (combo) {\n return combo.id;\n });\n\n var ids = Object(tslib_es6[\"__spreadArray\"])(Object(tslib_es6[\"__spreadArray\"])([], nodeIds, true), comboIds, true);\n\n var nonEdges = (edges || []).find(function (edge) {\n return !ids.includes(edge.source) || !ids.includes(edge.target);\n });\n\n if (nonEdges) {\n console.warn(\"G6 Warning Tips: The source %c\" + nonEdges.source + \"%c or the target %c\" + nonEdges.target + \"%c of the edge do not exist in the nodes or combos.\", 'font-size: 20px; color: red;', '', 'font-size: 20px; color: red;', '');\n return false;\n }\n\n return true;\n};\n/**\n * 验证添加节点、边或从combo时的数据\n * @param type 节点、边或从combo\n * @param data 添加的单条数据\n * @return boolean 全部验证通过返回 true,否则返回 false\n */\n\nvar validation_singleDataValidation = function singleDataValidation(type, data) {\n if (type === 'node' || type === 'combo') {\n // 必须有 id 字段,且id必须为字符串类型\n if (data.id && !Object(esm[\"isString\"])(data.id)) {\n console.warn(\"G6 Warning Tips: missing 'id' property, or the 'id' %c\" + data.id + \"%c is not a string.\", 'font-size: 20px; color: red;', '');\n return false;\n }\n } else if (type === 'edge') {\n // 必须有 source 和 target 字段\n if (!data.source || !data.target) {\n console.warn(\"G6 Warning Tips: missing 'source' or 'target' for the edge.\");\n return false;\n }\n }\n\n return true;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/mode.js\n\n\n\nvar mode_ModeController =\n/** @class */\nfunction () {\n function ModeController(graph) {\n this.graph = graph;\n this.destroyed = false;\n this.modes = graph.get('modes') || {\n default: []\n };\n this.formatModes();\n this.mode = graph.get('defaultMode') || 'default';\n this.currentBehaves = [];\n this.setMode(this.mode);\n }\n\n ModeController.prototype.formatModes = function () {\n var modes = this.modes;\n Object(esm[\"each\"])(modes, function (mode) {\n Object(esm[\"each\"])(mode, function (behavior, i) {\n if (Object(esm[\"isString\"])(behavior)) {\n mode[i] = {\n type: behavior\n };\n }\n });\n });\n };\n\n ModeController.prototype.setBehaviors = function (mode) {\n var graph = this.graph;\n var behaviors = this.modes[mode];\n var behaves = [];\n var behave;\n Object(esm[\"each\"])(behaviors || [], function (behavior) {\n var BehaviorInstance = behavior_behavior.getBehavior(behavior.type || behavior);\n\n if (!BehaviorInstance) {\n return;\n }\n\n behave = new BehaviorInstance(behavior);\n\n if (behave) {\n behave.bind(graph);\n behaves.push(behave);\n }\n });\n this.currentBehaves = behaves;\n };\n\n ModeController.mergeBehaviors = function (modeBehaviors, behaviors) {\n Object(esm[\"each\"])(behaviors, function (behavior) {\n if (modeBehaviors.indexOf(behavior) < 0) {\n if (Object(esm[\"isString\"])(behavior)) {\n behavior = {\n type: behavior\n };\n }\n\n modeBehaviors.push(behavior);\n }\n });\n return modeBehaviors;\n };\n\n ModeController.filterBehaviors = function (modeBehaviors, behaviors) {\n var result = [];\n modeBehaviors.forEach(function (behavior) {\n var type = '';\n\n if (Object(esm[\"isString\"])(behavior)) {\n type = behavior;\n } else {\n // eslint-disable-next-line prefer-destructuring\n type = behavior.type;\n }\n\n if (behaviors.indexOf(type) < 0) {\n result.push(behavior);\n }\n });\n return result;\n };\n\n ModeController.prototype.setMode = function (mode) {\n var _a = this,\n modes = _a.modes,\n graph = _a.graph;\n\n var current = mode;\n var behaviors = modes[current];\n\n if (!behaviors) {\n return;\n }\n\n graph.emit('beforemodechange', {\n mode: mode\n });\n Object(esm[\"each\"])(this.currentBehaves, function (behave) {\n if (behave.delegate) behave.delegate.remove();\n behave.unbind(graph);\n });\n this.setBehaviors(current);\n graph.emit('aftermodechange', {\n mode: mode\n });\n this.mode = mode;\n };\n\n ModeController.prototype.getMode = function () {\n return this.mode;\n };\n /**\n * 动态增加或删除 Behavior\n *\n * @param {ModeType[]} behaviors\n * @param {(ModeType[] | ModeType)} modes\n * @param {boolean} isAdd\n * @returns {Mode}\n * @memberof Mode\n */\n\n\n ModeController.prototype.manipulateBehaviors = function (behaviors, modes, isAdd) {\n var _this = this;\n\n var behaves;\n\n if (!Object(esm[\"isArray\"])(behaviors)) {\n behaves = [behaviors];\n } else {\n behaves = behaviors;\n }\n\n if (Object(esm[\"isArray\"])(modes)) {\n Object(esm[\"each\"])(modes, function (mode) {\n if (!_this.modes[mode]) {\n if (isAdd) {\n _this.modes[mode] = behaves;\n }\n } else if (isAdd) {\n _this.modes[mode] = ModeController.mergeBehaviors(_this.modes[mode] || [], behaves);\n } else {\n _this.modes[mode] = ModeController.filterBehaviors(_this.modes[mode] || [], behaves);\n }\n });\n return this;\n }\n\n var currentMode = modes;\n\n if (!modes) {\n currentMode = this.mode; // isString(this.mode) ? this.mode : this.mode.type\n }\n\n if (!this.modes[currentMode]) {\n if (isAdd) {\n this.modes[currentMode] = behaves;\n }\n }\n\n if (isAdd) {\n this.modes[currentMode] = ModeController.mergeBehaviors(this.modes[currentMode] || [], behaves);\n } else {\n this.modes[currentMode] = ModeController.filterBehaviors(this.modes[currentMode] || [], behaves);\n }\n\n this.formatModes();\n this.setMode(this.mode);\n return this;\n };\n /**\n * 更新行为参数\n * @param {string | ModeOption | ModeType} behavior 需要更新的行为\n * @param {string | string[]} modes 指定的模式中的行为,不指定则为 default\n * @return {Graph} Graph\n */\n\n\n ModeController.prototype.updateBehavior = function (behavior, newCfg, mode) {\n if (Object(esm[\"isString\"])(behavior)) {\n behavior = {\n type: behavior\n };\n }\n\n var behaviorSet = [];\n\n if (!mode || mode === this.mode || mode === 'default') {\n behaviorSet = this.currentBehaves;\n\n if (!behaviorSet || !behaviorSet.length) {\n console.warn('Update behavior failed! There is no behaviors in this mode on the graph.');\n return this;\n }\n\n var length_1 = behaviorSet.length;\n\n for (var i = 0; i < length_1; i++) {\n var behave = behaviorSet[i];\n\n if (behave.type === behavior.type) {\n behave.updateCfg(newCfg);\n return this;\n }\n\n if (i === length_1 - 1) console.warn('Update behavior failed! There is no such behavior in the mode');\n }\n } else {\n behaviorSet = this.modes[mode];\n\n if (!behaviorSet || !behaviorSet.length) {\n console.warn('Update behavior failed! There is no behaviors in this mode on the graph.');\n return this;\n }\n\n var length_2 = behaviorSet.length;\n\n for (var i = 0; i < length_2; i++) {\n var behave = behaviorSet[i];\n\n if (behave.type === behavior.type || behave === behavior.type) {\n if (behave === behavior.type) behave = {\n type: behave\n };\n Object.assign(behave, newCfg);\n behaviorSet[i] = behave;\n return this;\n }\n\n if (i === length_2 - 1) console.warn('Update behavior failed! There is no such behavior in the mode');\n }\n }\n\n return this;\n };\n\n ModeController.prototype.destroy = function () {\n this.graph = null;\n this.modes = null;\n this.currentBehaves = null;\n this.destroyed = true;\n };\n\n return ModeController;\n}();\n\n/* harmony default export */ var controller_mode = (mode_ModeController);\n// EXTERNAL MODULE: ./node_modules/@antv/g-base/esm/index.js\nvar g_base_esm = __webpack_require__(21);\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/interface/behavior.js\n\n\n\nvar behavior_G6GraphEvent =\n/** @class */\nfunction (_super) {\n Object(tslib_es6[\"__extends\"])(G6GraphEvent, _super);\n\n function G6GraphEvent(type, event) {\n var _this = _super.call(this, type, event) || this;\n\n _this.item = event.item;\n _this.canvasX = event.canvasX;\n _this.canvasY = event.canvasY;\n _this.wheelDelta = event.wheelDelta;\n _this.detail = event.detail;\n return _this;\n }\n\n return G6GraphEvent;\n}(g_base_esm[\"Event\"]);\n\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/base.js\n\n\nvar base_uniqueId = function uniqueId(type) {\n return type + \"-\" + Math.random() + Date.now();\n};\n/**\n * turn padding into [top, right, bottom, right]\n * @param {Number|Array} padding input padding\n * @return {array} output\n */\n\nvar base_formatPadding = function formatPadding(padding) {\n if (Object(esm[\"isArray\"])(padding)) {\n switch (padding.length) {\n case 4:\n return padding;\n\n case 3:\n padding.push(padding[1]);\n return padding;\n\n case 2:\n return padding.concat(padding);\n\n case 1:\n return [padding[0], padding[0], padding[0], padding[0]];\n\n default:\n return [0, 0, 0, 0];\n }\n }\n\n if (Object(esm[\"isNumber\"])(padding)) {\n return [padding, padding, padding, padding];\n } else if (Object(esm[\"isString\"])(padding)) {\n var intPadding = parseInt(padding, 10);\n return [intPadding, intPadding, intPadding, intPadding];\n }\n\n return [0, 0, 0, 0];\n};\n/**\n * clone event\n * @param e\n */\n\nvar base_cloneEvent = function cloneEvent(e) {\n var event = new behavior_G6GraphEvent(e.type, e);\n event.clientX = e.clientX;\n event.clientY = e.clientY;\n event.x = e.x;\n event.y = e.y;\n event.target = e.target;\n event.currentTarget = e.currentTarget;\n event.bubbles = true;\n event.item = e.item;\n return event;\n};\n/**\n * 判断 viewport 是否改变,通过和单位矩阵对比\n * @param matrix Viewport 的 Matrix\n */\n\nvar isViewportChanged = function isViewportChanged(matrix) {\n // matrix 为 null, 则说明没有变化\n if (!matrix) {\n return false;\n }\n\n var MATRIX_LEN = 9;\n var ORIGIN_MATRIX = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\n for (var i = 0; i < MATRIX_LEN; i++) {\n if (matrix[i] !== ORIGIN_MATRIX[i]) {\n return true;\n }\n }\n\n return false;\n};\nvar base_isNaN = function isNaN(input) {\n return Number.isNaN(Number(input));\n};\n/**\n * 计算一组 Item 的 BBox\n * @param items 选中的一组Item,可以是 node 或 combo\n */\n\nvar calculationItemsBBox = function calculationItemsBBox(items) {\n var minx = Infinity;\n var maxx = -Infinity;\n var miny = Infinity;\n var maxy = -Infinity; // 获取已节点的所有最大最小x y值\n\n for (var i = 0; i < items.length; i++) {\n var element = items[i];\n var bbox = element.getBBox();\n var minX = bbox.minX,\n minY = bbox.minY,\n maxX = bbox.maxX,\n maxY = bbox.maxY;\n\n if (minX < minx) {\n minx = minX;\n }\n\n if (minY < miny) {\n miny = minY;\n }\n\n if (maxX > maxx) {\n maxx = maxX;\n }\n\n if (maxY > maxy) {\n maxy = maxY;\n }\n }\n\n var x = Math.floor(minx);\n var y = Math.floor(miny);\n var width = Math.ceil(maxx) - Math.floor(minx);\n var height = Math.ceil(maxy) - Math.floor(miny);\n return {\n x: x,\n y: y,\n width: width,\n height: height,\n minX: minx,\n minY: miny,\n maxX: maxx,\n maxY: maxy\n };\n};\n/**\n * 若 edges 中存在两端点相同的边,使用 quadratic 边并自动计算 curveOffset 使它们不相互重叠\n * 文档: https://g6.antv.vision/en/docs/api/Util\n * @param edges 边数据集合\n * @param offsetDiff 相邻两边的 offset 之差\n * @param multiEdgeType\n * @param singleEdgeType\n * @param loopEdgeType\n */\n\nvar processParallelEdges = function processParallelEdges(edges, offsetDiff, multiEdgeType, singleEdgeType, loopEdgeType) {\n if (offsetDiff === void 0) {\n offsetDiff = 15;\n }\n\n if (multiEdgeType === void 0) {\n multiEdgeType = 'quadratic';\n }\n\n if (singleEdgeType === void 0) {\n singleEdgeType = undefined;\n }\n\n if (loopEdgeType === void 0) {\n loopEdgeType = undefined;\n }\n\n var len = edges.length;\n var cod = offsetDiff * 2;\n var loopPosition = ['top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left'];\n var edgeMap = {};\n var tags = [];\n var reverses = {};\n\n for (var i = 0; i < len; i++) {\n var edge = edges[i];\n var source = edge.source,\n target = edge.target;\n var sourceTarget = source + \"-\" + target;\n if (tags[i]) continue;\n\n if (!edgeMap[sourceTarget]) {\n edgeMap[sourceTarget] = [];\n }\n\n tags[i] = true;\n edgeMap[sourceTarget].push(edge);\n\n for (var j = 0; j < len; j++) {\n if (i === j) continue;\n var sedge = edges[j];\n var src = sedge.source;\n var dst = sedge.target; // 两个节点之间共同的边\n // 第一条的source = 第二条的target\n // 第一条的target = 第二条的source\n\n if (!tags[j]) {\n if (source === dst && target === src) {\n edgeMap[sourceTarget].push(sedge);\n tags[j] = true;\n reverses[src + \"|\" + dst + \"|\" + (edgeMap[sourceTarget].length - 1)] = true;\n } else if (source === src && target === dst) {\n edgeMap[sourceTarget].push(sedge);\n tags[j] = true;\n }\n }\n }\n }\n\n for (var key in edgeMap) {\n var arcEdges = edgeMap[key];\n var length_1 = arcEdges.length;\n\n for (var k = 0; k < length_1; k++) {\n var current = arcEdges[k];\n\n if (current.source === current.target) {\n if (loopEdgeType) current.type = loopEdgeType; // 超过8条自环边,则需要重新处理\n\n current.loopCfg = {\n position: loopPosition[k % 8],\n dist: Math.floor(k / 8) * 20 + 50\n };\n continue;\n }\n\n if (length_1 === 1 && singleEdgeType && current.source !== current.target) {\n current.type = singleEdgeType;\n continue;\n }\n\n current.type = multiEdgeType;\n var sign = (k % 2 === 0 ? 1 : -1) * (reverses[current.source + \"|\" + current.target + \"|\" + k] ? -1 : 1);\n\n if (length_1 % 2 === 1) {\n current.curveOffset = sign * Math.ceil(k / 2) * cod;\n } else {\n current.curveOffset = sign * (Math.floor(k / 2) * cod + offsetDiff);\n }\n }\n }\n\n return edges;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/view.js\n\n\n\n\n\nvar view_ViewController =\n/** @class */\nfunction () {\n function ViewController(graph) {\n this.destroyed = false;\n this.graph = graph;\n this.destroyed = false;\n } // get view center coordinate\n\n\n ViewController.prototype.getViewCenter = function () {\n var padding = this.getFormatPadding();\n var graph = this.graph;\n var width = this.graph.get('width');\n var height = graph.get('height');\n return {\n x: (width - padding[1] - padding[3]) / 2 + padding[3],\n y: (height - padding[0] - padding[2]) / 2 + padding[0]\n };\n };\n\n ViewController.prototype.fitCenter = function () {\n var graph = this.graph;\n var group = graph.get('group');\n group.resetMatrix();\n var bbox = group.getCanvasBBox();\n if (bbox.width === 0 || bbox.height === 0) return;\n var viewCenter = this.getViewCenter();\n var groupCenter = {\n x: bbox.x + bbox.width / 2,\n y: bbox.y + bbox.height / 2\n };\n graph.translate(viewCenter.x - groupCenter.x, viewCenter.y - groupCenter.y);\n }; // fit view graph\n\n\n ViewController.prototype.fitView = function () {\n var graph = this.graph;\n var padding = this.getFormatPadding();\n var width = graph.get('width');\n var height = graph.get('height');\n var group = graph.get('group');\n group.resetMatrix();\n var bbox = group.getCanvasBBox();\n if (bbox.width === 0 || bbox.height === 0) return;\n var viewCenter = this.getViewCenter();\n var groupCenter = {\n x: bbox.x + bbox.width / 2,\n y: bbox.y + bbox.height / 2\n };\n graph.translate(viewCenter.x - groupCenter.x, viewCenter.y - groupCenter.y);\n var w = (width - padding[1] - padding[3]) / bbox.width;\n var h = (height - padding[0] - padding[2]) / bbox.height;\n var ratio = w;\n\n if (w > h) {\n ratio = h;\n }\n\n if (!graph.zoom(ratio, viewCenter)) {\n console.warn('zoom failed, ratio out of range, ratio: %f', ratio);\n }\n }; // fit view graph by rule\n\n\n ViewController.prototype.fitViewByRules = function (rules) {\n var _a = rules.onlyOutOfViewPort,\n onlyOutOfViewPort = _a === void 0 ? false : _a,\n _b = rules.direction,\n direction = _b === void 0 ? 'both' : _b,\n _c = rules.ratioRule,\n ratioRule = _c === void 0 ? 'min' : _c;\n var graph = this.graph;\n var padding = this.getFormatPadding();\n var width = graph.get('width');\n var height = graph.get('height');\n var group = graph.get('group');\n group.resetMatrix();\n var bbox = group.getCanvasBBox();\n if (bbox.width === 0 || bbox.height === 0) return;\n var viewCenter = this.getViewCenter();\n var groupCenter = {\n x: bbox.x + bbox.width / 2,\n y: bbox.y + bbox.height / 2\n };\n graph.translate(viewCenter.x - groupCenter.x, viewCenter.y - groupCenter.y);\n var wRatio = (width - padding[1] - padding[3]) / bbox.width;\n var hRatio = (height - padding[0] - padding[2]) / bbox.height;\n var ratio;\n\n if (direction === 'x') {\n ratio = wRatio;\n } else if (direction === 'y') {\n ratio = hRatio;\n } else {\n // ratioRule\n ratio = ratioRule === 'max' ? Math.max(wRatio, hRatio) : Math.min(wRatio, hRatio);\n } // 如果设置了仅对超出视口宽高的场景进行fitview,则没超出的场景zoom取1\n\n\n if (onlyOutOfViewPort) {\n ratio = ratio < 1 ? ratio : 1;\n }\n\n var initZoomRatio = graph.getZoom();\n var endZoom = initZoomRatio * ratio;\n var minZoom = graph.get('minZoom'); // 如果zoom小于最小zoom, 则以最小zoom为准\n\n if (endZoom < minZoom) {\n endZoom = minZoom;\n console.warn('fitview failed, ratio out of range, ratio: %f', ratio, 'graph minzoom has been used instead');\n }\n\n graph.zoomTo(endZoom, viewCenter);\n };\n\n ViewController.prototype.getFormatPadding = function () {\n var padding = this.graph.get('fitViewPadding');\n return base_formatPadding(padding);\n };\n\n ViewController.prototype.focusPoint = function (point, animate, animateCfg) {\n var _this = this;\n\n var viewCenter = this.getViewCenter();\n var modelCenter = this.getPointByCanvas(viewCenter.x, viewCenter.y);\n var viewportMatrix = this.graph.get('group').getMatrix();\n if (!viewportMatrix) viewportMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\n if (animate) {\n var dx_1 = (modelCenter.x - point.x) * viewportMatrix[0];\n var dy_1 = (modelCenter.y - point.y) * viewportMatrix[4];\n var lastX_1 = 0;\n var lastY_1 = 0;\n var newX_1 = 0;\n var newY_1 = 0; // 动画每次平移一点,直到目标位置\n\n this.graph.get('canvas').animate(function (ratio) {\n newX_1 = dx_1 * ratio;\n newY_1 = dy_1 * ratio;\n\n _this.graph.translate(newX_1 - lastX_1, newY_1 - lastY_1);\n\n lastX_1 = newX_1;\n lastY_1 = newY_1;\n }, Object(tslib_es6[\"__assign\"])({}, animateCfg));\n } else {\n this.graph.translate((modelCenter.x - point.x) * viewportMatrix[0], (modelCenter.y - point.y) * viewportMatrix[4]);\n }\n };\n /**\n * 将 Canvas 坐标转成视口坐标\n * @param canvasX canvas x 坐标\n * @param canvasY canvas y 坐标\n */\n\n\n ViewController.prototype.getPointByCanvas = function (canvasX, canvasY) {\n var viewportMatrix = this.graph.get('group').getMatrix();\n\n if (!viewportMatrix) {\n viewportMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n var point = math_invertMatrix({\n x: canvasX,\n y: canvasY\n }, viewportMatrix);\n return point;\n };\n /**\n * 将页面坐标转成视口坐标\n * @param clientX 页面 x 坐标\n * @param clientY 页面 y 坐标\n */\n\n\n ViewController.prototype.getPointByClient = function (clientX, clientY) {\n var canvas = this.graph.get('canvas');\n var canvasPoint = canvas.getPointByClient(clientX, clientY);\n return this.getPointByCanvas(canvasPoint.x, canvasPoint.y);\n };\n /**\n * 将视口坐标转成页面坐标\n * @param x 视口 x 坐标\n * @param y 视口 y 坐标\n */\n\n\n ViewController.prototype.getClientByPoint = function (x, y) {\n var canvas = this.graph.get('canvas');\n var canvasPoint = this.getCanvasByPoint(x, y);\n var point = canvas.getClientByPoint(canvasPoint.x, canvasPoint.y);\n return {\n x: point.x,\n y: point.y\n };\n };\n /**\n * 将视口坐标转成 Canvas 坐标\n * @param x 视口 x 坐标\n * @param y 视口 y 坐标\n */\n\n\n ViewController.prototype.getCanvasByPoint = function (x, y) {\n var viewportMatrix = this.graph.get('group').getMatrix();\n\n if (!viewportMatrix) {\n viewportMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n return math_applyMatrix({\n x: x,\n y: y\n }, viewportMatrix);\n };\n /**\n * 将元素移动到画布中心\n * @param item Item 实例或 id\n * @param {boolean} animate 是否带有动画地移动\n * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项\n */\n\n\n ViewController.prototype.focus = function (item, animate, animateCfg) {\n if (Object(esm[\"isString\"])(item)) {\n item = this.graph.findById(item);\n }\n\n if (item) {\n var x = 0,\n y = 0;\n\n if (item.getType && item.getType() === 'edge') {\n var sourceMatrix = item.getSource().get('group').getMatrix();\n var targetMatrix = item.getTarget().get('group').getMatrix();\n\n if (sourceMatrix && targetMatrix) {\n x = (sourceMatrix[6] + targetMatrix[6]) / 2;\n y = (sourceMatrix[7] + targetMatrix[7]) / 2;\n } else if (sourceMatrix || targetMatrix) {\n x = sourceMatrix ? sourceMatrix[6] : targetMatrix[6];\n y = sourceMatrix ? sourceMatrix[7] : targetMatrix[7];\n }\n } else {\n var group = item.get('group');\n var matrix = group.getMatrix();\n if (!matrix) matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n x = matrix[6];\n y = matrix[7];\n } // 用实际位置而不是model中的x,y,防止由于拖拽等的交互导致model的x,y并不是当前的x,y\n\n\n this.focusPoint({\n x: x,\n y: y\n }, animate, animateCfg);\n }\n };\n /**\n * 改变 canvas 画布的宽度和高度\n * @param width canvas 宽度\n * @param height canvas 高度\n */\n\n\n ViewController.prototype.changeSize = function (width, height) {\n var graph = this.graph;\n\n if (!Object(esm[\"isNumber\"])(width) || !Object(esm[\"isNumber\"])(height)) {\n throw Error('invalid canvas width & height, please make sure width & height type is number');\n }\n\n graph.set({\n width: width,\n height: height\n });\n var canvas = graph.get('canvas');\n canvas.changeSize(width, height); // change the size of grid plugin if it exists on graph\n\n var plugins = graph.get('plugins');\n plugins.forEach(function (plugin) {\n if (plugin.get('gridContainer')) {\n // 网格定位信息初始化\n plugin.positionInit();\n }\n });\n };\n\n ViewController.prototype.destroy = function () {\n this.graph = null;\n this.destroyed = false;\n };\n\n return ViewController;\n}();\n\n/* harmony default export */ var view = (view_ViewController);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/xml.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/**\n * @fileOverview 从xml建立自定义Node,包含update\n * @author xuzhi.mxz@antfin.com\n */\n\n\n\n/**\n * 一种更宽松的JSON 解析,如果遇到不符合规范的字段会直接转为字符串\n * @param text json 内容\n */\n\nfunction looseJSONParse(text) {\n if (typeof text !== 'string') {\n return text;\n }\n\n var safeParse = function safeParse(str) {\n if (typeof str !== 'string') {\n return str;\n }\n\n try {\n return JSON.parse(str.trim());\n } catch (e) {\n return str.trim();\n }\n };\n\n var firstAttempt = safeParse(text);\n\n if (typeof firstAttempt !== 'string') {\n return firstAttempt;\n }\n\n var tail = function tail(arr) {\n return arr[arr.length - 1];\n };\n\n var str = text.trim();\n var objectStack = [];\n var syntaxStack = [];\n\n var isLastPair = function isLastPair() {\n var syntaxes = [];\n\n for (var _i = 0; _i < arguments.length; _i++) {\n syntaxes[_i] = arguments[_i];\n }\n\n return syntaxes.some(function (syntax) {\n return tail(syntaxStack) === syntax;\n });\n };\n\n var getValueStore = function getValueStore() {\n return tail(objectStack);\n };\n\n var rst = null;\n var i = 0;\n var temp = '';\n\n while (i < str.length) {\n var nowChar = str[i];\n var isInString = isLastPair('\"', \"'\");\n\n if (!isInString && !nowChar.trim()) {\n i += 1;\n continue;\n }\n\n var isLastTranslate = str[i - 1] === '\\\\';\n var isInObject = isLastPair('}');\n var isInArray = isLastPair(']');\n var isWaitingValue = isLastPair(',');\n var tempArr = getValueStore();\n\n if (isInString) {\n if (tail(syntaxStack) === nowChar && !isLastTranslate) {\n syntaxStack.pop();\n var value = safeParse(temp);\n tempArr.push(value);\n rst = value;\n temp = '';\n } else {\n temp += nowChar;\n }\n } else if (isInArray && nowChar === ',') {\n if (temp) {\n tempArr.push(safeParse(temp));\n temp = '';\n }\n } else if (isInObject && nowChar === ':') {\n syntaxStack.push(',');\n\n if (temp) {\n tempArr.push(temp);\n temp = '';\n }\n } else if (isWaitingValue && nowChar === ',') {\n if (temp) {\n tempArr.push(safeParse(temp));\n temp = '';\n }\n\n syntaxStack.pop();\n } else if (nowChar === '}' && (isInObject || isWaitingValue)) {\n if (temp) {\n tempArr.push(safeParse(temp));\n temp = '';\n }\n\n if (isWaitingValue) {\n syntaxStack.pop();\n }\n\n var obj = {};\n\n for (var c = 1; c < tempArr.length; c += 2) {\n obj[tempArr[c - 1]] = tempArr[c];\n }\n\n objectStack.pop();\n\n if (objectStack.length) {\n tail(objectStack).push(obj);\n }\n\n syntaxStack.pop();\n rst = obj;\n } else if (nowChar === ']' && isInArray) {\n if (temp) {\n tempArr.push(safeParse(temp));\n temp = '';\n }\n\n objectStack.pop();\n\n if (objectStack.length) {\n tail(objectStack).push(tempArr);\n }\n\n syntaxStack.pop();\n rst = tempArr;\n } else if (nowChar === '{') {\n objectStack.push([]);\n syntaxStack.push('}');\n } else if (nowChar === '[') {\n objectStack.push([]);\n syntaxStack.push(']');\n } else if (nowChar === '\"') {\n syntaxStack.push('\"');\n } else if (nowChar === \"'\") {\n syntaxStack.push(\"'\");\n } else {\n temp += nowChar;\n }\n\n i += 1;\n }\n\n return rst || temp;\n}\n\nvar keyConvert = function keyConvert(str) {\n return str.split('-').reduce(function (a, b) {\n return a + b.charAt(0).toUpperCase() + b.slice(1);\n });\n};\n/**\n * 简单的一个{{}}模板渲染,不包含任何复杂语法\n * @param xml\n */\n\n\nvar xml_xmlDataRenderer = function xmlDataRenderer(xml) {\n return function (data) {\n var len = xml.length;\n var arr = [];\n var i = 0;\n var tmp = '';\n\n while (i < len) {\n if (xml[i] === '{' && xml[i + 1] === '{') {\n arr.push(tmp);\n tmp = '';\n i += 2;\n } else if (xml[i] === '}' && xml[i + 1] === '}') {\n if (arr.length) {\n var last = arr.pop();\n tmp = Object(esm[\"get\"])(data, tmp, last.endsWith('=') ? \"\\\"{\" + tmp + \"}\\\"\" : tmp);\n arr.push(last + tmp);\n }\n\n i += 2;\n tmp = '';\n } else {\n tmp += xml[i];\n i += 1;\n }\n }\n\n arr.push(tmp);\n return arr.map(function (e, index) {\n return arr[index - 1] && arr[index - 1].endsWith('=') ? \"\\\"{\" + e + \"}\\\"\" : e;\n }).join('');\n };\n};\n/**\n * 解析XML,并转化为相应的JSON结构\n * @param xml xml解析后的节点\n */\n\nfunction parseXML(xml, cfg) {\n var attrs = {};\n var keys = xml.getAttributeNames && xml.getAttributeNames() || [];\n var children = xml.children && Array.from(xml.children).map(function (e) {\n return parseXML(e, cfg);\n });\n var rst = {};\n var tagName = xml.tagName ? xml.tagName.toLowerCase() : 'group';\n\n if (tagName === 'text') {\n attrs.text = xml.innerText;\n }\n\n rst.type = tagName;\n\n if (tagName === 'img') {\n rst.type = 'image';\n }\n\n Array.from(keys).forEach(function (k) {\n var key = keyConvert(k);\n var val = xml.getAttribute(k);\n\n try {\n if (key === 'style' || key === 'attrs') {\n var style = looseJSONParse(val);\n attrs = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, attrs), style);\n } else {\n rst[key] = looseJSONParse(val);\n }\n } catch (e) {\n if (key === 'style') {\n throw e;\n }\n\n rst[key] = val;\n }\n });\n rst.attrs = attrs;\n\n if (cfg && cfg.style && rst.name && _typeof(cfg.style[rst.name]) === 'object') {\n rst.attrs = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, rst.attrs), cfg.style[rst.name]);\n }\n\n if (cfg && cfg.style && rst.keyshape) {\n rst.attrs = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, rst.attrs), cfg.style);\n }\n\n if (children.length) {\n rst.children = children;\n }\n\n return rst;\n}\n/**\n * 根据偏移量和内部节点最终的bounding box来得出该shape最终的bbox\n */\n\nfunction xml_getBBox(node, offset, chilrenBBox) {\n var _a = node.attrs,\n attrs = _a === void 0 ? {} : _a;\n var bbox = {\n x: offset.x || 0,\n y: offset.y || 0,\n width: chilrenBBox.width || 0,\n height: chilrenBBox.height || 0\n };\n var shapeHeight, shapeWidth;\n\n switch (node.type) {\n case 'maker':\n case 'circle':\n if (attrs.r) {\n shapeWidth = 2 * attrs.r;\n shapeHeight = 2 * attrs.r;\n }\n\n break;\n\n case 'text':\n if (attrs.text) {\n shapeWidth = getTextSize(attrs.text, attrs.fontSize || 12)[0];\n shapeHeight = 16;\n bbox.y += shapeHeight;\n bbox.height = shapeHeight;\n bbox.width = shapeWidth;\n node.attrs = Object(tslib_es6[\"__assign\"])({\n fontSize: 12,\n fill: '#000'\n }, attrs);\n }\n\n break;\n\n default:\n if (attrs.width) {\n shapeWidth = attrs.width;\n }\n\n if (attrs.height) {\n shapeHeight = attrs.height;\n }\n\n }\n\n if (shapeHeight >= 0) {\n bbox.height = shapeHeight;\n }\n\n if (shapeWidth >= 0) {\n bbox.width = shapeWidth;\n }\n\n if (attrs.marginTop) {\n bbox.y += attrs.marginTop;\n }\n\n if (attrs.marginLeft) {\n bbox.x += attrs.marginLeft;\n }\n\n return bbox;\n}\n/**\n * 把从xml计算出的结构填上位置信息,补全attrs\n * @param target\n * @param lastOffset\n */\n\nfunction generateTarget(target, lastOffset) {\n var _a;\n\n if (lastOffset === void 0) {\n lastOffset = {\n x: 0,\n y: 0\n };\n }\n\n var defaultBbox = Object(tslib_es6[\"__assign\"])({\n x: 0,\n y: 0,\n width: 0,\n height: 0\n }, lastOffset);\n\n if ((_a = target.children) === null || _a === void 0 ? void 0 : _a.length) {\n var _b = target.attrs,\n attrs = _b === void 0 ? {} : _b;\n var marginTop = attrs.marginTop;\n\n var offset = Object(tslib_es6[\"__assign\"])({}, lastOffset);\n\n if (marginTop) {\n offset.y += marginTop;\n }\n\n for (var index = 0; index < target.children.length; index++) {\n target.children[index].attrs.key = (attrs.key || 'root') + \" -\" + index + \" \";\n var node = generateTarget(target.children[index], offset);\n\n if (node.bbox) {\n var bbox = node.bbox;\n\n if (node.attrs.next === 'inline') {\n offset.x += node.bbox.width;\n } else {\n offset.y += node.bbox.height;\n }\n\n if (bbox.width + bbox.x > defaultBbox.width) {\n defaultBbox.width = bbox.width + bbox.x;\n }\n\n if (bbox.height + bbox.y > defaultBbox.height) {\n defaultBbox.height = bbox.height + bbox.y;\n }\n }\n }\n }\n\n target.bbox = xml_getBBox(target, lastOffset, defaultBbox);\n target.attrs = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, target.attrs), target.bbox);\n return target;\n}\n/**\n * 对比前后两个最终计算出来的node,并对比出最小改动,\n * 动作: 'add' 添加节点 | ’delete‘ 删除节点 | ’change‘ 改变节点attrs | 'restructure' 重构节点\n * @param nowTarget\n * @param formerTarget\n */\n\nfunction compareTwoTarget(nowTarget, formerTarget) {\n var _a, _b, _c, _d;\n\n var type = (nowTarget || {}).type;\n var key = ((formerTarget === null || formerTarget === void 0 ? void 0 : formerTarget.attrs) || {}).key;\n\n if (key && nowTarget) {\n nowTarget.attrs.key = key;\n }\n\n if (!nowTarget && formerTarget) {\n return {\n action: 'delete',\n val: formerTarget,\n type: type,\n key: key\n };\n }\n\n if (nowTarget && !formerTarget) {\n return {\n action: 'add',\n val: nowTarget,\n type: type\n };\n }\n\n if (!nowTarget && !formerTarget) {\n return {\n action: 'same',\n type: type\n };\n }\n\n var children = [];\n\n if (((_a = nowTarget.children) === null || _a === void 0 ? void 0 : _a.length) > 0 || ((_b = formerTarget.children) === null || _b === void 0 ? void 0 : _b.length) > 0) {\n var length_1 = Math.max((_c = nowTarget.children) === null || _c === void 0 ? void 0 : _c.length, (_d = formerTarget.children) === null || _d === void 0 ? void 0 : _d.length);\n var formerChilren = formerTarget.children || [];\n var nowChilren = nowTarget.children || [];\n\n for (var index = 0; index < length_1; index += 1) {\n children.push(compareTwoTarget(nowChilren[index], formerChilren[index]));\n }\n }\n\n var formerKeys = Object.keys(formerTarget.attrs);\n var nowKeys = Object.keys(nowTarget.attrs);\n\n if (formerTarget.type !== nowTarget.type) {\n return {\n action: 'restructure',\n nowTarget: nowTarget,\n formerTarget: formerTarget,\n key: key,\n children: children\n };\n }\n\n if (formerKeys.filter(function (e) {\n return e !== 'children';\n }).some(function (e) {\n return nowTarget.attrs[e] !== formerTarget.attrs[e] || !nowKeys.includes(e);\n })) {\n return {\n action: 'change',\n val: nowTarget,\n children: children,\n type: type,\n key: key\n };\n }\n\n return {\n action: 'same',\n children: children,\n type: type,\n key: key\n };\n}\n/**\n * 根据xml或者返回xml的函数构建自定义节点的结构\n * @param gen\n */\n\nfunction createNodeFromXML(gen) {\n var structures = {};\n\n var compileXML = function compileXML(cfg) {\n var rawStr = typeof gen === 'function' ? gen(cfg) : gen;\n var target = xml_xmlDataRenderer(rawStr)(cfg);\n var xmlParser = document.createElement('div');\n xmlParser.innerHTML = target;\n var xml = xmlParser.children[0];\n var result = generateTarget(parseXML(xml, cfg));\n xmlParser.remove();\n return result;\n };\n\n return {\n draw: function draw(cfg, group) {\n var resultTarget = compileXML(cfg);\n var keyshape = group;\n\n var renderTarget = function renderTarget(target) {\n var _a = target.attrs,\n attrs = _a === void 0 ? {} : _a,\n bbox = target.bbox,\n type = target.type,\n children = target.children,\n rest = Object(tslib_es6[\"__rest\"])(target, [\"attrs\", \"bbox\", \"type\", \"children\"]);\n\n if (target.type !== 'group') {\n var shape = group.addShape(target.type, Object(tslib_es6[\"__assign\"])({\n attrs: attrs,\n origin: {\n bbox: bbox,\n type: type,\n children: children\n }\n }, rest));\n\n if (target.keyshape) {\n keyshape = shape;\n }\n }\n\n if (target.children) {\n target.children.forEach(function (n) {\n return renderTarget(n);\n });\n }\n };\n\n renderTarget(resultTarget);\n structures[cfg.id] = [resultTarget];\n return keyshape;\n },\n update: function update(cfg, node) {\n if (!structures[cfg.id]) {\n structures[cfg.id] = [];\n }\n\n var container = node.getContainer();\n var children = container.get('children');\n var newTarget = compileXML(cfg);\n var lastTarget = structures[cfg.id].pop();\n var diffResult = compareTwoTarget(newTarget, lastTarget);\n\n var addShape = function addShape(shape) {\n var _a;\n\n if (shape.type !== 'group') {\n container.addShape(shape.type, {\n attrs: shape.attrs\n });\n }\n\n if ((_a = shape.children) === null || _a === void 0 ? void 0 : _a.length) {\n shape.children.map(function (e) {\n return addShape(e);\n });\n }\n };\n\n var delShape = function delShape(shape) {\n var _a;\n\n var targetShape = children.find(function (e) {\n return e.attrs.key === shape.attrs.key;\n });\n\n if (targetShape) {\n container.removeChild(targetShape);\n }\n\n if ((_a = shape.children) === null || _a === void 0 ? void 0 : _a.length) {\n shape.children.map(function (e) {\n return delShape(e);\n });\n }\n };\n\n var updateTarget = function updateTarget(target) {\n var key = target.key;\n\n if (target.type !== 'group') {\n var targetShape = children.find(function (e) {\n return e.attrs.key === key;\n });\n\n switch (target.action) {\n case 'change':\n if (targetShape) {\n var originAttr = target.val.keyshape ? node.getOriginStyle() : {};\n targetShape.attr(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, originAttr), target.val.attrs));\n }\n\n break;\n\n case 'add':\n addShape(target.val);\n break;\n\n case 'delete':\n delShape(target.val);\n break;\n\n case 'restructure':\n delShape(target.formerTarget);\n addShape(target.nowTarget);\n break;\n\n default:\n break;\n }\n }\n\n if (target.children) {\n target.children.forEach(function (n) {\n return updateTarget(n);\n });\n }\n };\n\n updateTarget(diffResult);\n structures[cfg.id].push(newTarget);\n },\n getAnchorPoints: function getAnchorPoints() {\n return [[0, 0.5], [1, 0.5], [0.5, 1], [0.5, 0]];\n }\n };\n}\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/shape.js\n\n\n\nvar shape_cache = {}; // ucfirst 开销过大,进行缓存\n// 首字母大写\n\nfunction ucfirst(str) {\n if (!shape_cache[str]) {\n shape_cache[str] = Object(esm[\"upperFirst\"])(str);\n }\n\n return shape_cache[str];\n}\n/**\n * 工厂方法的基类\n * @type Shape.FactoryBase\n */\n\n\nvar ShapeFactoryBase = {\n /**\n * 默认的形状,当没有指定/匹配 shapeType 时,使用默认的\n * @type {String}\n */\n defaultShapeType: 'defaultType',\n\n /**\n * 形状的 className,用于搜索\n * @type {String}\n */\n className: null,\n\n /**\n * 获取绘制 Shape 的工具类,无状态\n * @param {String} type 类型\n * @return {Shape} 工具类\n */\n getShape: function getShape(type) {\n var self = this;\n var shape = self[type] || self[self.defaultShapeType] || self['simple-circle'];\n return shape;\n },\n\n /**\n * 绘制图形\n * @param {String} type 类型\n * @param {Object} cfg 配置项\n * @param {G.Group} group 图形的分组\n * @return {IShape} 图形对象\n */\n draw: function draw(type, cfg, group) {\n var shape = this.getShape(type);\n group['shapeMap'] = {};\n var rst = shape.draw(cfg, group);\n\n if (shape.afterDraw) {\n shape.afterDraw(cfg, group, rst);\n }\n\n return rst;\n },\n\n /**\n * 更新\n * @param {String} type 类型\n * @param {Object} cfg 配置项\n * @param {G6.Item} item 节点、边、分组等\n */\n baseUpdate: function baseUpdate(type, cfg, item, updateType) {\n var _a, _b;\n\n var shape = this.getShape(type); // 防止没定义 update 函数\n\n if (shape.update) {\n // shape.mergeStyle = updateType === 'move' || updateType === 'bbox' ? {} : shape.getOptions?.(cfg);\n shape.mergeStyle = (_a = shape.getOptions) === null || _a === void 0 ? void 0 : _a.call(shape, cfg, updateType);\n (_b = shape.update) === null || _b === void 0 ? void 0 : _b.call(shape, cfg, item, updateType);\n }\n\n if (shape.afterUpdate) {\n shape.afterUpdate(cfg, item);\n }\n },\n\n /**\n * 设置状态\n * @param {String} type 类型\n * @param {String} name 状态名\n * @param {String | Boolean} value 状态值\n * @param {G6.Item} item 节点、边、分组等\n */\n setState: function setState(type, name, value, item) {\n var shape = this.getShape(type); // 调用 shape/shapeBase.ts 中的 setState 方法\n\n shape.setState(name, value, item);\n },\n\n /**\n * 是否允许更新,不重新绘制图形\n * @param {String} type 类型\n * @return {Boolean} 是否允许使用更新\n */\n shouldUpdate: function shouldUpdate(type) {\n var shape = this.getShape(type);\n return !!shape.update;\n },\n getControlPoints: function getControlPoints(type, cfg) {\n var shape = this.getShape(type);\n return shape.getControlPoints(cfg);\n },\n\n /**\n * 获取控制点\n * @param {String} type 节点、边类型\n * @param {Object} cfg 节点、边的配置项\n * @return {Array|null} 控制点的数组,如果为 null,则没有控制点\n */\n getAnchorPoints: function getAnchorPoints(type, cfg) {\n var shape = this.getShape(type);\n return shape.getAnchorPoints(cfg);\n }\n};\n/**\n * 元素的框架\n */\n\nvar ShapeFramework = {\n // 默认样式及配置\n options: {},\n\n /**\n * 绘制\n */\n draw: function draw(cfg, group) {\n return this.drawShape(cfg, group);\n },\n\n /**\n * 绘制\n */\n drawShape: function drawShape() {},\n\n /**\n * 绘制完成后的操作,便于用户继承现有的节点、边\n */\n afterDraw: function afterDraw() {},\n // update(cfg, item) // 默认不定义\n afterUpdate: function afterUpdate() {},\n\n /**\n * 设置节点、边状态\n */\n setState: function setState() {},\n\n /**\n * 获取控制点\n * @param {Object} cfg 节点、边的配置项\n * @return {Array|null} 控制点的数组,如果为 null,则没有控制点\n */\n getControlPoints: function getControlPoints(cfg) {\n return cfg.controlPoints;\n },\n\n /**\n * 获取控制点\n * @param {Object} cfg 节点、边的配置项\n * @return {Array|null} 控制点的数组,如果为 null,则没有控制点\n */\n getAnchorPoints: function getAnchorPoints(cfg) {\n var defaultAnchorPoints = this.options.anchorPoints;\n var anchorPoints = cfg.anchorPoints || defaultAnchorPoints;\n return anchorPoints;\n }\n /* 如果没定义 update 方法,每次都调用 draw 方法\n update(cfg, item) {\n }\n */\n\n};\n\nvar shape_Shape =\n/** @class */\nfunction () {\n function Shape() {}\n\n Shape.registerFactory = function (factoryType, cfg) {\n var className = ucfirst(factoryType);\n var factoryBase = ShapeFactoryBase;\n\n var shapeFactory = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, factoryBase), cfg);\n\n Shape[className] = shapeFactory;\n shapeFactory.className = className;\n return shapeFactory;\n };\n\n Shape.getFactory = function (factoryType) {\n var className = ucfirst(factoryType);\n return Shape[className];\n };\n\n Shape.registerNode = function (shapeType, nodeDefinition, extendShapeType) {\n var shapeFactory = Shape.Node;\n var shapeObj;\n\n if (typeof nodeDefinition === 'string' || typeof nodeDefinition === 'function') {\n var autoNodeDefinition = createNodeFromXML(nodeDefinition);\n shapeObj = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, shapeFactory.getShape('single-node')), autoNodeDefinition);\n } else if (nodeDefinition.jsx) {\n var jsx = nodeDefinition.jsx;\n var autoNodeDefinition = createNodeFromXML(jsx);\n shapeObj = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, shapeFactory.getShape('single-node')), autoNodeDefinition), nodeDefinition);\n } else {\n shapeFactory.getShape(extendShapeType);\n var extendShape = extendShapeType ? shapeFactory.getShape(extendShapeType) : ShapeFramework;\n shapeObj = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, extendShape), nodeDefinition);\n }\n\n shapeObj.type = shapeType;\n shapeObj.itemType = 'node';\n shapeFactory[shapeType] = shapeObj;\n return shapeObj;\n };\n\n Shape.registerEdge = function (shapeType, edgeDefinition, extendShapeType) {\n var shapeFactory = Shape.Edge;\n var extendShape = extendShapeType ? shapeFactory.getShape(extendShapeType) : ShapeFramework;\n\n var shapeObj = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, extendShape), edgeDefinition);\n\n shapeObj.type = shapeType;\n shapeObj.itemType = 'edge';\n shapeFactory[shapeType] = shapeObj;\n return shapeObj;\n };\n\n Shape.registerCombo = function (shapeType, comboDefinition, extendShapeType) {\n var shapeFactory = Shape.Combo;\n var extendShape = extendShapeType ? shapeFactory.getShape(extendShapeType) : ShapeFramework;\n\n var shapeObj = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, extendShape), comboDefinition);\n\n shapeObj.type = shapeType;\n shapeObj.itemType = 'combo';\n shapeFactory[shapeType] = shapeObj;\n return shapeObj;\n };\n\n return Shape;\n}();\n\n/* harmony default export */ var element_shape = (shape_Shape); // 注册 Node 的工厂方法\n\nshape_Shape.registerFactory('node', {\n defaultShapeType: 'circle'\n}); // 注册 Edge 的工厂方法\n\nshape_Shape.registerFactory('edge', {\n defaultShapeType: 'line'\n}); // 注册 Combo 的工厂方法\n\nshape_Shape.registerFactory('combo', {\n defaultShapeType: 'circle'\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/item/item.js\n\n\n\n\n\n\nvar CACHE_BBOX = 'bboxCache';\nvar CACHE_CANVAS_BBOX = 'bboxCanvasCache';\nvar ARROWS = ['startArrow', 'endArrow'];\n\nvar item_ItemBase =\n/** @class */\nfunction () {\n function ItemBase(cfg) {\n this._cfg = {};\n this.destroyed = false;\n var defaultCfg = {\n /**\n * id\n * @type {string}\n */\n id: undefined,\n\n /**\n * 类型\n * @type {string}\n */\n type: 'item',\n\n /**\n * data model\n * @type {object}\n */\n model: {},\n\n /**\n * g group\n * @type {G.Group}\n */\n group: undefined,\n\n /**\n * is open animate\n * @type {boolean}\n */\n animate: false,\n\n /**\n * visible - not group visible\n * @type {boolean}\n */\n visible: true,\n\n /**\n * locked - lock node\n * @type {boolean}\n */\n locked: false,\n\n /**\n * capture event\n * @type {boolean}\n */\n event: true,\n\n /**\n * key shape to calculate item's bbox\n * @type object\n */\n keyShape: undefined,\n\n /**\n * item's states, such as selected or active\n * @type Array\n */\n states: []\n };\n this._cfg = Object.assign(defaultCfg, this.getDefaultCfg(), cfg);\n var model = this.get('model');\n var id = model.id;\n var itemType = this.get('type');\n\n if (!id) {\n id = base_uniqueId(itemType);\n this.get('model').id = id;\n }\n\n this.set('id', id);\n var group = cfg.group;\n\n if (group) {\n group.set('item', this);\n group.set('id', id);\n }\n\n this.init();\n this.draw();\n var shapeType = model.shape || model.type || (itemType === 'edge' ? 'line' : 'circle');\n var shapeFactory = this.get('shapeFactory');\n\n if (shapeFactory && shapeFactory[shapeType]) {\n var options = shapeFactory[shapeType].options; // merge the stateStyles from item and shape\n\n if (options && options.stateStyles) {\n var styles = this.get('styles') || model.stateStyles;\n styles = Object(esm[\"deepMix\"])({}, options.stateStyles, styles);\n this.set('styles', styles);\n }\n }\n }\n /**\n * 根据 keyshape 计算包围盒\n */\n\n\n ItemBase.prototype.calculateBBox = function () {\n var keyShape = this.get('keyShape');\n var group = this.get('group'); // 因为 group 可能会移动,所以必须通过父元素计算才能计算出正确的包围盒\n\n var bbox = graphic_getBBox(keyShape, group);\n bbox.x = bbox.minX;\n bbox.y = bbox.minY;\n bbox.width = bbox.maxX - bbox.minX;\n bbox.height = bbox.maxY - bbox.minY;\n bbox.centerX = (bbox.minX + bbox.maxX) / 2;\n bbox.centerY = (bbox.minY + bbox.maxY) / 2;\n return bbox;\n };\n /**\n * 根据 keyshape 计算包围盒\n */\n\n\n ItemBase.prototype.calculateCanvasBBox = function () {\n var keyShape = this.get('keyShape');\n var group = this.get('group'); // 因为 group 可能会移动,所以必须通过父元素计算才能计算出正确的包围盒\n\n var bbox = graphic_getBBox(keyShape, group);\n bbox.x = bbox.minX;\n bbox.y = bbox.minY;\n bbox.width = bbox.maxX - bbox.minX;\n bbox.height = bbox.maxY - bbox.minY;\n bbox.centerX = (bbox.minX + bbox.maxX) / 2;\n bbox.centerY = (bbox.minY + bbox.maxY) / 2;\n return bbox;\n };\n /**\n * draw shape\n */\n\n\n ItemBase.prototype.drawInner = function () {\n var self = this;\n var shapeFactory = self.get('shapeFactory');\n var group = self.get('group');\n var model = self.get('model');\n group.clear();\n var visible = model.visible;\n if (visible !== undefined && !visible) self.changeVisibility(visible);\n\n if (!shapeFactory) {\n return;\n }\n\n self.updatePosition(model);\n var cfg = self.getShapeCfg(model); // 可能会附加额外信息\n\n var shapeType = cfg.type;\n var keyShape = shapeFactory.draw(shapeType, cfg, group);\n\n if (keyShape) {\n self.set('keyShape', keyShape);\n keyShape.set('isKeyShape', true);\n keyShape.set('draggable', true);\n }\n\n this.setOriginStyle(); // 防止由于用户外部修改 model 中的 shape 导致 shape 不更新\n\n this.set('currentShape', shapeType);\n this.restoreStates(shapeFactory, shapeType);\n };\n /**\n * 设置图元素原始样式\n * @param keyShape 图元素 keyShape\n * @param group Group 容器\n */\n\n\n ItemBase.prototype.setOriginStyle = function () {\n var group = this.get('group');\n var children = group.get('children');\n var keyShape = this.getKeyShape();\n var self = this;\n var keyShapeName = keyShape.get('name');\n\n if (!this.get('originStyle')) {\n // 第一次 set originStyle,直接拿首次渲染所有图形的 attrs\n var originStyles = {};\n\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n var shapeType = child.get('type');\n var name_1 = child.get('name');\n\n if (name_1 && name_1 !== keyShapeName) {\n originStyles[name_1] = shapeType !== 'image' ? Object(esm[\"clone\"])(child.attr()) : self.getShapeStyleByName(name_1); // The text's position and matrix is not allowed to be affected by states\n\n if (shapeType === 'text' && originStyles[name_1]) {\n delete originStyles[name_1].x;\n delete originStyles[name_1].y;\n delete originStyles[name_1].matrix;\n }\n } else {\n var keyShapeStyle = self.getShapeStyleByName(); // 可优化,需要去除 child.attr 中其他 shape 名的对象\n\n delete keyShapeStyle.path;\n delete keyShapeStyle.matrix;\n\n if (!keyShapeName) {\n Object.assign(originStyles, keyShapeStyle);\n } else {\n // 若 keyShape 有 name 且 !name,这个图形不是 keyShape,给这个图形一个 name\n if (!name_1) {\n var shapeName = base_uniqueId('shape');\n child.set('name', shapeName);\n group['shapeMap'][shapeName] = child;\n originStyles[shapeName] = shapeType !== 'image' ? Object(esm[\"clone\"])(child.attr()) : self.getShapeStyleByName(name_1);\n } else {\n originStyles[keyShapeName] = keyShapeStyle;\n }\n }\n }\n }\n\n self.set('originStyle', originStyles);\n } else {\n // 第二次 set originStyles,需要找到不是 stateStyles 的样式,更新到 originStyles 中\n // 上一次设置的 originStyle,是初始的 shape attrs\n var styles_1 = this.get('originStyle'); // let styles: ShapeStyle = {};\n\n if (keyShapeName && !styles_1[keyShapeName]) styles_1[keyShapeName] = {}; // 获取当前状态样式\n\n var currentStatesStyle_1 = this.getCurrentStatesStyle();\n\n var _loop_1 = function _loop_1(i) {\n var child = children[i];\n var name_2 = child.get('name');\n var shapeAttrs = child.attr();\n\n if (name_2 && name_2 !== keyShapeName) {\n // 有 name 的非 keyShape 图形\n var shapeStateStyle_1 = currentStatesStyle_1[name_2];\n if (!styles_1[name_2]) styles_1[name_2] = {};\n\n if (shapeStateStyle_1) {\n Object.keys(shapeAttrs).forEach(function (key) {\n var value = shapeAttrs[key];\n if (value !== shapeStateStyle_1[key]) styles_1[name_2][key] = value;\n });\n } else {\n styles_1[name_2] = child.get('type') !== 'image' ? Object(esm[\"clone\"])(shapeAttrs) : self.getShapeStyleByName(name_2);\n }\n } else {\n var shapeAttrs_1 = child.attr();\n var keyShapeStateStyles_1 = {};\n Object.keys(currentStatesStyle_1).forEach(function (styleKey) {\n var subStyle = currentStatesStyle_1[styleKey];\n\n if (styleKey === keyShapeName || !Object(esm[\"isPlainObject\"])(subStyle)) {\n keyShapeStateStyles_1[styleKey] = subStyle;\n }\n });\n Object.keys(shapeAttrs_1).forEach(function (key) {\n var value = shapeAttrs_1[key]; // 如果是对象且不是 arrow,则是其他 shape 的样式\n // if (isPlainObject(value) && ARROWS.indexOf(name) === -1) return;\n\n if (keyShapeStateStyles_1[key] !== value) {\n if (keyShapeName) styles_1[keyShapeName][key] = value;else styles_1[key] = value;\n }\n });\n }\n }; // 遍历当前所有图形的 attrs,找到不是 stateStyles 的样式更新到 originStyles 中\n\n\n for (var i = 0; i < children.length; i++) {\n _loop_1(i);\n }\n\n delete styles_1.path;\n delete styles_1.matrix;\n delete styles_1.x;\n delete styles_1.y;\n\n if (styles_1[keyShapeName]) {\n delete styles_1[keyShapeName].x;\n delete styles_1[keyShapeName].y;\n delete styles_1[keyShapeName].matrix;\n delete styles_1[keyShapeName].path;\n }\n\n self.set('originStyle', styles_1);\n }\n };\n /**\n * restore shape states\n * @param shapeFactory\n * @param shapeType\n */\n\n\n ItemBase.prototype.restoreStates = function (shapeFactory, shapeType) {\n var self = this;\n var states = self.get('states');\n Object(esm[\"each\"])(states, function (state) {\n shapeFactory.setState(shapeType, state, true, self);\n });\n };\n\n ItemBase.prototype.init = function () {\n var shapeFactory = element_shape.getFactory(this.get('type'));\n this.set('shapeFactory', shapeFactory);\n };\n /**\n * 获取属性\n * @internal 仅内部类使用\n * @param {String} key 属性名\n * @return {object | string | number} 属性值\n */\n\n\n ItemBase.prototype.get = function (key) {\n return this._cfg[key];\n };\n /**\n * 设置属性\n * @internal 仅内部类使用\n * @param {String|Object} key 属性名,也可以是对象\n * @param {object | string | number} val 属性值\n */\n\n\n ItemBase.prototype.set = function (key, val) {\n if (Object(esm[\"isPlainObject\"])(key)) {\n this._cfg = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, this._cfg), key);\n } else {\n this._cfg[key] = val;\n }\n };\n\n ItemBase.prototype.getDefaultCfg = function () {\n return {};\n };\n /**\n * 更新/刷新等操作后,清除 cache\n */\n\n\n ItemBase.prototype.clearCache = function () {\n this.set(CACHE_BBOX, null);\n this.set(CACHE_CANVAS_BBOX, null);\n };\n /**\n * 渲染前的逻辑,提供给子类复写\n */\n\n\n ItemBase.prototype.beforeDraw = function () {};\n /**\n * 渲染后的逻辑,提供给子类复写\n */\n\n\n ItemBase.prototype.afterDraw = function () {};\n /**\n * 更新后做一些工作\n */\n\n\n ItemBase.prototype.afterUpdate = function () {};\n /**\n * draw shape\n */\n\n\n ItemBase.prototype.draw = function () {\n this.beforeDraw();\n this.drawInner();\n this.afterDraw();\n };\n\n ItemBase.prototype.getShapeStyleByName = function (name) {\n var group = this.get('group');\n var currentShape;\n\n if (name) {\n currentShape = group['shapeMap'][name]; // group.find((element) => element.get('name') === name) as IShapeBase;\n } else {\n currentShape = this.getKeyShape();\n }\n\n if (currentShape) {\n var styles_2 = {};\n Object(esm[\"each\"])(currentShape.attr(), function (val, key) {\n // 修改 img 通过 updateItem 实现\n if (key !== 'img' || Object(esm[\"isString\"])(val)) {\n styles_2[key] = val;\n }\n });\n return styles_2;\n }\n\n return {};\n };\n\n ItemBase.prototype.getShapeCfg = function (model, updateType) {\n var styles = this.get('styles');\n\n if (styles) {\n // merge graph的item样式与数据模型中的样式\n var newModel = model;\n newModel.style = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), model.style);\n return newModel;\n }\n\n return model;\n };\n /**\n * 获取指定状态的样式,去除了全局样式\n * @param state 状态名称\n */\n\n\n ItemBase.prototype.getStateStyle = function (state) {\n var styles = this.get('styles');\n var stateStyle = styles && styles[state];\n return stateStyle;\n };\n /**\n * get keyshape style\n */\n\n\n ItemBase.prototype.getOriginStyle = function () {\n return this.get('originStyle');\n };\n\n ItemBase.prototype.getCurrentStatesStyle = function () {\n var self = this;\n var styles = {};\n var states = self.getStates();\n\n if (!states || !states.length) {\n return this.get('originStyle');\n }\n\n Object(esm[\"each\"])(self.getStates(), function (state) {\n styles = Object.assign(styles, self.getStateStyle(state));\n });\n return styles;\n };\n /**\n * 更改元素状态, visible 不属于这个范畴\n * @internal 仅提供内部类 graph 使用\n * @param {String} state 状态名\n * @param {Boolean} value 节点状态值\n */\n\n\n ItemBase.prototype.setState = function (state, value) {\n var states = this.get('states');\n var shapeFactory = this.get('shapeFactory');\n var stateName = state;\n var filterStateName = state;\n\n if (Object(esm[\"isString\"])(value)) {\n stateName = state + \":\" + value;\n filterStateName = state + \":\";\n }\n\n var newStates = states;\n\n if (Object(esm[\"isBoolean\"])(value)) {\n var index = states.indexOf(filterStateName);\n\n if (value) {\n if (index > -1) {\n return;\n }\n\n states.push(stateName);\n } else if (index > -1) {\n states.splice(index, 1);\n }\n } else if (Object(esm[\"isString\"])(value)) {\n // 过滤掉 states 中 filterStateName 相关的状态\n var filterStates = states.filter(function (name) {\n return name.includes(filterStateName);\n });\n\n if (filterStates.length > 0) {\n this.clearStates(filterStates);\n }\n\n newStates = newStates.filter(function (name) {\n return !name.includes(filterStateName);\n });\n newStates.push(stateName);\n this.set('states', newStates);\n }\n\n if (shapeFactory) {\n var model = this.get('model');\n var type = model.type; // 调用 shape/shape.ts 中的 setState\n\n shapeFactory.setState(type, state, value, this);\n }\n };\n /**\n * 清除指定的状态,如果参数为空,则不做任务处理\n * @param states 状态名称\n */\n\n\n ItemBase.prototype.clearStates = function (states) {\n var self = this;\n var originStates = self.getStates();\n var shapeFactory = self.get('shapeFactory');\n var model = self.get('model');\n var shape = model.type;\n\n if (!states) {\n states = originStates;\n }\n\n if (Object(esm[\"isString\"])(states)) {\n states = [states];\n }\n\n var newStates = originStates.filter(function (state) {\n return states.indexOf(state) === -1;\n });\n self.set('states', newStates);\n states.forEach(function (state) {\n shapeFactory.setState(shape, state, false, self);\n });\n };\n /**\n * 节点的图形容器\n * @return {G.Group} 图形容器\n */\n\n\n ItemBase.prototype.getContainer = function () {\n return this.get('group');\n };\n /**\n * 节点的关键形状,用于计算节点大小,连线截距等\n * @return {IShapeBase} 关键形状\n */\n\n\n ItemBase.prototype.getKeyShape = function () {\n return this.get('keyShape');\n };\n /**\n * 节点数据模型\n * @return {Object} 数据模型\n */\n\n\n ItemBase.prototype.getModel = function () {\n return this.get('model');\n };\n /**\n * 节点类型\n * @return {string} 节点的类型\n */\n\n\n ItemBase.prototype.getType = function () {\n return this.get('type');\n };\n /**\n * 获取 Item 的ID\n */\n\n\n ItemBase.prototype.getID = function () {\n return this.get('id');\n };\n /**\n * 是否是 Item 对象,悬空边情况下进行判定\n */\n\n\n ItemBase.prototype.isItem = function () {\n return true;\n };\n /**\n * 获取当前元素的所有状态\n * @return {Array} 元素的所有状态\n */\n\n\n ItemBase.prototype.getStates = function () {\n return this.get('states');\n };\n /**\n * 当前元素是否处于某状态\n * @param {String} state 状态名\n * @return {Boolean} 是否处于某状态\n */\n\n\n ItemBase.prototype.hasState = function (state) {\n var states = this.getStates();\n return states.indexOf(state) >= 0;\n };\n /**\n * 刷新一般用于处理几种情况\n * 1. item model 在外部被改变\n * 2. 边的节点位置发生改变,需要重新计算边\n *\n * 因为数据从外部被修改无法判断一些属性是否被修改,直接走位置和 shape 的更新\n */\n\n\n ItemBase.prototype.refresh = function (updateType) {\n var model = this.get('model'); // 更新元素位置\n\n this.updatePosition(model); // 更新元素内容,样式\n\n this.updateShape(updateType); // 做一些更新之后的操作\n\n this.afterUpdate(); // 清除缓存\n\n this.clearCache();\n };\n\n ItemBase.prototype.getUpdateType = function (cfg) {\n return undefined;\n };\n /**\n * 将更新应用到 model 上,刷新属性\n * @internal 仅提供给 Graph 使用,外部直接调用 graph.update 接口\n * @param {Object} cfg 配置项,可以是增量信息\n */\n\n\n ItemBase.prototype.update = function (cfg, updateType) {\n if (updateType === void 0) {\n updateType = undefined;\n }\n\n var model = this.get('model'); // 仅仅移动位置时,既不更新,也不重绘\n\n if (updateType === 'move') {\n this.updatePosition(cfg);\n } else {\n var oriVisible = model.visible;\n var cfgVisible = cfg.visible;\n if (oriVisible !== cfgVisible && cfgVisible !== undefined) this.changeVisibility(cfgVisible);\n var originPosition = {\n x: model.x,\n y: model.y\n };\n cfg.x = isNaN(+cfg.x) ? model.x : +cfg.x;\n cfg.y = isNaN(+cfg.y) ? model.y : +cfg.y;\n var styles = this.get('styles');\n\n if (cfg.stateStyles) {\n // 更新 item 时更新 this.get('styles') 中的值\n var stateStyles = cfg.stateStyles;\n Object(esm[\"mix\"])(styles, stateStyles);\n delete cfg.stateStyles;\n } // 直接将更新合到原数据模型上,可以保证用户在外部修改源数据然后刷新时的样式符合期待。\n\n\n Object.assign(model, cfg); // 如果 x,y 有变化,先重置位置\n\n if (originPosition.x !== cfg.x || originPosition.y !== cfg.y) {\n this.updatePosition(cfg);\n }\n\n this.updateShape(updateType);\n }\n\n this.afterUpdate();\n this.clearCache();\n };\n /**\n * 更新元素内容,样式\n */\n\n\n ItemBase.prototype.updateShape = function (updateType) {\n var shapeFactory = this.get('shapeFactory');\n var model = this.get('model');\n var shape = model.type; // 判定是否允许更新\n // 1. 注册的节点允许更新\n // 2. 更新后的 shape 等于原先的 shape\n\n if (shapeFactory.shouldUpdate(shape) && shape === this.get('currentShape')) {\n var updateCfg = this.getShapeCfg(model, updateType);\n shapeFactory.baseUpdate(shape, updateCfg, this, updateType); // 更新完以后重新设置原始样式\n\n if (updateType !== 'move') this.setOriginStyle();\n } else {\n // 如果不满足上面两种状态,重新绘制\n this.draw();\n } // 更新后重置节点状态\n\n\n this.restoreStates(shapeFactory, shape);\n };\n /**\n * 更新位置,避免整体重绘\n * @param {object} cfg 待更新数据\n */\n\n\n ItemBase.prototype.updatePosition = function (cfg) {\n var model = this.get('model');\n var x = isNaN(+cfg.x) ? +model.x : +cfg.x;\n var y = isNaN(+cfg.y) ? +model.y : +cfg.y;\n var group = this.get('group');\n\n if (isNaN(x) || isNaN(y)) {\n return false;\n }\n\n model.x = x;\n model.y = y;\n var matrix = group.getMatrix();\n if (matrix && matrix[6] === x && matrix[7] === y) return false;\n group.resetMatrix(); // G 4.0 element 中移除了矩阵相关方法,详见https://www.yuque.com/antv/blog/kxzk9g#4rMMV\n\n translate(group, {\n x: x,\n y: y\n });\n this.clearCache(); // 位置更新后需要清除缓存\n\n return true;\n };\n /**\n * 获取 item 的包围盒,这个包围盒是相对于 item 自己,不会将 matrix 计算在内\n * @return {Object} 包含 x,y,width,height, centerX, centerY\n */\n\n\n ItemBase.prototype.getBBox = function () {\n // 计算 bbox 开销有些大,缓存\n var bbox = this.get(CACHE_BBOX);\n\n if (!bbox) {\n bbox = this.calculateBBox();\n this.set(CACHE_BBOX, bbox);\n }\n\n return bbox;\n };\n /**\n * 获取 item 相对于画布的包围盒,会将从顶层到当前元素的 matrix 都计算在内\n * @return {Object} 包含 x,y,width,height, centerX, centerY\n */\n\n\n ItemBase.prototype.getCanvasBBox = function () {\n // 计算 bbox 开销有些大,缓存\n var bbox = this.get(CACHE_CANVAS_BBOX);\n\n if (!bbox) {\n bbox = this.calculateCanvasBBox();\n this.set(CACHE_CANVAS_BBOX, bbox);\n }\n\n return bbox;\n };\n /**\n * 将元素放到最前面\n */\n\n\n ItemBase.prototype.toFront = function () {\n var group = this.get('group');\n group.toFront();\n };\n /**\n * 将元素放到最后面\n */\n\n\n ItemBase.prototype.toBack = function () {\n var group = this.get('group');\n group.toBack();\n };\n /**\n * 显示元素\n */\n\n\n ItemBase.prototype.show = function () {\n this.changeVisibility(true);\n };\n /**\n * 隐藏元素\n */\n\n\n ItemBase.prototype.hide = function () {\n this.changeVisibility(false);\n };\n /**\n * 更改是否显示\n * @param {Boolean} visible 是否显示\n */\n\n\n ItemBase.prototype.changeVisibility = function (visible) {\n var group = this.get('group');\n\n if (visible) {\n group.show();\n } else {\n group.hide();\n }\n\n this.set('visible', visible);\n };\n /**\n * 元素是否可见\n * @return {Boolean} 返回该元素是否可见\n */\n\n\n ItemBase.prototype.isVisible = function () {\n return this.get('visible');\n };\n /**\n * 是否拾取及出发该元素的交互事件\n * @param {Boolean} enable 标识位\n */\n\n\n ItemBase.prototype.enableCapture = function (enable) {\n var group = this.get('group');\n\n if (group) {\n group.set('capture', enable);\n }\n };\n\n ItemBase.prototype.destroy = function () {\n if (!this.destroyed) {\n var animate = this.get('animate');\n var group = this.get('group');\n\n if (animate) {\n group.stopAnimate();\n }\n\n group['shapeMap'] = {};\n this.clearCache();\n group.remove();\n this._cfg = null;\n this.destroyed = true;\n }\n };\n\n return ItemBase;\n}();\n\n/* harmony default export */ var item_item = (item_ItemBase);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/item/edge.js\n\n\n\nvar END_MAP = {\n source: 'start',\n target: 'end'\n};\nvar ITEM_NAME_SUFFIX = 'Node'; // 端点的后缀,如 sourceNode, targetNode\n\nvar POINT_NAME_SUFFIX = 'Point'; // 起点或者结束点的后缀,如 startPoint, endPoint\n\nvar ANCHOR_NAME_SUFFIX = 'Anchor';\n\nvar edge_Edge =\n/** @class */\nfunction (_super) {\n Object(tslib_es6[\"__extends\"])(Edge, _super);\n\n function Edge() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n\n Edge.prototype.getDefaultCfg = function () {\n return {\n type: 'edge',\n sourceNode: null,\n targetNode: null,\n startPoint: null,\n endPoint: null,\n linkCenter: false\n };\n };\n\n Edge.prototype.setEnd = function (name, value) {\n var pointName = END_MAP[name] + POINT_NAME_SUFFIX;\n var itemName = name + ITEM_NAME_SUFFIX;\n var preItem = this.get(itemName);\n\n if (preItem && !preItem.destroyed) {\n // 如果之前存在节点,则移除掉边\n preItem.removeEdge(this);\n }\n\n if (Object(esm[\"isPlainObject\"])(value)) {\n // 如果设置成具体的点,则清理节点\n this.set(pointName, value);\n this.set(itemName, null);\n } else if (value) {\n value.addEdge(this);\n this.set(itemName, value);\n this.set(pointName, null);\n }\n };\n /**\n * 获取连接点的坐标\n * @param name source | target\n * @param model 边的数据模型\n * @param controlPoints 控制点\n */\n\n\n Edge.prototype.getLinkPoint = function (name, model, controlPoints) {\n var pointName = END_MAP[name] + POINT_NAME_SUFFIX;\n var itemName = name + ITEM_NAME_SUFFIX;\n var point = this.get(pointName);\n\n if (!point) {\n var item = this.get(itemName);\n var anchorName = name + ANCHOR_NAME_SUFFIX;\n var prePoint = this.getPrePoint(name, controlPoints);\n var anchorIndex = model[anchorName];\n\n if (!Object(esm[\"isNil\"])(anchorIndex)) {\n // 如果有锚点,则使用锚点索引获取连接点\n point = item.getLinkPointByAnchor(anchorIndex);\n } // 如果锚点没有对应的点或者没有锚点,则直接计算连接点\n\n\n point = point || item.getLinkPoint(prePoint);\n\n if (!Object(esm[\"isNil\"])(point.index)) {\n this.set(name + \"AnchorIndex\", point.index);\n }\n }\n\n return point;\n };\n /**\n * 获取同端点进行连接的点,计算交汇点\n * @param name\n * @param controlPoints\n */\n\n\n Edge.prototype.getPrePoint = function (name, controlPoints) {\n if (controlPoints && controlPoints.length) {\n var index = name === 'source' ? 0 : controlPoints.length - 1;\n return controlPoints[index];\n }\n\n var oppositeName = name === 'source' ? 'target' : 'source'; // 取另一个节点的位置\n\n return this.getEndPoint(oppositeName);\n };\n /**\n * 获取端点的位置\n * @param name\n */\n\n\n Edge.prototype.getEndPoint = function (name) {\n var itemName = name + ITEM_NAME_SUFFIX;\n var pointName = END_MAP[name] + POINT_NAME_SUFFIX;\n var item = this.get(itemName); // 如果有端点,直接使用 model\n\n if (item) {\n return item.get('model');\n } // 否则直接使用点\n\n\n return this.get(pointName);\n };\n /**\n * 通过端点的中心获取控制点\n * @param model\n */\n\n\n Edge.prototype.getControlPointsByCenter = function (model) {\n var sourcePoint = this.getEndPoint('source');\n var targetPoint = this.getEndPoint('target');\n var shapeFactory = this.get('shapeFactory');\n var type = model.type;\n return shapeFactory.getControlPoints(type, {\n startPoint: sourcePoint,\n endPoint: targetPoint\n });\n };\n\n Edge.prototype.getEndCenter = function (name) {\n var itemName = name + ITEM_NAME_SUFFIX;\n var pointName = END_MAP[name] + POINT_NAME_SUFFIX;\n var item = this.get(itemName); // 如果有端点,直接使用 model\n\n if (item) {\n var bbox = item.getBBox();\n return {\n x: bbox.centerX,\n y: bbox.centerY\n };\n } // 否则直接使用点\n\n\n return this.get(pointName);\n };\n\n Edge.prototype.init = function () {\n _super.prototype.init.call(this); // 初始化两个端点\n\n\n this.setSource(this.get('source'));\n this.setTarget(this.get('target'));\n };\n\n Edge.prototype.getShapeCfg = function (model, updateType) {\n var self = this;\n var linkCenter = self.get('linkCenter'); // 如果连接到中心,忽视锚点、忽视控制点\n\n var cfg = (updateType === null || updateType === void 0 ? void 0 : updateType.includes('move')) ? model : _super.prototype.getShapeCfg.call(this, model);\n\n if (linkCenter) {\n cfg.startPoint = self.getEndCenter('source');\n cfg.endPoint = self.getEndCenter('target');\n } else {\n var controlPoints = cfg.controlPoints || self.getControlPointsByCenter(cfg);\n cfg.startPoint = self.getLinkPoint('source', model, controlPoints);\n cfg.endPoint = self.getLinkPoint('target', model, controlPoints);\n }\n\n cfg.sourceNode = self.get('sourceNode');\n cfg.targetNode = self.get('targetNode');\n return cfg;\n };\n /**\n * 获取边的数据模型\n */\n\n\n Edge.prototype.getModel = function () {\n var out = this.get('model');\n var sourceItem = this.get(\"source\" + ITEM_NAME_SUFFIX);\n var targetItem = this.get(\"target\" + ITEM_NAME_SUFFIX);\n\n if (sourceItem) {\n delete out[\"source\" + ITEM_NAME_SUFFIX];\n } else {\n out.source = this.get(\"start\" + POINT_NAME_SUFFIX);\n }\n\n if (targetItem) {\n delete out[\"target\" + ITEM_NAME_SUFFIX];\n } else {\n out.target = this.get(\"end\" + POINT_NAME_SUFFIX);\n }\n\n if (!Object(esm[\"isString\"])(out.source) && !Object(esm[\"isPlainObject\"])(out.source)) {\n out.source = out.source.getID();\n }\n\n if (!Object(esm[\"isString\"])(out.target) && !Object(esm[\"isPlainObject\"])(out.target)) {\n out.target = out.target.getID();\n }\n\n return out;\n };\n\n Edge.prototype.setSource = function (source) {\n this.setEnd('source', source);\n this.set('source', source);\n };\n\n Edge.prototype.setTarget = function (target) {\n this.setEnd('target', target);\n this.set('target', target);\n };\n\n Edge.prototype.getSource = function () {\n return this.get('source');\n };\n\n Edge.prototype.getTarget = function () {\n return this.get('target');\n };\n\n Edge.prototype.updatePosition = function () {\n return false;\n };\n /**\n * 边不需要重计算容器位置,直接重新计算 path 位置\n * @param {object} cfg 待更新数据\n */\n\n\n Edge.prototype.update = function (cfg, updateType) {\n if (updateType === void 0) {\n updateType = undefined;\n }\n\n var model = this.get('model');\n var oriVisible = model.visible;\n var cfgVisible = cfg.visible;\n if (oriVisible !== cfgVisible && cfgVisible !== undefined) this.changeVisibility(cfgVisible);\n var styles = this.get('styles');\n\n if (cfg.stateStyles) {\n // 更新 item 时更新 this.get('styles') 中的值\n var stateStyles = cfg.stateStyles;\n Object(esm[\"mix\"])(styles, stateStyles);\n delete cfg.stateStyles;\n }\n\n Object.assign(model, cfg);\n this.updateShape(updateType);\n this.afterUpdate();\n this.clearCache();\n };\n\n Edge.prototype.destroy = function () {\n var sourceItem = this.get(\"source\" + ITEM_NAME_SUFFIX);\n var targetItem = this.get(\"target\" + ITEM_NAME_SUFFIX);\n\n if (sourceItem && !sourceItem.destroyed) {\n sourceItem.removeEdge(this);\n }\n\n if (targetItem && !targetItem.destroyed) {\n targetItem.removeEdge(this);\n }\n\n _super.prototype.destroy.call(this);\n };\n\n return Edge;\n}(item_item);\n\n/* harmony default export */ var item_edge = (edge_Edge);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/item/node.js\n\n\n\n\nvar CACHE_ANCHOR_POINTS = 'anchorPointsCache';\nvar node_CACHE_BBOX = 'bboxCache';\n\nvar node_Node =\n/** @class */\nfunction (_super) {\n Object(tslib_es6[\"__extends\"])(Node, _super);\n\n function Node() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n\n Node.prototype.getNearestPoint = function (points, curPoint) {\n var index = 0;\n var nearestPoint = points[0];\n var minDistance = math_distance(points[0], curPoint);\n\n for (var i = 0; i < points.length; i++) {\n var point = points[i];\n var dis = math_distance(point, curPoint);\n\n if (dis < minDistance) {\n nearestPoint = point;\n minDistance = dis;\n index = i;\n }\n }\n\n nearestPoint.anchorIndex = index;\n return nearestPoint;\n };\n\n Node.prototype.getDefaultCfg = function () {\n return {\n type: 'node',\n edges: []\n };\n };\n /**\n * 获取从节点关联的所有边\n */\n\n\n Node.prototype.getEdges = function () {\n return this.get('edges');\n };\n /**\n * 获取所有的入边\n */\n\n\n Node.prototype.getInEdges = function () {\n var self = this;\n return this.get('edges').filter(function (edge) {\n return edge.get('target') === self;\n });\n };\n /**\n * 获取所有的出边\n */\n\n\n Node.prototype.getOutEdges = function () {\n var self = this;\n return this.get('edges').filter(function (edge) {\n return edge.get('source') === self;\n });\n };\n /**\n * 获取节点的邻居节点\n *\n * @returns {INode[]}\n * @memberof Node\n */\n\n\n Node.prototype.getNeighbors = function (type) {\n var _this = this;\n\n var edges = this.get('edges');\n\n if (type === 'target') {\n // 当前节点为 source,它所指向的目标节点\n var neighhborsConverter_1 = function neighhborsConverter_1(edge) {\n return edge.getSource() === _this;\n };\n\n return edges.filter(neighhborsConverter_1).map(function (edge) {\n return edge.getTarget();\n });\n }\n\n if (type === 'source') {\n // 当前节点为 target,它所指向的源节点\n var neighhborsConverter_2 = function neighhborsConverter_2(edge) {\n return edge.getTarget() === _this;\n };\n\n return edges.filter(neighhborsConverter_2).map(function (edge) {\n return edge.getSource();\n });\n } // 若未指定 type ,则返回所有邻居\n\n\n var neighhborsConverter = function neighhborsConverter(edge) {\n return edge.getSource() === _this ? edge.getTarget() : edge.getSource();\n };\n\n return edges.map(neighhborsConverter);\n };\n /**\n * 根据锚点的索引获取连接点\n * @param {Number} index 索引\n */\n\n\n Node.prototype.getLinkPointByAnchor = function (index) {\n var anchorPoints = this.getAnchorPoints();\n return anchorPoints[index];\n };\n /**\n * 获取连接点\n * @param point\n */\n\n\n Node.prototype.getLinkPoint = function (point) {\n var keyShape = this.get('keyShape');\n var type = keyShape.get('type');\n var itemType = this.get('type');\n var centerX;\n var centerY;\n var bbox = this.getBBox();\n\n if (itemType === 'combo') {\n centerX = bbox.centerX || (bbox.maxX + bbox.minX) / 2;\n centerY = bbox.centerY || (bbox.maxY + bbox.minY) / 2;\n } else {\n centerX = bbox.centerX;\n centerY = bbox.centerY;\n }\n\n var anchorPoints = this.getAnchorPoints();\n var intersectPoint;\n\n switch (type) {\n case 'circle':\n intersectPoint = getCircleIntersectByPoint({\n x: centerX,\n y: centerY,\n r: bbox.width / 2\n }, point);\n break;\n\n case 'ellipse':\n intersectPoint = getEllipseIntersectByPoint({\n x: centerX,\n y: centerY,\n rx: bbox.width / 2,\n ry: bbox.height / 2\n }, point);\n break;\n\n default:\n intersectPoint = getRectIntersectByPoint(bbox, point);\n }\n\n var linkPoint = intersectPoint; // 如果存在锚点,则使用交点计算最近的锚点\n\n if (anchorPoints.length) {\n if (!linkPoint) {\n // 如果计算不出交点\n linkPoint = point;\n }\n\n linkPoint = this.getNearestPoint(anchorPoints, linkPoint);\n }\n\n if (!linkPoint) {\n // 如果最终依然没法找到锚点和连接点,直接返回中心点\n linkPoint = {\n x: centerX,\n y: centerY\n };\n }\n\n return linkPoint;\n };\n /**\n * 获取锚点的定义\n * @return {array} anchorPoints\n */\n\n\n Node.prototype.getAnchorPoints = function () {\n var anchorPoints = this.get(CACHE_ANCHOR_POINTS);\n\n if (!anchorPoints) {\n anchorPoints = [];\n var shapeFactory = this.get('shapeFactory');\n var bbox_1 = this.getBBox();\n var model = this.get('model');\n var shapeCfg = this.getShapeCfg(model);\n var type = model.type;\n var points = shapeFactory.getAnchorPoints(type, shapeCfg) || [];\n Object(esm[\"each\"])(points, function (pointArr, index) {\n var point = {\n x: bbox_1.minX + pointArr[0] * bbox_1.width,\n y: bbox_1.minY + pointArr[1] * bbox_1.height,\n anchorIndex: index\n };\n anchorPoints.push(point);\n });\n this.set(CACHE_ANCHOR_POINTS, anchorPoints);\n }\n\n return anchorPoints;\n };\n /**\n * add edge\n * @param edge Edge instance\n */\n\n\n Node.prototype.addEdge = function (edge) {\n this.get('edges').push(edge);\n };\n /**\n * 锁定节点\n */\n\n\n Node.prototype.lock = function () {\n this.set('locked', true);\n };\n /**\n * 解锁锁定的节点\n */\n\n\n Node.prototype.unlock = function () {\n this.set('locked', false);\n };\n\n Node.prototype.hasLocked = function () {\n return this.get('locked');\n };\n /**\n * 移除边\n * @param {Edge} edge 边\n */\n\n\n Node.prototype.removeEdge = function (edge) {\n var edges = this.getEdges();\n var index = edges.indexOf(edge);\n if (index > -1) edges.splice(index, 1);\n };\n\n Node.prototype.clearCache = function () {\n this.set(node_CACHE_BBOX, null); // 清理缓存的 bbox\n\n this.set(CACHE_ANCHOR_POINTS, null);\n };\n /**\n * 判断更新的种类,move 表示仅移动,bbox 表示大小有变化,style 表示仅与大小无关的参数变化\n * @param cfg 节点数据模型\n */\n\n\n Node.prototype.getUpdateType = function (cfg) {\n var _a, _b, _c, _d, _e;\n\n if (!cfg) return undefined;\n var existX = !Object(esm[\"isNil\"])(cfg.x);\n var existY = !Object(esm[\"isNil\"])(cfg.y);\n var keys = Object.keys(cfg); // 仅有一个字段,包含 x 或者 包含 y\n // 两个字段,同时有 x,同时有 y\n\n if (keys.length === 1 && (existX || existY) || keys.length === 2 && existX && existY) return 'move';\n if (Object(esm[\"isNumber\"])(cfg.x) || Object(esm[\"isNumber\"])(cfg.y) || cfg.type || cfg.anchorPoints || cfg.size || (cfg === null || cfg === void 0 ? void 0 : cfg.style) && (((_a = cfg === null || cfg === void 0 ? void 0 : cfg.style) === null || _a === void 0 ? void 0 : _a.r) || ((_b = cfg === null || cfg === void 0 ? void 0 : cfg.style) === null || _b === void 0 ? void 0 : _b.width) || ((_c = cfg === null || cfg === void 0 ? void 0 : cfg.style) === null || _c === void 0 ? void 0 : _c.height) || ((_d = cfg === null || cfg === void 0 ? void 0 : cfg.style) === null || _d === void 0 ? void 0 : _d.rx) || ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.style) === null || _e === void 0 ? void 0 : _e.ry))) return 'bbox|label';\n var updateLabel = keys.includes('label') || keys.includes('labelCfg');\n return updateLabel ? 'style|label' : 'style';\n };\n\n return Node;\n}(item_item);\n\n/* harmony default export */ var item_node = (node_Node);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/item/combo.js\n\n\n\n\n\nvar combo_CACHE_BBOX = 'bboxCache';\nvar combo_CACHE_CANVAS_BBOX = 'bboxCanvasCache';\nvar CACHE_SIZE = 'sizeCache';\nvar combo_CACHE_ANCHOR_POINTS = 'anchorPointsCache';\n\nvar combo_Combo =\n/** @class */\nfunction (_super) {\n Object(tslib_es6[\"__extends\"])(Combo, _super);\n\n function Combo() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n\n Combo.prototype.getDefaultCfg = function () {\n return {\n type: 'combo',\n nodes: [],\n edges: [],\n combos: []\n };\n };\n\n Combo.prototype.getShapeCfg = function (model) {\n var styles = this.get('styles');\n var bbox = this.get('bbox');\n\n if (styles && bbox) {\n // merge graph的item样式与数据模型中的样式\n var newModel = model;\n var size = {\n r: Math.hypot(bbox.height, bbox.width) / 2 || global.defaultCombo.size[0] / 2,\n width: bbox.width || global.defaultCombo.size[0],\n height: bbox.height || global.defaultCombo.size[1]\n };\n newModel.style = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), model.style), size);\n var padding = model.padding || global.defaultCombo.padding;\n\n if (Object(esm[\"isNumber\"])(padding)) {\n size.r += padding;\n size.width += padding * 2;\n size.height += padding * 2;\n } else {\n size.r += padding[0];\n size.width += padding[1] + padding[3] || padding[1] * 2;\n size.height += padding[0] + padding[2] || padding[0] * 2;\n }\n\n this.set(CACHE_SIZE, size);\n return newModel;\n }\n\n return model;\n };\n /**\n * 根据 keyshape 计算包围盒\n */\n\n\n Combo.prototype.calculateCanvasBBox = function () {\n if (this.destroyed) return;\n var keyShape = this.get('keyShape');\n var group = this.get('group'); // 因为 group 可能会移动,所以必须通过父元素计算才能计算出正确的包围盒\n\n var bbox = graphic_getBBox(keyShape, group);\n bbox.centerX = (bbox.minX + bbox.maxX) / 2;\n bbox.centerY = (bbox.minY + bbox.maxY) / 2;\n var cacheSize = this.get(CACHE_SIZE);\n var cacheBBox = this.get(combo_CACHE_BBOX) || {};\n var oriX = cacheBBox.x;\n var oriY = cacheBBox.x;\n\n if (cacheSize) {\n cacheSize.width = Math.max(cacheSize.width, bbox.width);\n cacheSize.height = Math.max(cacheSize.height, bbox.height);\n var type = keyShape.get('type');\n\n if (type === 'circle') {\n bbox.width = cacheSize.r * 2;\n bbox.height = cacheSize.r * 2;\n } else {\n bbox.width = cacheSize.width;\n bbox.height = cacheSize.height;\n }\n\n bbox.minX = bbox.centerX - bbox.width / 2;\n bbox.minY = bbox.centerY - bbox.height / 2;\n bbox.maxX = bbox.centerX + bbox.width / 2;\n bbox.maxY = bbox.centerY + bbox.height / 2;\n } else {\n bbox.width = bbox.maxX - bbox.minX;\n bbox.height = bbox.maxY - bbox.minY;\n bbox.centerX = (bbox.minX + bbox.maxX) / 2;\n bbox.centerY = (bbox.minY + bbox.maxY) / 2;\n }\n\n bbox.x = bbox.minX;\n bbox.y = bbox.minY;\n if (bbox.x !== oriX || bbox.y !== oriY) this.set(combo_CACHE_ANCHOR_POINTS, null);\n return bbox;\n };\n /**\n * 获取 Combo 中所有的子元素,包括 Combo、Node 及 Edge\n */\n\n\n Combo.prototype.getChildren = function () {\n var self = this;\n return {\n nodes: self.getNodes(),\n combos: self.getCombos()\n };\n };\n /**\n * 获取 Combo 中所有子节点\n */\n\n\n Combo.prototype.getNodes = function () {\n var self = this;\n return self.get('nodes');\n };\n /**\n * 获取 Combo 中所有子 combo\n */\n\n\n Combo.prototype.getCombos = function () {\n var self = this;\n return self.get('combos');\n };\n /**\n * 向 Combo 中增加子 combo 或 node\n * @param item Combo 或节点实例\n * @return boolean 添加成功返回 true,否则返回 false\n */\n\n\n Combo.prototype.addChild = function (item) {\n var self = this;\n var itemType = item.getType();\n\n switch (itemType) {\n case 'node':\n self.addNode(item);\n break;\n\n case 'combo':\n self.addCombo(item);\n break;\n\n default:\n console.warn('Only node or combo items are allowed to be added into a combo');\n return false;\n }\n\n return true;\n };\n /**\n * 向 Combo 中增加 combo\n * @param combo Combo 实例\n * @return boolean 添加成功返回 true,否则返回 false\n */\n\n\n Combo.prototype.addCombo = function (combo) {\n var self = this;\n self.get('combos').push(combo);\n return true;\n };\n /**\n * 向 Combo 中添加节点\n * @param node 节点实例\n * @return boolean 添加成功返回 true,否则返回 false\n */\n\n\n Combo.prototype.addNode = function (node) {\n var self = this;\n self.get('nodes').push(node);\n return true;\n };\n /**\n * 向 Combo 中增加子 combo 或 node\n * @param item Combo 或节点实例\n * @return boolean 添加成功返回 true,否则返回 false\n */\n\n\n Combo.prototype.removeChild = function (item) {\n var self = this;\n var itemType = item.getType();\n\n switch (itemType) {\n case 'node':\n self.removeNode(item);\n break;\n\n case 'combo':\n self.removeCombo(item);\n break;\n\n default:\n console.warn('Only node or combo items are allowed to be added into a combo');\n return false;\n }\n\n return true;\n };\n /**\n * 从 Combo 中移除指定的 combo\n * @param combo Combo 实例\n * @return boolean 移除成功返回 true,否则返回 false\n */\n\n\n Combo.prototype.removeCombo = function (combo) {\n if (!combo) return;\n var combos = this.getCombos();\n var index = combos.indexOf(combo);\n\n if (index > -1) {\n combos.splice(index, 1);\n return true;\n }\n\n return false;\n };\n /**\n * 向 Combo 中移除指定的节点\n * @param node 节点实例\n * @return boolean 移除成功返回 true,否则返回 false\n */\n\n\n Combo.prototype.removeNode = function (node) {\n if (!node) return;\n var nodes = this.getNodes();\n var index = nodes.indexOf(node);\n\n if (index > -1) {\n nodes.splice(index, 1);\n return true;\n }\n\n return false;\n };\n\n Combo.prototype.getUpdateType = function (cfg) {\n return undefined;\n };\n /**\n * 获取 item 的包围盒,这个包围盒是相对于 item 自己,不会将 matrix 计算在内\n * @return {Object} 包含 x,y,width,height, centerX, centerY\n */\n\n\n Combo.prototype.getBBox = function () {\n this.set(combo_CACHE_CANVAS_BBOX, null);\n var bbox = this.calculateCanvasBBox();\n return bbox;\n };\n\n Combo.prototype.clearCache = function () {\n this.set(combo_CACHE_BBOX, null); // 清理缓存的 bbox\n\n this.set(combo_CACHE_CANVAS_BBOX, null);\n this.set(combo_CACHE_ANCHOR_POINTS, null);\n };\n\n Combo.prototype.destroy = function () {\n if (!this.destroyed) {\n var animate = this.get('animate');\n var group = this.get('group');\n\n if (animate) {\n group.stopAnimate();\n }\n\n group['shapeMap'] = {};\n this.clearCache();\n this.set(CACHE_SIZE, null);\n this.set('bbox', null);\n group.remove();\n this._cfg = null;\n this.destroyed = true;\n }\n };\n\n return Combo;\n}(item_node);\n\n/* harmony default export */ var item_combo = (combo_Combo);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/item.js\n\n\n\n\n\n\nvar NODE = 'node';\nvar EDGE = 'edge';\nvar VEDGE = 'vedge';\nvar COMBO = 'combo';\nvar CFG_PREFIX = 'default';\nvar MAPPER_SUFFIX = 'Mapper';\nvar STATE_SUFFIX = 'stateStyles';\n\nvar item_ItemController =\n/** @class */\nfunction () {\n function ItemController(graph) {\n var _this = this;\n\n this.edgeToBeUpdateMap = {};\n /**\n * 更新边限流,同时可以防止相同的边频繁重复更新\n * */\n\n this.throttleRefresh = Object(esm[\"throttle\"])(function (_) {\n var _a;\n\n var graph = _this.graph;\n if (!graph || graph.get('destroyed')) return;\n var edgeToBeUpdateMap = _this.edgeToBeUpdateMap;\n if (!edgeToBeUpdateMap || !((_a = Object.keys(edgeToBeUpdateMap)) === null || _a === void 0 ? void 0 : _a.length)) return;\n Object.keys(edgeToBeUpdateMap).forEach(function (eid) {\n var edge = edgeToBeUpdateMap[eid].edge;\n if (!edge || edge.destroyed) return;\n edge.refresh(edgeToBeUpdateMap[eid].updateType);\n });\n _this.edgeToBeUpdateMap = {};\n }, 16, {\n trailing: true,\n leading: true\n });\n this.graph = graph;\n this.destroyed = false;\n }\n /**\n * 增加 Item 实例\n *\n * @param {ITEM_TYPE} type 实例类型,node 或 edge\n * @param {(NodeConfig & EdgeConfig)} model 数据模型\n * @returns {(Item)}\n * @memberof ItemController\n */\n\n\n ItemController.prototype.addItem = function (type, model) {\n var graph = this.graph;\n var vType = type === VEDGE ? EDGE : type;\n var parent = graph.get(vType + \"Group\") || graph.get('group');\n var upperType = Object(esm[\"upperFirst\"])(vType);\n var item = null; // 获取 this.get('styles') 中的值\n\n var styles = graph.get(vType + Object(esm[\"upperFirst\"])(STATE_SUFFIX)) || {};\n var defaultModel = graph.get(CFG_PREFIX + upperType);\n\n if (model[STATE_SUFFIX]) {\n // 设置 this.get('styles') 中的值\n styles = model[STATE_SUFFIX];\n }\n\n if (defaultModel) {\n // 很多布局会直接修改原数据模型,所以不能用 merge 的形式,逐个写入原 model 中\n Object(esm[\"each\"])(defaultModel, function (val, cfg) {\n if (Object(esm[\"isObject\"])(val) && !Object(esm[\"isArray\"])(val)) {\n model[cfg] = Object(esm[\"deepMix\"])({}, val, model[cfg]);\n } else if (Object(esm[\"isArray\"])(val)) {\n model[cfg] = model[cfg] || Object(esm[\"clone\"])(defaultModel[cfg]);\n } else {\n model[cfg] = model[cfg] || defaultModel[cfg];\n }\n });\n }\n\n var mapper = graph.get(vType + MAPPER_SUFFIX);\n\n if (mapper) {\n var mappedModel_1 = mapper(model);\n\n if (mappedModel_1[STATE_SUFFIX]) {\n // 设置 this.get('styles') 中的值\n styles = mappedModel_1[STATE_SUFFIX];\n delete mappedModel_1[STATE_SUFFIX];\n } // 如果配置了 defaultEdge 或 defaultNode,则将默认配置的数据也合并进去\n\n\n Object(esm[\"each\"])(mappedModel_1, function (val, cfg) {\n if (Object(esm[\"isObject\"])(val) && !Object(esm[\"isArray\"])(val)) {\n model[cfg] = Object(esm[\"deepMix\"])({}, model[cfg], val);\n } else {\n model[cfg] = mappedModel_1[cfg] || model[cfg];\n }\n });\n }\n\n graph.emit('beforeadditem', {\n type: type,\n model: model\n });\n\n if (type === EDGE || type === VEDGE) {\n var source = void 0;\n var target = void 0;\n source = model.source; // eslint-disable-line prefer-destructuring\n\n target = model.target; // eslint-disable-line prefer-destructuring\n\n if (source && Object(esm[\"isString\"])(source)) {\n source = graph.findById(source);\n }\n\n if (target && Object(esm[\"isString\"])(target)) {\n target = graph.findById(target);\n }\n\n if (!source || !target) {\n console.warn(\"The source or target node of edge \" + model.id + \" does not exist!\");\n return;\n }\n\n if (source.getType && source.getType() === 'combo') {\n model.isComboEdge = true; // graph.updateCombo(source as ICombo);\n }\n\n if (target.getType && target.getType() === 'combo') {\n model.isComboEdge = true; // graph.updateCombo(target as ICombo);\n }\n\n item = new item_edge({\n model: model,\n source: source,\n target: target,\n styles: styles,\n linkCenter: graph.get('linkCenter'),\n group: parent.addGroup()\n });\n } else if (type === NODE) {\n item = new item_node({\n model: model,\n styles: styles,\n group: parent.addGroup()\n });\n } else if (type === COMBO) {\n var children = model.children;\n var comboBBox = getComboBBox(children, graph);\n if (!isNaN(comboBBox.x)) model.x = comboBBox.x;else if (isNaN(model.x)) model.x = Math.random() * 100;\n if (!isNaN(comboBBox.y)) model.y = comboBBox.y;else if (isNaN(model.y)) model.y = Math.random() * 100;\n var comboGroup = parent.addGroup();\n comboGroup.setZIndex(model.depth);\n item = new item_combo({\n model: model,\n styles: styles,\n bbox: model.collapsed ? getComboBBox([], graph) : comboBBox,\n group: comboGroup\n });\n var comboModel_1 = item.getModel();\n (children || []).forEach(function (child) {\n var childItem = graph.findById(child.id);\n item.addChild(childItem);\n child.depth = comboModel_1.depth + 2;\n }); // collapse the combo if the collapsed is true in the model\n\n if (model.collapsed) {\n setTimeout(function () {\n if (!item.destroyed) {\n graph.collapseCombo(item);\n }\n }, 0);\n }\n }\n\n if (item) {\n graph.get(type + \"s\").push(item);\n graph.get('itemMap')[item.get('id')] = item;\n graph.emit('afteradditem', {\n item: item,\n model: model\n }); // eslint-disable-next-line consistent-return\n\n return item;\n }\n };\n /**\n * 更新节点或边\n *\n * @param {Item} item ID 或 实例\n * @param {(EdgeConfig | Partial)} cfg 数据模型\n * @returns\n * @memberof ItemController\n */\n\n\n ItemController.prototype.updateItem = function (item, cfg) {\n var _this = this;\n\n var _a, _b;\n\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(item)) {\n item = graph.findById(item);\n }\n\n if (!item || item.destroyed) {\n return;\n } // 更新的 item 的类型\n\n\n var type = '';\n if (item.getType) type = item.getType();\n var mapper = graph.get(type + MAPPER_SUFFIX);\n var model = item.getModel();\n var updateType = item.getUpdateType(cfg);\n\n if (mapper) {\n var result = Object(esm[\"deepMix\"])({}, model, cfg);\n var mappedModel = mapper(result); // 将 update 时候用户传入的参数与mapperModel做deepMix,以便复用之前设置的参数值\n\n var newModel = Object(esm[\"deepMix\"])({}, model, mappedModel, cfg);\n\n if (mappedModel[STATE_SUFFIX]) {\n item.set('styles', newModel[STATE_SUFFIX]);\n delete newModel[STATE_SUFFIX];\n }\n\n Object(esm[\"each\"])(newModel, function (val, key) {\n cfg[key] = val;\n });\n } else {\n // merge update传进来的对象参数,model中没有的数据不做处理,对象和字符串值也不做处理,直接替换原来的\n Object(esm[\"each\"])(cfg, function (val, key) {\n if (model[key]) {\n if (Object(esm[\"isObject\"])(val) && !Object(esm[\"isArray\"])(val)) {\n cfg[key] = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, model[key]), cfg[key]);\n }\n }\n });\n } // emit beforeupdateitem 事件\n\n\n graph.emit('beforeupdateitem', {\n item: item,\n cfg: cfg\n });\n\n if (type === EDGE) {\n // 若是边要更新source || target, 为了不影响示例内部model,并且重新计算startPoint和endPoint,手动设置\n if (cfg.source) {\n var source = cfg.source;\n\n if (Object(esm[\"isString\"])(source)) {\n source = graph.findById(source);\n }\n\n item.setSource(source);\n }\n\n if (cfg.target) {\n var target = cfg.target;\n\n if (Object(esm[\"isString\"])(target)) {\n target = graph.findById(target);\n }\n\n item.setTarget(target);\n }\n\n item.update(cfg);\n } // item.update(cfg);\n\n\n if (type === NODE || type === COMBO) {\n item.update(cfg, updateType);\n var edges_1 = item.getEdges();\n var refreshEdge = (updateType === null || updateType === void 0 ? void 0 : updateType.includes('bbox')) || updateType === 'move';\n\n if (type === NODE) {\n if (updateType === 'move') {\n Object(esm[\"each\"])(edges_1, function (edge) {\n _this.edgeToBeUpdateMap[edge.getID()] = {\n edge: edge,\n updateType: updateType\n };\n\n _this.throttleRefresh();\n });\n } else if (refreshEdge) {\n Object(esm[\"each\"])(edges_1, function (edge) {\n edge.refresh(updateType);\n });\n }\n } else if (refreshEdge && type === COMBO) {\n var shapeFactory = item.get('shapeFactory');\n var shapeType = model.type || 'circle';\n var comboAnimate = model.animate === undefined || cfg.animate === undefined ? (_b = (_a = shapeFactory[shapeType]) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.animate : model.animate || cfg.animate;\n\n if (comboAnimate) {\n setTimeout(function () {\n if (!item || item.destroyed) return;\n var keyShape = item.getKeyShape();\n if (!keyShape || keyShape.destroyed) return;\n Object(esm[\"each\"])(edges_1, function (edge) {\n if (edge && !edge.destroyed) edge.refresh();\n });\n }, 201);\n } else {\n Object(esm[\"each\"])(edges_1, function (edge) {\n edge.refresh();\n });\n }\n }\n }\n\n graph.emit('afterupdateitem', {\n item: item,\n cfg: cfg\n });\n };\n /**\n * 根据 combo 的子元素更新 combo 的位置及大小\n *\n * @param {ICombo} combo ID 或 实例\n * @returns\n * @memberof ItemController\n */\n\n\n ItemController.prototype.updateCombo = function (combo, children) {\n var _this = this;\n\n var _a, _b;\n\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(combo)) {\n combo = graph.findById(combo);\n }\n\n if (!combo || combo.destroyed) {\n return;\n }\n\n var model = combo.getModel();\n var comboBBox = getComboBBox(model.collapsed ? [] : children, graph);\n\n var _c = model.collapsed ? getComboBBox(children, graph) : comboBBox,\n comboX = _c.x,\n comboY = _c.y;\n\n combo.set('bbox', comboBBox);\n combo.update({\n x: comboX,\n y: comboY\n });\n var shapeFactory = combo.get('shapeFactory');\n var shapeType = model.type || 'circle';\n var comboAnimate = model.animate === undefined ? (_b = (_a = shapeFactory[shapeType]) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.animate : model.animate;\n\n if (comboAnimate) {\n setTimeout(function () {\n if (!combo || combo.destroyed) return;\n var keyShape = combo.getKeyShape();\n if (!keyShape || keyShape.destroyed) return;\n combo.getShapeCfg(model); // 更新 combo 缓存的 size\n\n _this.updateComboEdges(combo);\n }, 201);\n } else {\n this.updateComboEdges(combo);\n }\n };\n\n ItemController.prototype.updateComboEdges = function (combo) {\n var combEdges = combo.getEdges() || [];\n\n for (var i = 0; i < combEdges.length; i++) {\n var edge = combEdges[i];\n\n if (edge && !edge.destroyed) {\n var edgeSF = edge.get('shapeFactory');\n var edgeCfg = edge.getShapeCfg(edge.getModel());\n var edgeGroup = edge.getContainer();\n edgeGroup.clear();\n var keyShape = edgeSF.draw(edgeCfg.type, edgeCfg, edgeGroup);\n edge.set('keyShape', keyShape);\n keyShape.set('isKeyShape', true);\n keyShape.set('draggable', true);\n edge.setOriginStyle();\n }\n }\n };\n /**\n * 收起 combo,隐藏相关元素\n */\n\n\n ItemController.prototype.collapseCombo = function (combo) {\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(combo)) {\n combo = graph.findById(combo);\n }\n\n var children = combo.getChildren();\n children.nodes.forEach(function (node) {\n graph.hideItem(node);\n });\n children.combos.forEach(function (c) {\n graph.hideItem(c);\n });\n };\n /**\n * 展开 combo,相关元素出现\n * 若子 combo 原先是收起状态,则保持它的收起状态\n */\n\n\n ItemController.prototype.expandCombo = function (combo) {\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(combo)) {\n combo = graph.findById(combo);\n }\n\n var children = combo.getChildren();\n children.nodes.forEach(function (node) {\n graph.showItem(node);\n });\n children.combos.forEach(function (c) {\n if (c.getModel().collapsed) {\n c.show();\n } else {\n graph.showItem(c);\n }\n });\n };\n /**\n * 删除指定的节点或边\n *\n * @param {Item} item item ID 或实例\n * @returns {void}\n * @memberof ItemController\n */\n\n\n ItemController.prototype.removeItem = function (item) {\n var _this = this;\n\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(item)) {\n item = graph.findById(item);\n }\n\n if (!item || item.destroyed) {\n return;\n }\n\n var itemModel = Object(esm[\"clone\"])(item.getModel());\n graph.emit('beforeremoveitem', {\n item: itemModel\n });\n var type = '';\n if (item.getType) type = item.getType();\n var items = graph.get(type + \"s\");\n var index = items.indexOf(item);\n if (index > -1) items.splice(index, 1);\n\n if (type === EDGE) {\n var vitems = graph.get(\"v\" + type + \"s\");\n var vindex = vitems.indexOf(item);\n if (vindex > -1) vitems.splice(vindex, 1);\n }\n\n var itemId = item.get('id');\n var itemMap = graph.get('itemMap');\n delete itemMap[itemId];\n var comboTrees = graph.get('comboTrees');\n var id = item.get('id');\n\n if (type === NODE) {\n var comboId = item.getModel().comboId;\n\n if (comboTrees && comboId) {\n var brothers_1 = comboTrees;\n var found_1 = false; // the flag to terminate the forEach circulation\n // remove the node from the children array of its parent fromt he tree\n\n comboTrees.forEach(function (ctree) {\n if (found_1) return;\n traverseTree(ctree, function (combo) {\n if (combo.id === id && brothers_1) {\n var bidx = brothers_1.indexOf(combo);\n brothers_1.splice(bidx, 1);\n found_1 = true;\n return false; // terminate the traverse\n }\n\n brothers_1 = combo.children;\n return true;\n });\n });\n } // 若移除的是节点,需要将与之相连的边一同删除\n\n\n var edges = item.getEdges();\n\n for (var i = edges.length - 1; i >= 0; i--) {\n graph.removeItem(edges[i], false);\n }\n\n if (comboId) graph.updateCombo(comboId);\n } else if (type === COMBO) {\n var parentId = item.getModel().parentId;\n var comboInTree_1; // find the subtree rooted at the item to be removed\n\n var found_2 = false; // the flag to terminate the forEach circulation\n\n (comboTrees || []).forEach(function (ctree) {\n if (found_2) return;\n traverseTree(ctree, function (combo) {\n if (combo.id === id) {\n comboInTree_1 = combo;\n found_2 = true;\n return false; // terminate the traverse\n }\n\n return true;\n });\n });\n comboInTree_1.removed = true;\n\n if (comboInTree_1 && comboInTree_1.children) {\n comboInTree_1.children.forEach(function (child) {\n _this.removeItem(child.id);\n });\n } // 若移除的是 combo,需要将与之相连的边一同删除\n\n\n var edges = item.getEdges();\n\n for (var i = edges.length; i >= 0; i--) {\n graph.removeItem(edges[i], false);\n }\n\n if (parentId) graph.updateCombo(parentId);\n }\n\n item.destroy();\n graph.emit('afterremoveitem', {\n item: itemModel\n });\n };\n /**\n * 更新 item 状态\n *\n * @param {Item} item Item 实例\n * @param {string} state 状态名称\n * @param {boolean} value 是否启用状态或状态值\n * @returns {void}\n * @memberof ItemController\n */\n\n\n ItemController.prototype.setItemState = function (item, state, value) {\n var graph = this.graph;\n var stateName = state;\n\n if (Object(esm[\"isString\"])(value)) {\n stateName = state + \":\" + value;\n } // 已经存在要设置的 state,或不存在 state 的样式为 undefined\n\n\n if (item.hasState(stateName) === value && value || // 当该状态已经存在且现在需要设置为 true 时,不需要继续。当该状态不存在,且设置为 false 时,需要继续\n Object(esm[\"isString\"])(value) && item.hasState(stateName)) {\n // 当该状态 value 是字符串,且已经存在该状态,不需要继续\n return;\n }\n\n graph.emit('beforeitemstatechange', {\n item: item,\n state: stateName,\n enabled: value\n });\n item.setState(state, value);\n graph.autoPaint();\n graph.emit('afteritemstatechange', {\n item: item,\n state: stateName,\n enabled: value\n });\n };\n /**\n * 将指定状态的优先级提升为最高优先级\n * @param {Item} item 元素id或元素实例\n * @param state 状态名称\n */\n\n\n ItemController.prototype.priorityState = function (item, state) {\n var graph = this.graph;\n var currentItem = item;\n\n if (Object(esm[\"isString\"])(item)) {\n currentItem = graph.findById(item);\n } // 先取消已有的 state\n\n\n this.setItemState(currentItem, state, false); // 再设置state,则此时该优先级为最高\n\n this.setItemState(currentItem, state, true);\n };\n /**\n * 清除所有指定的状态\n *\n * @param {Item} item Item 实例\n * @param {string[]} states 状态名称集合\n * @memberof ItemController\n */\n\n\n ItemController.prototype.clearItemStates = function (item, states) {\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(item)) {\n item = graph.findById(item);\n }\n\n graph.emit('beforeitemstatesclear', {\n item: item,\n states: states\n });\n item.clearStates(states);\n graph.emit('afteritemstatesclear', {\n item: item,\n states: states\n });\n };\n /**\n * 刷新指定的 Item\n *\n * @param {Item} item Item ID 或 实例\n * @memberof ItemController\n */\n\n\n ItemController.prototype.refreshItem = function (item) {\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(item)) {\n item = graph.findById(item);\n }\n\n graph.emit('beforeitemrefresh', {\n item: item\n }); // 调用 Item 的 refresh 方法,实现刷新功能\n\n item.refresh();\n graph.emit('afteritemrefresh', {\n item: item\n });\n };\n /**\n * 根据 graph 上用 combos 数据生成的 comboTree 来增加所有 combos\n *\n * @param {ComboTree[]} comboTrees graph 上用 combos 数据生成的 comboTree\n * @param {ComboConfig[]} comboModels combos 数据\n * @memberof ItemController\n */\n\n\n ItemController.prototype.addCombos = function (comboTrees, comboModels) {\n var _this = this;\n\n var graph = this.graph;\n (comboTrees || []).forEach(function (ctree) {\n traverseTreeUp(ctree, function (child) {\n var comboModel;\n comboModels.forEach(function (model) {\n if (model.id === child.id) {\n model.children = child.children;\n model.depth = child.depth;\n comboModel = model;\n }\n });\n\n if (comboModel) {\n _this.addItem('combo', comboModel);\n }\n\n return true;\n });\n });\n var comboGroup = graph.get('comboGroup');\n if (comboGroup) comboGroup.sort();\n };\n /**\n * 改变Item的显示状态\n *\n * @param {Item} item Item ID 或 实例\n * @param {boolean} visible 是否显示\n * @memberof ItemController\n */\n\n\n ItemController.prototype.changeItemVisibility = function (item, visible) {\n var _this = this;\n\n var graph = this.graph;\n\n if (Object(esm[\"isString\"])(item)) {\n item = graph.findById(item);\n }\n\n if (!item) {\n console.warn('The item to be shown or hidden does not exist!');\n return;\n }\n\n graph.emit('beforeitemvisibilitychange', {\n item: item,\n visible: visible\n });\n item.changeVisibility(visible);\n\n if (item.getType && item.getType() === NODE) {\n var edges = item.getEdges();\n Object(esm[\"each\"])(edges, function (edge) {\n // 若隐藏节点,则将与之关联的边也隐藏\n // 若显示节点,则将与之关联的边也显示,但是需要判断边两端的节点都是可见的\n if (visible && !(edge.get('source').isVisible() && edge.get('target').isVisible())) {\n return;\n }\n\n _this.changeItemVisibility(edge, visible);\n });\n } else if (item.getType && item.getType() === COMBO) {\n var comboTrees = graph.get('comboTrees');\n var id_1 = item.get('id');\n var children_1 = [];\n var found_3 = false; // flag the terminate the forEach\n\n (comboTrees || []).forEach(function (ctree) {\n if (found_3) return;\n if (!ctree.children || ctree.children.length === 0) return;\n traverseTree(ctree, function (combo) {\n if (combo.id === id_1) {\n children_1 = combo.children;\n found_3 = true;\n return false; // terminate the traverse\n }\n\n return true;\n });\n });\n\n if (children_1 && (!visible || visible && !item.getModel().collapsed)) {\n children_1.forEach(function (child) {\n var childItem = graph.findById(child.id);\n\n _this.changeItemVisibility(childItem, visible);\n });\n }\n\n var edges = item.getEdges();\n Object(esm[\"each\"])(edges, function (edge) {\n // 若隐藏 combo,则将与 combo 本身关联的边也隐藏\n // 若显示 combo,则将与 combo 本身关联的边也显示,但是需要判断边两端的节点都是可见的\n if (visible && !(edge.get('source').isVisible() && edge.get('target').isVisible())) {\n return;\n }\n\n _this.changeItemVisibility(edge, visible);\n });\n }\n\n graph.emit('afteritemvisibilitychange', {\n item: item,\n visible: visible\n });\n return item;\n };\n\n ItemController.prototype.destroy = function () {\n this.graph = null;\n this.destroyed = true;\n };\n\n return ItemController;\n}();\n\n/* harmony default export */ var controller_item = (item_ItemController);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/state.js\n\nvar timer = null;\n\nvar state_StateController =\n/** @class */\nfunction () {\n function StateController(graph) {\n this.graph = graph;\n /**\n * this.cachedStates = {\n * enabled: {\n * hover: [Node]\n * },\n * disabled: {}\n * }\n */\n\n this.cachedStates = {\n enabled: {},\n disabled: {}\n };\n this.destroyed = false;\n }\n /**\n * 检查 cache 的可用性\n *\n * @private\n * @param {Item} item\n * @param {string} state\n * @param {object} cache\n * @returns\n * @memberof State\n */\n\n\n StateController.checkCache = function (item, state, cache) {\n if (!cache[state]) {\n return;\n }\n\n var index = cache[state].indexOf(item);\n\n if (index >= 0) {\n cache[state].splice(index, 1);\n }\n };\n /**\n * 缓存 state\n *\n * @private\n * @param {Item} item Item 实例\n * @param {string} state 状态名称\n * @param {object} states\n * @memberof State\n */\n\n\n StateController.cacheState = function (item, state, states) {\n if (!states[state]) {\n states[state] = [];\n }\n\n states[state].push(item);\n };\n /**\n * 更新 Item 的状态\n *\n * @param {Item} item Item实例\n * @param {string} state 状态名称\n * @param {boolean} enabled 状态是否可用\n * @memberof State\n */\n\n\n StateController.prototype.updateState = function (item, state, enabled) {\n var _this = this;\n\n var checkCache = StateController.checkCache,\n cacheState = StateController.cacheState;\n\n if (item.destroyed) {\n return;\n }\n\n var cachedStates = this.cachedStates;\n var enabledStates = cachedStates.enabled;\n var disabledStates = cachedStates.disabled;\n\n if (enabled) {\n checkCache(item, state, disabledStates);\n cacheState(item, state, enabledStates);\n } else {\n checkCache(item, state, enabledStates);\n cacheState(item, state, disabledStates);\n }\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(function () {\n timer = null;\n\n _this.updateGraphStates();\n }, 16);\n };\n /**\n * 批量更新 states,兼容 updateState,支持更新一个 state\n *\n * @param {Item} item\n * @param {(string | string[])} states\n * @param {boolean} enabled\n * @memberof State\n */\n\n\n StateController.prototype.updateStates = function (item, states, enabled) {\n var _this = this;\n\n if (Object(esm[\"isString\"])(states)) {\n this.updateState(item, states, enabled);\n } else {\n states.forEach(function (state) {\n _this.updateState(item, state, enabled);\n });\n }\n };\n /**\n * 更新 states\n *\n * @memberof State\n */\n\n\n StateController.prototype.updateGraphStates = function () {\n var states = this.graph.get('states');\n var cachedStates = this.cachedStates;\n Object(esm[\"each\"])(cachedStates.disabled, function (val, key) {\n if (states[key]) {\n states[key] = states[key].filter(function (item) {\n return val.indexOf(item) < 0 && !val.destroyed;\n });\n }\n });\n Object(esm[\"each\"])(cachedStates.enabled, function (val, key) {\n if (!states[key]) {\n states[key] = val;\n } else {\n var map_1 = {};\n states[key].forEach(function (item) {\n if (!item.destroyed) {\n map_1[item.get('id')] = true;\n }\n });\n val.forEach(function (item) {\n if (!item.destroyed) {\n var id = item.get('id');\n\n if (!map_1[id]) {\n map_1[id] = true;\n states[key].push(item);\n }\n }\n });\n }\n });\n this.graph.emit('graphstatechange', {\n states: states\n });\n this.cachedStates = {\n enabled: {},\n disabled: {}\n };\n };\n\n StateController.prototype.destroy = function () {\n this.graph = null;\n this.cachedStates = null;\n\n if (timer) {\n clearTimeout(timer);\n }\n\n timer = null;\n this.destroyed = true;\n };\n\n return StateController;\n}();\n\n/* harmony default export */ var controller_state = (state_StateController);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/index.js\n\n\n\n\n// EXTERNAL MODULE: ./node_modules/@antv/path-util/esm/index.js + 22 modules\nvar path_util_esm = __webpack_require__(37);\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/path.js\n\n\n/**\n * 替换字符串中的字段\n * @param {String} str 模版字符串\n * @param {Object} o json data\n */\n\nvar substitute = function substitute(str, o) {\n if (!str || !o) {\n return str;\n }\n\n return str.replace(/\\\\?\\{([^{}]+)\\}/g, function (match, name) {\n if (match.charAt(0) === '\\\\') {\n return match.slice(1);\n }\n\n var res = o[name];\n if (res === 0) res = '0';\n return res || '';\n });\n};\n/**\n * 给定坐标获取三次贝塞尔曲线的 M 及 C 值\n * @param points coordinate set\n */\n\n\nvar path_getSpline = function getSpline(points) {\n var data = [];\n\n if (points.length < 2) {\n throw new Error(\"point length must largn than 2, now it's \" + points.length);\n }\n\n for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {\n var point = points_1[_i];\n var x = point.x,\n y = point.y;\n data.push(x);\n data.push(y);\n }\n\n var spliePath = Object(path_util_esm[\"a\" /* catmullRom2Bezier */])(data);\n spliePath.unshift(['M', points[0].x, points[0].y]);\n return spliePath;\n};\n/**\n * 根据起始点、相对位置、偏移量计算控制点\n * @param {IPoint} startPoint 起始点,包含 x,y\n * @param {IPoint} endPoint 结束点, 包含 x,y\n * @param {Number} percent 相对位置,范围 0-1\n * @param {Number} offset 偏移量\n * @return {IPoint} 控制点,包含 x,y\n */\n\nvar path_getControlPoint = function getControlPoint(startPoint, endPoint, percent, offset) {\n if (percent === void 0) {\n percent = 0;\n }\n\n if (offset === void 0) {\n offset = 0;\n }\n\n var point = {\n x: (1 - percent) * startPoint.x + percent * endPoint.x,\n y: (1 - percent) * startPoint.y + percent * endPoint.y\n };\n var tangent = [0, 0];\n matrix_util_esm[\"vec2\"].normalize(tangent, [endPoint.x - startPoint.x, endPoint.y - startPoint.y]);\n\n if (!tangent || !tangent[0] && !tangent[1]) {\n tangent = [0, 0];\n }\n\n var perpendicular = [-tangent[1] * offset, tangent[0] * offset]; // 垂直向量\n\n point.x += perpendicular[0];\n point.y += perpendicular[1];\n return point;\n};\n/**\n * 点集转化为Path多边形\n * @param {Array} points 点集\n * @param {Boolen} z 是否封闭\n * @return {Array} Path\n */\n\nvar pointsToPolygon = function pointsToPolygon(points, z) {\n var length = points.length;\n\n if (!length) {\n return '';\n }\n\n var path = '';\n var str = '';\n\n for (var i = 0; i < length; i++) {\n var item = points[i];\n\n if (i === 0) {\n str = 'M{x} {y}';\n } else {\n str = 'L{x} {y}';\n }\n\n path += substitute(str, item);\n }\n\n if (z) {\n path += 'Z';\n }\n\n return path;\n};\nvar pathToPoints = function pathToPoints(path) {\n var points = [];\n path.forEach(function (seg) {\n var command = seg[0];\n\n if (command !== 'A') {\n for (var i = 1; i < seg.length; i = i + 2) {\n points.push([seg[i], seg[i + 1]]);\n }\n } else {\n var length_1 = seg.length;\n points.push([seg[length_1 - 2], seg[length_1 - 1]]);\n }\n });\n return points;\n};\n/**\n * 生成平滑的闭合曲线\n * @param points\n */\n\nvar getClosedSpline = function getClosedSpline(points) {\n if (points.length < 2) {\n throw new Error(\"point length must largn than 2, now it's \" + points.length);\n }\n\n var first = points[0];\n var second = points[1];\n var last = points[points.length - 1];\n var lastSecond = points[points.length - 2];\n points.unshift(last);\n points.unshift(lastSecond);\n points.push(first);\n points.push(second);\n var closedPath = [];\n\n for (var i = 1; i < points.length - 2; i += 1) {\n var x0 = points[i - 1].x;\n var y0 = points[i - 1].y;\n var x1 = points[i].x;\n var y1 = points[i].y;\n var x2 = points[i + 1].x;\n var y2 = points[i + 1].y;\n var x3 = i !== points.length - 2 ? points[i + 2].x : x2;\n var y3 = i !== points.length - 2 ? points[i + 2].y : y2;\n var cp1x = x1 + (x2 - x0) / 6;\n var cp1y = y1 + (y2 - y0) / 6;\n var cp2x = x2 - (x3 - x1) / 6;\n var cp2y = y2 - (y3 - y1) / 6;\n closedPath.push(['C', cp1x, cp1y, cp2x, cp2y, x2, y2]);\n }\n\n closedPath.unshift(['M', last.x, last.y]);\n return closedPath;\n};\n\nvar path_vecScaleTo = function vecScaleTo(v, length) {\n // Vector with direction of v with specified length\n return matrix_util_esm[\"vec2\"].scale([0, 0], matrix_util_esm[\"vec2\"].normalize([0, 0], v), length);\n};\n\nvar unitNormal = function unitNormal(p0, p1) {\n // Returns the unit normal to the line segment from p0 to p1.\n var n = [p0[1] - p1[1], p1[0] - p0[0]];\n var nLength = Math.sqrt(n[0] * n[0] + n[1] * n[1]);\n\n if (nLength === 0) {\n throw new Error('p0 should not be equal to p1');\n }\n\n return [n[0] / nLength, n[1] / nLength];\n};\n\nvar vecFrom = function vecFrom(p0, p1) {\n // Vector from p0 to p1\n return [p1[0] - p0[0], p1[1] - p0[1]];\n};\n/**\n * 传入的节点作为多边形顶点,生成有圆角的多边形\n * @param polyPoints 多边形顶点\n * @param padding 在原多边形基础上增加最终轮廓和原多边形的空白间隔\n */\n\n\nfunction roundedHull(polyPoints, padding) {\n // The rounded hull path around a single point\n var roundedHull1 = function roundedHull1(points) {\n var p1 = [points[0][0], points[0][1] - padding];\n var p2 = [points[0][0], points[0][1] + padding];\n return \"M \" + p1 + \" A \" + padding + \",\" + padding + \",0,0,0,\" + p2 + \" A \" + padding + \",\" + padding + \",0,0,0,\" + p1;\n }; // The rounded hull path around two points\n\n\n var roundedHull2 = function roundedHull2(points) {\n var offsetVector = matrix_util_esm[\"vec2\"].scale([0, 0], unitNormal(points[0], points[1]), padding);\n var invOffsetVector = matrix_util_esm[\"vec2\"].scale([0, 0], offsetVector, -1);\n var p0 = matrix_util_esm[\"vec2\"].add([0, 0], points[0], offsetVector);\n var p1 = matrix_util_esm[\"vec2\"].add([0, 0], points[1], offsetVector);\n var p2 = matrix_util_esm[\"vec2\"].add([0, 0], points[1], invOffsetVector);\n var p3 = matrix_util_esm[\"vec2\"].add([0, 0], points[0], invOffsetVector);\n return \"M \" + p0 + \" L \" + p1 + \" A \" + [padding, padding, '0,0,0', p2].join(',') + \" L \" + p3 + \" A \" + [padding, padding, '0,0,0', p0].join(',');\n }; // 特殊情况处理:节点数小于等于2\n\n\n if (!polyPoints || polyPoints.length < 1) return '';\n if (polyPoints.length === 1) return roundedHull1(polyPoints);\n if (polyPoints.length === 2) return roundedHull2(polyPoints);\n var segments = new Array(polyPoints.length); // Calculate each offset (outwards) segment of the convex hull.\n\n for (var segmentIndex = 0; segmentIndex < segments.length; ++segmentIndex) {\n var p0 = segmentIndex === 0 ? polyPoints[polyPoints.length - 1] : polyPoints[segmentIndex - 1];\n var p1 = polyPoints[segmentIndex]; // Compute the offset vector for the line segment, with length = padding.\n\n var offset = matrix_util_esm[\"vec2\"].scale([0, 0], unitNormal(p0, p1), padding);\n segments[segmentIndex] = [matrix_util_esm[\"vec2\"].add([0, 0], p0, offset), matrix_util_esm[\"vec2\"].add([0, 0], p1, offset)];\n }\n\n var arcData = \"A \" + [padding, padding, '0,0,0,'].join(',');\n segments = segments.map(function (segment, index) {\n var pathFragment = '';\n\n if (index === 0) {\n pathFragment = \"M \" + segments[segments.length - 1][1] + \" \";\n }\n\n pathFragment += arcData + segment[0] + \" L \" + segment[1];\n return pathFragment;\n });\n return segments.join(' ');\n}\n/**\n * 传入的节点作为多边形顶点,生成平滑的闭合多边形\n * @param polyPoints\n * @param padding\n */\n\nfunction paddedHull(polyPoints, padding) {\n var pointCount = polyPoints.length;\n\n var smoothHull1 = function smoothHull1(points) {\n // Returns the path for a circular hull around a single point.\n var p1 = [points[0][0], points[0][1] - padding];\n var p2 = [points[0][0], points[0][1] + padding];\n return \"M \" + p1 + \" A \" + [padding, padding, '0,0,0', p2].join(',') + \" A \" + [padding, padding, '0,0,0', p1].join(',');\n }; // Returns the path for a rounded hull around two points.\n\n\n var smoothHull2 = function smoothHull2(points) {\n var v = vecFrom(points[0], points[1]);\n var extensionVec = path_vecScaleTo(v, padding);\n var extension0 = matrix_util_esm[\"vec2\"].add([0, 0], points[0], matrix_util_esm[\"vec2\"].scale([0, 0], extensionVec, -1));\n var extension1 = matrix_util_esm[\"vec2\"].add([0, 0], points[1], extensionVec);\n var tangentHalfLength = 1.2 * padding;\n var controlDelta = path_vecScaleTo(matrix_util_esm[\"vec2\"].normalize([0, 0], v), tangentHalfLength);\n var invControlDelta = matrix_util_esm[\"vec2\"].scale([0, 0], controlDelta, -1);\n var control0 = matrix_util_esm[\"vec2\"].add([0, 0], extension0, invControlDelta);\n var control1 = matrix_util_esm[\"vec2\"].add([0, 0], extension1, invControlDelta);\n var control3 = matrix_util_esm[\"vec2\"].add([0, 0], extension0, controlDelta); // return [\n // ['M', extension0[0], extension0[1]],\n // ['C', control0, control1, extension1],\n // ['S', control3, extension0],\n // 'Z',\n // ];\n\n return \"M \" + extension0 + \" C \" + [control0, control1, extension1].join(',') + \" S \" + [control3, extension0].join(',') + \" Z\";\n }; // Handle special cases\n\n\n if (!polyPoints || pointCount < 1) return '';\n if (pointCount === 1) return smoothHull1(polyPoints);\n if (pointCount === 2) return smoothHull2(polyPoints);\n var hullPoints = polyPoints.map(function (point, index) {\n var pNext = polyPoints[(index + 1) % pointCount];\n return {\n p: point,\n v: matrix_util_esm[\"vec2\"].normalize([0, 0], vecFrom(point, pNext))\n };\n }); // Compute the expanded hull points, and the nearest prior control point for each.\n\n for (var i = 0; i < hullPoints.length; ++i) {\n var priorIndex = i > 0 ? i - 1 : pointCount - 1;\n var extensionVec = matrix_util_esm[\"vec2\"].normalize([0, 0], matrix_util_esm[\"vec2\"].add([0, 0], hullPoints[priorIndex].v, matrix_util_esm[\"vec2\"].scale([0, 0], hullPoints[i].v, -1)));\n hullPoints[i].p = matrix_util_esm[\"vec2\"].add([0, 0], hullPoints[i].p, matrix_util_esm[\"vec2\"].scale([0, 0], extensionVec, padding));\n }\n\n return hullPoints.map(function (obj) {\n var point = obj.p;\n return {\n x: point[0],\n y: point[1]\n };\n });\n}\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/hull/convexHull.js\n/**\n * Use cross product to judge the direction of the turn.\n * Returns a positive value, if OAB makes a clockwise turn,\n * negative for counter-clockwise turn, and zero if the points are collinear.\n */\nvar cross = function cross(a, b, o) {\n return (a.y - o.y) * (b.x - o.x) - (a.x - o.x) * (b.y - o.y);\n};\n/**\n * Generate a convex hull of given points. Andrew's monotone chain algorithm.\n * @param points An array of [x, y] representing the coordinates of points.\n * @return a list of vertices of the convex hull in counter-clockwise order,\n */\n\nvar genConvexHull = function genConvexHull(items) {\n var points = items.map(function (item) {\n return {\n x: item.getModel().x,\n y: item.getModel().y\n };\n });\n points.sort(function (a, b) {\n return a.x === b.x ? a.y - b.y : a.x - b.x;\n });\n\n if (points.length === 1) {\n return points;\n } // build the lower hull\n\n\n var lower = [];\n\n for (var i = 0; i < points.length; i++) {\n while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], points[i]) <= 0) {\n lower.pop();\n }\n\n lower.push(points[i]);\n } // build the upper hull\n\n\n var upper = [];\n\n for (var i = points.length - 1; i >= 0; i--) {\n while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], points[i]) <= 0) {\n upper.pop();\n }\n\n upper.push(points[i]);\n }\n\n upper.pop();\n lower.pop();\n var strictHull = lower.concat(upper);\n return strictHull;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/hull/bubbleset.js\n\nvar defaultOps = {\n maxRoutingIterations: 100,\n maxMarchingIterations: 100,\n pixelGroupSize: 2,\n edgeR0: 10,\n edgeR1: 10,\n nodeR0: 5,\n nodeR1: 10,\n morphBuffer: 5,\n threshold: 0.001,\n skip: 16,\n nodeInfluenceFactor: 1,\n edgeInfluenceFactor: 1,\n negativeNodeInfluenceFactor: -0.5\n};\n/**\n * Marching square algorithm for traching the contour of a pixel group\n * https://www.emanueleferonato.com/2013/03/01/using-marching-squares-algorithm-to-trace-the-contour-of-an-image/\n * @param potentialArea\n * @param threshold\n */\n\nfunction MarchingSquares(contour, potentialArea, threshold) {\n var marched = false;\n\n var getVal = function getVal(x, y) {\n return potentialArea.cells[x + y * potentialArea.width];\n };\n\n var getState = function getState(x, y) {\n var squareVal = 0;\n\n if (getVal(x - 1, y - 1) >= threshold) {\n squareVal += 1;\n }\n\n if (getVal(x, y - 1) > threshold) {\n squareVal += 2;\n }\n\n if (getVal(x - 1, y) > threshold) {\n squareVal += 4;\n }\n\n if (getVal(x, y) > threshold) {\n squareVal += 8;\n }\n\n return squareVal;\n };\n\n var doMarch = function doMarch(xPos, yPos) {\n var x = xPos;\n var y = yPos;\n var prevX;\n var prevY;\n\n for (var i = 0; i < potentialArea.width * potentialArea.height; i++) {\n prevX = x;\n prevY = y;\n\n if (contour.findIndex(function (item) {\n return item.x === x && item.y === y;\n }) > -1) {\n if (contour[0].x !== x || contour[0].y !== y) {// encountered a loop but haven't returned to start: change direction using conditionals and continue back to start\n } else {\n return true;\n }\n } else {\n contour.push({\n x: x,\n y: y\n });\n }\n\n var state = getState(x, y); // assign the move direction according to state of the square\n\n switch (state) {\n case -1:\n console.warn('Marched out of bounds');\n return true;\n\n case 0:\n case 3:\n case 2:\n case 7:\n x++; // go right\n\n break;\n\n case 12:\n case 14:\n case 4:\n x--; // go left\n\n break;\n\n case 6:\n // go left if come from up else go right\n if (prevX === 0) {\n if (prevY === -1) {\n x -= 1;\n } else {\n x += 1;\n }\n }\n\n break;\n\n case 1:\n case 13:\n case 5:\n y--; // go up\n\n break;\n\n case 9:\n // go up if come from right else go down\n if (prevX === 1) {\n if (prevY === 0) {\n y -= 1;\n } else {\n y += 1;\n }\n }\n\n break;\n\n case 10:\n case 8:\n case 11:\n y++; // go down\n\n break;\n\n default:\n console.warn(\"Marching squares invalid state: \" + state);\n return true;\n }\n }\n };\n\n this.march = function () {\n for (var x = 0; x < potentialArea.width && !marched; x += 1) {\n for (var y = 0; y < potentialArea.height && !marched; y += 1) {\n if (getVal(x, y) > threshold && getState(x, y) !== 15) {\n marched = doMarch(x, y);\n }\n }\n }\n\n return marched;\n };\n}\n/**\n * Space partition & assign value to each cell\n * @param points\n */\n\n\nvar initGridCells = function initGridCells(width, height, pixelGroupSize) {\n var scaleWidth = Math.ceil(width / pixelGroupSize);\n var scaleHeight = Math.ceil(height / pixelGroupSize);\n var gridCells = new Float32Array(Math.max(0, scaleWidth * scaleHeight)).fill(0);\n return {\n cells: gridCells,\n width: scaleWidth,\n height: scaleHeight\n };\n};\n/**\n * Find the optimal already visited member to item;\n Optimal: minimize cost(j) = distance(i,j) ∗ countObstacles(i,j)\n * @param item\n * @param visited\n */\n\n\nvar bubbleset_pickBestNeighbor = function pickBestNeighbor(item, visited, nonMembers) {\n var closestNeighbour = null;\n var minCost = Number.POSITIVE_INFINITY;\n visited.forEach(function (neighbourItem) {\n var itemP = {\n x: item.getModel().x,\n y: item.getModel().y\n };\n var neighbourItemP = {\n x: neighbourItem.getModel().x,\n y: neighbourItem.getModel().y\n };\n var dist = squareDist(itemP, neighbourItemP);\n var directLine = new math_Line(itemP.x, itemP.y, neighbourItemP.x, neighbourItemP.y);\n var numberObstacles = nonMembers.reduce(function (count, _item) {\n if (fractionToLine(_item, directLine) > 0) {\n return count + 1;\n }\n\n return count;\n }, 0);\n\n if (dist * Math.pow(numberObstacles + 1, 2) < minCost) {\n closestNeighbour = neighbourItem;\n minCost = dist * Math.pow(numberObstacles + 1, 2);\n }\n });\n return closestNeighbour;\n};\n/**\n * 返回和线相交的item中,离边的起点最近的item\n * @param items\n * @param line\n */\n\n\nvar bubbleset_getIntersectItem = function getIntersectItem(items, line) {\n var minDistance = Number.POSITIVE_INFINITY;\n var closestItem = null;\n items.forEach(function (item) {\n var distance = fractionToLine(item, line); // find closest intersection\n\n if (distance >= 0 && distance < minDistance) {\n closestItem = item;\n minDistance = distance;\n }\n });\n return closestItem;\n};\n/**\n * Modify the directLine and Route virtual edges around obstacles\n */\n\n\nvar bubbleset_computeRoute = function computeRoute(directLine, nonMembers, maxRoutingIterations, morphBuffer) {\n var checkedLines = [];\n var linesToCheck = [];\n linesToCheck.push(directLine);\n var hasIntersection = true;\n var iterations = 0;\n\n var pointExists = function pointExists(point, lines) {\n var flag = false;\n lines.forEach(function (line) {\n if (flag) return;\n\n if (isPointsOverlap(point, {\n x: line.x1,\n y: line.y1\n }) || isPointsOverlap(point, {\n x: line.x2,\n y: line.y2\n })) {\n flag = true;\n }\n });\n return flag;\n };\n\n var isPointInNonMembers = function isPointInNonMembers(point, _nonMembers) {\n for (var _i = 0, _nonMembers_1 = _nonMembers; _i < _nonMembers_1.length; _i++) {\n var item = _nonMembers_1[_i];\n var bbox = item.getBBox();\n var itemContour = [[bbox.x, bbox.y], [bbox.x + bbox.width, bbox.y], [bbox.x, bbox.y + bbox.height], [bbox.x + bbox.width, bbox.y + bbox.height]];\n\n if (isPointInPolygon(itemContour, point.x, point.y)) {\n return true;\n }\n }\n\n return false;\n }; // outer loop end when no more intersections or out of iterations\n\n\n while (hasIntersection && iterations < maxRoutingIterations) {\n hasIntersection = false;\n\n var _loop_1 = function _loop_1() {\n var line = linesToCheck.pop();\n var closestItem = bubbleset_getIntersectItem(nonMembers, line);\n\n if (closestItem) {\n var _a = itemIntersectByLine(closestItem, line),\n intersections_1 = _a[0],\n countIntersections = _a[1]; // if line passes through item\n\n\n if (countIntersections === 2) {\n var testReroute = function testReroute(isFirst) {\n var tempMorphBuffer = morphBuffer;\n var virtualNode = rerouteLine(closestItem, tempMorphBuffer, intersections_1, isFirst); // test the virtualNode already exists\n\n var exist = pointExists(virtualNode, linesToCheck) || pointExists(virtualNode, checkedLines);\n var pointInside = isPointInNonMembers(virtualNode, nonMembers);\n\n while (!exist && pointInside && tempMorphBuffer >= 1) {\n // try a smaller buffer\n tempMorphBuffer /= 1.5;\n virtualNode = rerouteLine(closestItem, tempMorphBuffer, intersections_1, isFirst);\n exist = pointExists(virtualNode, linesToCheck) || pointExists(virtualNode, checkedLines);\n pointInside = isPointInNonMembers(virtualNode, nonMembers);\n } // 第二次route时不要求pointInside\n\n\n if (virtualNode && !exist && (!isFirst || !pointInside)) {\n // add 2 rerouted lines to check\n linesToCheck.push(new math_Line(line.x1, line.y1, virtualNode.x, virtualNode.y));\n linesToCheck.push(new math_Line(virtualNode.x, virtualNode.y, line.x2, line.y2));\n hasIntersection = true;\n }\n };\n\n testReroute(true);\n\n if (!hasIntersection) {\n // if we didn't find a valid point around the first corner, try the second\n testReroute(false);\n }\n }\n } // no intersection found, mark this line as completed\n\n\n if (!hasIntersection) {\n checkedLines.push(line);\n }\n\n iterations += 1;\n }; // inner loop end when out of lines or found an intersection\n\n\n while (!hasIntersection && linesToCheck.length) {\n _loop_1();\n }\n } // 加入剩余的线\n\n\n while (linesToCheck.length) {\n checkedLines.push(linesToCheck.pop());\n }\n\n return checkedLines;\n};\n/**\n * Connect item with visited members using direct line or virtual edges\n */\n\n\nfunction getRoute(item, nonMembers, visited, maxRoutingIterations, morphBuffer) {\n var optimalNeighbor = bubbleset_pickBestNeighbor(item, visited, nonMembers);\n\n if (optimalNeighbor === null) {\n return [];\n } // merge the consecutive lines\n\n\n var mergeLines = function mergeLines(checkedLines) {\n var finalRoute = [];\n\n while (checkedLines.length > 0) {\n var line1 = checkedLines.pop();\n\n if (checkedLines.length === 0) {\n finalRoute.push(line1);\n break;\n }\n\n var line2 = checkedLines.pop();\n var mergeLine = new math_Line(line1.x1, line1.y1, line2.x2, line2.y2);\n var closestItem = bubbleset_getIntersectItem(nonMembers, mergeLine); // merge most recent line and previous line\n\n if (!closestItem) {\n checkedLines.push(mergeLine);\n } else {\n finalRoute.push(line1);\n checkedLines.push(line2);\n }\n }\n\n return finalRoute;\n };\n\n var directLine = new math_Line(item.getModel().x, item.getModel().y, optimalNeighbor.getModel().x, optimalNeighbor.getModel().y);\n var checkedLines = bubbleset_computeRoute(directLine, nonMembers, maxRoutingIterations, morphBuffer);\n var finalRoute = mergeLines(checkedLines);\n return finalRoute;\n}\n/**\n * Calculate the countor that includes the selected items and exclues the non-selected items\n * @param graph\n * @param members\n * @param nonMembers\n * @param options\n */\n\n\nvar bubbleset_genBubbleSet = function genBubbleSet(members, nonMembers, ops) {\n // eslint-disable-next-line no-redeclare\n var options = Object.assign(defaultOps, ops);\n var centroid = getPointsCenter(members.map(function (item) {\n return {\n x: item.getModel().x,\n y: item.getModel().y\n };\n })); // 按照到中心距离远近排序\n\n members = members.sort(function (a, b) {\n return squareDist({\n x: a.getModel().x,\n y: a.getModel().y\n }, centroid) - squareDist({\n x: b.getModel().x,\n y: b.getModel().y\n }, centroid);\n });\n var visited = [];\n var virtualEdges = [];\n members.forEach(function (item) {\n var lines = getRoute(item, nonMembers, visited, options.maxRoutingIterations, options.morphBuffer);\n lines.forEach(function (l) {\n virtualEdges.push(l);\n });\n visited.push(item);\n }); // 由于edge也可以作为member和nonMember传入,暂时不考虑把edges作为参数传入genBubbleSet\n // edges && edges.forEach(e => {\n // virtualEdges.push(new Line(e.getSource().getModel().x, e.getSource().getModel().y, e.getTarget().getModel().x, e.getTarget().getModel().y));\n // });\n\n var activeRegion = getActiveRregion(members, virtualEdges, options.nodeR0);\n var potentialArea = initGridCells(activeRegion.width, activeRegion.height, options.pixelGroupSize); // Use march squares to generate contour\n\n var contour = [];\n var hull = [];\n\n for (var iterations = 0; iterations < options.maxMarchingIterations; iterations++) {\n fillPotentialArea(members, nonMembers, virtualEdges, activeRegion, potentialArea, options);\n contour = [];\n hull = [];\n if (!new MarchingSquares(contour, potentialArea, options.threshold).march()) continue;\n var marchedPath = contour.map(function (point) {\n return {\n x: Math.round(point.x * options.pixelGroupSize + activeRegion.minX),\n y: Math.round(point.y * options.pixelGroupSize + activeRegion.minY)\n };\n }); // const marchedPath = marchingSquares(potentialArea, options.threshold).map(point => ({ x: Math.round(point.x * options.pixelGroupSize + activeRegion.minX), y: Math.round(point.y * options.pixelGroupSize + activeRegion.minY) }))\n\n if (marchedPath) {\n var size = marchedPath.length;\n\n if (options.skip > 1) {\n size = Math.floor(marchedPath.length / options.skip); // if we reduced too much (fewer than three points in reduced surface) reduce skip and try again\n\n while (size < 3 && options.skip > 1) {\n options.skip -= 1;\n size = Math.floor(marchedPath.length / options.skip);\n }\n } // copy hull values\n\n\n for (var i = 0, j = 0; j < size; j += 1, i += options.skip) {\n hull.push({\n x: marchedPath[i].x,\n y: marchedPath[i].y\n });\n }\n }\n\n var isContourValid = function isContourValid() {\n for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {\n var item = members_1[_i];\n var hullPoints = hull.map(function (point) {\n return [point.x, point.y];\n });\n if (!isPointInPolygon(hullPoints, item.getBBox().centerX, item.getBBox().centerY)) return false;\n } // 不强制要求所有nonMembers都没有包含在内\n // for (const item of nonMembers) {\n // if (isPointInPolygon({ x: item.getBBox().centerX, y: item.getBBox().centerY }, contour)) return false\n // }\n\n\n return true;\n };\n\n if (hull && isContourValid()) {\n return hull;\n } // update parameters for next iteraction\n\n\n options.threshold *= 0.9;\n\n if (iterations <= options.maxMarchingIterations * 0.5) {\n options.memberInfluenceFactor *= 1.2;\n options.edgeInfluenceFactor *= 1.2;\n } else if (options.nonMemberInfluenceFactor !== 0 && nonMembers.length > 0) {\n // after half the iterations, start increasing positive energy and lowering the threshold\n options.nonMemberInfluenceFactor *= 0.8;\n } else {\n break;\n }\n }\n\n return hull;\n};\n/**\n * unionboundingbox\n * @param members\n * @param edges\n */\n\nfunction getActiveRregion(members, edges, offset) {\n var activeRegion = {\n minX: Number.POSITIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n maxX: Number.NEGATIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n width: 0,\n height: 0,\n x: 0,\n y: 0\n };\n var bboxes = [];\n members.forEach(function (item) {\n bboxes.push(item.getBBox());\n });\n edges.forEach(function (l) {\n bboxes.push(l.getBBox());\n });\n\n for (var _i = 0, bboxes_1 = bboxes; _i < bboxes_1.length; _i++) {\n var bbox = bboxes_1[_i];\n activeRegion.minX = (bbox.minX < activeRegion.minX ? bbox.minX : activeRegion.minX) - offset;\n activeRegion.minY = (bbox.minY < activeRegion.minY ? bbox.minY : activeRegion.minY) - offset;\n activeRegion.maxX = (bbox.maxX > activeRegion.maxX ? bbox.maxX : activeRegion.maxX) + offset;\n activeRegion.maxY = (bbox.maxY > activeRegion.maxY ? bbox.maxY : activeRegion.maxY) + offset;\n }\n\n activeRegion.width = activeRegion.maxX - activeRegion.minX;\n activeRegion.height = activeRegion.maxY - activeRegion.minY;\n activeRegion.x = activeRegion.minX;\n activeRegion.y = activeRegion.minY;\n return activeRegion;\n}\n\nfunction fillPotentialArea(members, nonMembers, edges, activeRegion, potentialArea, options) {\n function pos2GridIx(x, offset) {\n var gridIx = Math.floor((x - offset) / options.pixelGroupSize);\n return gridIx < 0 ? 0 : gridIx;\n }\n\n function gridIx2Pos(x, offset) {\n return x * options.pixelGroupSize + offset;\n } // using inverse a for numerical stability\n\n\n var nodeInfA = (options.nodeR0 - options.nodeR1) * (options.nodeR0 - options.nodeR1);\n var edgeInfA = (options.edgeR0 - options.edgeR1) * (options.edgeR0 - options.edgeR1);\n\n var getAffectedRegion = function getAffectedRegion(bbox, thresholdR) {\n var startX = Math.min(pos2GridIx(bbox.minX, thresholdR + activeRegion.minX), potentialArea.width);\n var startY = Math.min(pos2GridIx(bbox.minY, thresholdR + activeRegion.minY), potentialArea.height);\n var endX = Math.min(pos2GridIx(bbox.maxX, -thresholdR + activeRegion.minX), potentialArea.width);\n var endY = Math.min(pos2GridIx(bbox.maxY, -thresholdR + activeRegion.minY), potentialArea.height);\n return [startX, startY, endX, endY];\n };\n\n var addItemInfluence = function addItemInfluence(item, influenceFactor) {\n var bbox = item.getBBox();\n\n var _a = getAffectedRegion(bbox, options.nodeR1),\n startX = _a[0],\n startY = _a[1],\n endX = _a[2],\n endY = _a[3]; // calculate item influence for each cell\n\n\n for (var y = startY; y < endY; y += 1) {\n for (var x = startX; x < endX; x += 1) {\n if (influenceFactor < 0 && potentialArea[x + y * potentialArea.width] <= 0) {\n continue;\n }\n\n var tempX = gridIx2Pos(x, activeRegion.minX);\n var tempY = gridIx2Pos(y, activeRegion.minY);\n var distanceSq = pointRectSquareDist({\n x: tempX,\n y: tempY\n }, {\n x: bbox.minX,\n y: bbox.minY,\n width: bbox.width,\n height: bbox.height\n });\n\n if (distanceSq < Math.pow(options.nodeR1, 2)) {\n var dr = Math.sqrt(distanceSq) - options.nodeR1;\n potentialArea.cells[x + y * potentialArea.width] += influenceFactor * dr * dr;\n }\n }\n }\n };\n\n var addEdgeInfluence = function addEdgeInfluence(line, influenceFactor) {\n var bbox = line.getBBox();\n\n var _a = getAffectedRegion(bbox, options.edgeR1),\n startX = _a[0],\n startY = _a[1],\n endX = _a[2],\n endY = _a[3]; // for every point in active part of potentialArea, calculate distance to nearest point on line and add influence\n\n\n for (var y = startY; y < endY; y += 1) {\n for (var x = startX; x < endX; x += 1) {\n if (influenceFactor < 0 && potentialArea.cells[x + y * potentialArea.width] <= 0) {\n continue;\n }\n\n var tempX = gridIx2Pos(x, activeRegion.minX);\n var tempY = gridIx2Pos(y, activeRegion.minY);\n var minDistanceSq = pointLineSquareDist({\n x: tempX,\n y: tempY\n }, line); // only influence if less than r1\n\n if (minDistanceSq < Math.pow(options.edgeR1, 2)) {\n var mdr = Math.sqrt(minDistanceSq) - options.edgeR1;\n potentialArea.cells[x + y * potentialArea.width] += influenceFactor * mdr * mdr;\n }\n }\n }\n };\n\n if (options.nodeInfluenceFactor) {\n members.forEach(function (item) {\n addItemInfluence(item, options.nodeInfluenceFactor / nodeInfA);\n });\n }\n\n if (options.edgeInfluenceFactor) {\n edges.forEach(function (edge) {\n addEdgeInfluence(edge, options.edgeInfluenceFactor / edgeInfA);\n });\n }\n\n if (options.negativeNodeInfluenceFactor) {\n nonMembers.forEach(function (item) {\n addItemInfluence(item, options.negativeNodeInfluenceFactor / nodeInfA);\n });\n }\n}\n\nfunction rerouteLine(item, buffer, intersections, wrapNormal) {\n var bbox = item.getBBox();\n var topIntersect = intersections[0],\n leftIntersect = intersections[1],\n bottomIntersect = intersections[2],\n rightIntersect = intersections[3];\n var cornerPos = {\n topLeft: {\n x: bbox.minX - buffer,\n y: bbox.minY - buffer\n },\n topRight: {\n x: bbox.maxX + buffer,\n y: bbox.minY - buffer\n },\n bottomLeft: {\n x: bbox.minX - buffer,\n y: bbox.maxY + buffer\n },\n bottomRight: {\n x: bbox.maxX + buffer,\n y: bbox.maxY + buffer\n }\n };\n var totalArea = bbox.height * bbox.width;\n\n function calcHalfArea(intersect1, intersect2) {\n return bbox.width * ((intersect1.y - bbox.minY + (intersect2.y - bbox.minY)) * 0.5);\n } // 根据线和boundingbox相交的情况,确定control point的位置\n\n\n if (leftIntersect) {\n // 相交区域有三角形\n if (topIntersect) return wrapNormal ? cornerPos.topLeft : cornerPos.bottomRight;\n if (bottomIntersect) return wrapNormal ? cornerPos.bottomLeft : cornerPos.topRight; // 相交区域分成上下两个梯形,比较面积\n\n var topArea = calcHalfArea(leftIntersect, rightIntersect);\n\n if (topArea < totalArea * 0.5) {\n if (leftIntersect.y > rightIntersect.y) return wrapNormal ? cornerPos.topLeft : cornerPos.bottomRight;\n return wrapNormal ? cornerPos.topRight : cornerPos.bottomLeft;\n }\n\n if (leftIntersect.y < rightIntersect.y) return wrapNormal ? cornerPos.bottomLeft : cornerPos.topRight;\n return wrapNormal ? cornerPos.bottomRight : cornerPos.topLeft;\n }\n\n if (rightIntersect) {\n if (topIntersect) return wrapNormal ? cornerPos.topRight : cornerPos.bottomLeft;\n if (bottomIntersect) return wrapNormal ? cornerPos.bottomRight : cornerPos.topLeft;\n } // 相交区域分成左右两个梯形\n\n\n var leftArea = calcHalfArea(topIntersect, bottomIntersect);\n\n if (leftArea < totalArea * 0.5) {\n if (topIntersect.x > bottomIntersect.x) return wrapNormal ? cornerPos.topLeft : cornerPos.bottomRight;\n return wrapNormal ? cornerPos.bottomLeft : cornerPos.topRight;\n }\n\n if (topIntersect.x < bottomIntersect.x) return wrapNormal ? cornerPos.topRight : cornerPos.bottomLeft;\n return wrapNormal ? cornerPos.bottomRight : cornerPos.topLeft;\n}\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/item/hull.js\n\n\n\n\n\n\n\n/**\n * 用于包裹内部的成员的轮廓。\n * convex hull(凸包):http://geomalgorithms.com/a10-_hull-1.html#Monotone%20Chain\n * bubble: 使用 bubbleset算法,refer: http://vialab.science.uoit.ca/wp-content/papercite-data/pdf/col2009c.pdf\n * 通过配置 padding 可以调节包裹轮廓对节点的松紧程度\n */\n\nvar hull_Hull =\n/** @class */\nfunction () {\n function Hull(graph, cfg) {\n this.cfg = Object(esm[\"deepMix\"])(this.getDefaultCfg(), cfg);\n this.graph = graph;\n this.id = this.cfg.id;\n this.group = this.cfg.group;\n this.members = this.cfg.members.map(function (item) {\n return Object(esm[\"isString\"])(item) ? graph.findById(item) : item;\n });\n this.nonMembers = this.cfg.nonMembers.map(function (item) {\n return Object(esm[\"isString\"])(item) ? graph.findById(item) : item;\n });\n this.setPadding();\n this.setType();\n this.path = this.calcPath(this.members, this.nonMembers);\n this.render();\n }\n\n Hull.prototype.getDefaultCfg = function () {\n return {\n id: 'g6-hull',\n type: 'round-convex',\n members: [],\n nonMembers: [],\n style: {\n fill: 'lightblue',\n stroke: 'blue',\n opacity: 0.2\n },\n padding: 10\n };\n };\n\n Hull.prototype.setPadding = function () {\n var nodeSize = this.members.length && this.members[0].getKeyShape().getCanvasBBox().width / 2;\n this.padding = this.cfg.padding > 0 ? this.cfg.padding + nodeSize : 10 + nodeSize;\n this.cfg.bubbleCfg = {\n nodeR0: this.padding - nodeSize,\n nodeR1: this.padding - nodeSize,\n morphBuffer: this.padding - nodeSize\n };\n };\n\n Hull.prototype.setType = function () {\n this.type = this.cfg.type;\n\n if (this.members.length < 3) {\n this.type = 'round-convex';\n }\n\n if (this.type !== 'round-convex' && this.type !== 'smooth-convex' && this.type !== 'bubble') {\n console.warn('The hull type should be either round-convex, smooth-convex or bubble, round-convex is used by default.');\n this.type = 'round-convex';\n }\n };\n\n Hull.prototype.calcPath = function (members, nonMembers) {\n var contour, path, hull;\n\n switch (this.type) {\n case 'round-convex':\n contour = genConvexHull(members);\n hull = roundedHull(contour.map(function (p) {\n return [p.x, p.y];\n }), this.padding);\n path = Object(path_util_esm[\"b\" /* parsePathString */])(hull);\n break;\n\n case 'smooth-convex':\n contour = genConvexHull(members);\n\n if (contour.length === 2) {\n hull = roundedHull(contour.map(function (p) {\n return [p.x, p.y];\n }), this.padding);\n path = Object(path_util_esm[\"b\" /* parsePathString */])(hull);\n } else if (contour.length > 2) {\n hull = paddedHull(contour.map(function (p) {\n return [p.x, p.y];\n }), this.padding);\n path = getClosedSpline(hull);\n }\n\n break;\n\n case 'bubble':\n contour = bubbleset_genBubbleSet(members, nonMembers, this.cfg.bubbleCfg);\n path = contour.length >= 2 && getClosedSpline(contour);\n break;\n\n default:\n }\n\n return path;\n };\n\n Hull.prototype.render = function () {\n this.group.addShape('path', {\n attrs: Object(tslib_es6[\"__assign\"])({\n path: this.path\n }, this.cfg.style),\n id: this.id,\n name: this.cfg.id,\n capture: false\n });\n this.group.toBack();\n };\n /**\n * 增加hull的成员,同时如果该成员原先在nonMembers中,则从nonMembers中去掉\n * @param item 节点实例\n * @return boolean 添加成功返回 true,否则返回 false\n */\n\n\n Hull.prototype.addMember = function (item) {\n if (!item) return;\n if (Object(esm[\"isString\"])(item)) item = this.graph.findById(item);\n this.members.push(item);\n var index = this.nonMembers.indexOf(item);\n\n if (index > -1) {\n this.nonMembers.splice(index, 1);\n }\n\n this.updateData(this.members, this.nonMembers);\n return true;\n };\n /**\n * 增加hull需要排除的节点,同时如果该成员原先在members中,则从members中去掉\n * @param item 节点实例\n * @return boolean 添加成功返回 true,否则返回 false\n */\n\n\n Hull.prototype.addNonMember = function (item) {\n if (!item) return;\n if (Object(esm[\"isString\"])(item)) item = this.graph.findById(item);\n this.nonMembers.push(item);\n var index = this.members.indexOf(item);\n\n if (index > -1) {\n this.members.splice(index, 1);\n }\n\n this.updateData(this.members, this.nonMembers);\n return true;\n };\n /**\n * 移除hull中的成员\n * @param node 节点实例\n * @return boolean 移除成功返回 true,否则返回 false\n */\n\n\n Hull.prototype.removeMember = function (item) {\n if (!item) return;\n if (Object(esm[\"isString\"])(item)) item = this.graph.findById(item);\n var index = this.members.indexOf(item);\n\n if (index > -1) {\n this.members.splice(index, 1);\n this.updateData(this.members, this.nonMembers);\n return true;\n }\n\n return false;\n };\n /**\n * @param node 节点实例\n * @return boolean 移除成功返回 true,否则返回 false\n */\n\n\n Hull.prototype.removeNonMember = function (item) {\n if (!item) return;\n if (Object(esm[\"isString\"])(item)) item = this.graph.findById(item);\n var index = this.nonMembers.indexOf(item);\n\n if (index > -1) {\n this.nonMembers.splice(index, 1);\n this.updateData(this.members, this.nonMembers);\n return true;\n }\n\n return false;\n };\n\n Hull.prototype.updateData = function (members, nonMembers) {\n var _this = this;\n\n this.group.findById(this.id).remove();\n if (members) this.members = members.map(function (item) {\n return Object(esm[\"isString\"])(item) ? _this.graph.findById(item) : item;\n });\n if (nonMembers) this.nonMembers = nonMembers.map(function (item) {\n return Object(esm[\"isString\"])(item) ? _this.graph.findById(item) : item;\n });\n this.path = this.calcPath(this.members, this.nonMembers);\n this.render();\n };\n\n Hull.prototype.updateStyle = function (cfg) {\n var path = this.group.findById(this.id);\n path.attr(Object(tslib_es6[\"__assign\"])({}, cfg));\n };\n /**\n * 更新 hull\n * @param cfg hull 配置项\n */\n\n\n Hull.prototype.updateCfg = function (cfg) {\n var _this = this;\n\n this.cfg = Object(esm[\"deepMix\"])(this.cfg, cfg);\n this.id = this.cfg.id;\n this.group = this.cfg.group;\n\n if (cfg.members) {\n this.members = this.cfg.members.map(function (item) {\n return Object(esm[\"isString\"])(item) ? _this.graph.findById(item) : item;\n });\n }\n\n if (cfg.nonMembers) {\n this.nonMembers = this.cfg.nonMembers.map(function (item) {\n return Object(esm[\"isString\"])(item) ? _this.graph.findById(item) : item;\n });\n } // TODO padding 设置太大,会影响到 contain 结果\n\n\n this.setPadding();\n this.setType();\n this.path = this.calcPath(this.members, this.nonMembers);\n this.render();\n };\n /**\n * 判断是否在hull内部\n * @param item\n */\n\n\n Hull.prototype.contain = function (item) {\n var _this = this;\n\n var nodeItem;\n\n if (Object(esm[\"isString\"])(item)) {\n nodeItem = this.graph.findById(item);\n } else {\n nodeItem = item;\n }\n\n var shapePoints;\n var shape = nodeItem.getKeyShape();\n\n if (nodeItem.get('type') === 'path') {\n shapePoints = pathToPoints(shape.attr('path'));\n } else {\n var shapeBBox = shape.getCanvasBBox();\n shapePoints = [[shapeBBox.minX, shapeBBox.minY], [shapeBBox.maxX, shapeBBox.minY], [shapeBBox.maxX, shapeBBox.maxY], [shapeBBox.minX, shapeBBox.maxY]];\n }\n\n shapePoints = shapePoints.map(function (canvasPoint) {\n var point = _this.graph.getPointByCanvas(canvasPoint[0], canvasPoint[1]);\n\n return [point.x, point.y];\n });\n return math_isPolygonsIntersect(shapePoints, pathToPoints(this.path));\n };\n\n Hull.prototype.destroy = function () {\n this.group.remove();\n this.cfg = null;\n };\n\n return Hull;\n}();\n\n/* harmony default export */ var item_hull = (hull_Hull);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/graph.js\n\n\n\n\n\n\n\n\n\n\n\nvar graph_transform = matrix_util_esm[\"ext\"].transform;\nvar graph_NODE = 'node';\n\nvar graph_AbstractGraph =\n/** @class */\nfunction (_super) {\n Object(tslib_es6[\"__extends\"])(AbstractGraph, _super);\n\n function AbstractGraph(cfg) {\n var _this = _super.call(this) || this;\n\n _this.cfg = Object(esm[\"deepMix\"])(_this.getDefaultCfg(), cfg);\n\n _this.init();\n\n _this.animating = false;\n _this.destroyed = false; // 启用 stack 后,实例化 undoStack 和 redoStack\n\n if (_this.cfg.enabledStack) {\n // 实例化 undo 和 redo 栈\n _this.undoStack = new structs_stack(_this.cfg.maxStep);\n _this.redoStack = new structs_stack(_this.cfg.maxStep);\n }\n\n return _this;\n }\n\n AbstractGraph.prototype.init = function () {\n this.initCanvas(); // instance controller\n\n var viewController = new view(this);\n var modeController = new controller_mode(this);\n var itemController = new controller_item(this);\n var stateController = new controller_state(this);\n this.set({\n viewController: viewController,\n modeController: modeController,\n itemController: itemController,\n stateController: stateController\n }); // 初始化布局机制\n\n this.initLayoutController(); // 初始化事件机制\n\n this.initEventController();\n this.initGroups();\n /** 初始化插件 */\n\n this.initPlugins();\n }; // 初始化所有 Group\n\n\n AbstractGraph.prototype.initGroups = function () {\n var canvas = this.get('canvas');\n if (!canvas) return;\n var el = canvas.get('el');\n var _a = (el || {}).id,\n id = _a === void 0 ? 'g6' : _a;\n var group = canvas.addGroup({\n id: id + \"-root\",\n className: global.rootContainerClassName\n });\n\n if (this.get('groupByTypes')) {\n var edgeGroup = group.addGroup({\n id: id + \"-edge\",\n className: global.edgeContainerClassName\n });\n var nodeGroup = group.addGroup({\n id: id + \"-node\",\n className: global.nodeContainerClassName\n });\n var comboGroup = group.addGroup({\n id: id + \"-combo\",\n className: global.comboContainerClassName\n }); // 用于存储自定义的群组\n\n comboGroup.toBack();\n this.set({\n nodeGroup: nodeGroup,\n edgeGroup: edgeGroup,\n comboGroup: comboGroup\n });\n }\n\n var delegateGroup = group.addGroup({\n id: id + \"-delegate\",\n className: global.delegateContainerClassName\n });\n this.set({\n delegateGroup: delegateGroup\n });\n this.set('group', group);\n }; // eslint-disable-next-line class-methods-use-this\n\n\n AbstractGraph.prototype.getDefaultCfg = function () {\n return {\n /**\n * Container could be dom object or dom id\n */\n container: undefined,\n\n /**\n * Canvas width\n * unit pixel if undefined force fit width\n */\n width: undefined,\n\n /**\n * Canvas height\n * unit pixel if undefined force fit height\n */\n height: undefined,\n\n /**\n * renderer canvas or svg\n * @type {string}\n */\n renderer: 'canvas',\n\n /**\n * control graph behaviors\n */\n modes: {},\n\n /**\n * 注册插件\n */\n plugins: [],\n\n /**\n * source data\n */\n data: {},\n\n /**\n * Fit view padding (client scale)\n */\n fitViewPadding: 10,\n\n /**\n * Minimum scale size\n */\n minZoom: 0.2,\n\n /**\n * Maxmum scale size\n */\n maxZoom: 10,\n\n /**\n * capture events\n */\n event: true,\n\n /**\n * group node & edges into different graphic groups\n */\n groupByTypes: true,\n\n /**\n * determine if it's a directed graph\n */\n directed: false,\n\n /**\n * when data or shape changed, should canvas draw automatically\n */\n autoPaint: true,\n\n /**\n * store all the node instances\n */\n nodes: [],\n\n /**\n * store all the edge instances\n */\n edges: [],\n\n /**\n * store all the combo instances\n */\n combos: [],\n\n /**\n * store all the edge instances which are virtual edges related to collapsed combo\n */\n vedges: [],\n\n /**\n * all the instances indexed by id\n */\n itemMap: {},\n\n /**\n * 边直接连接到节点的中心,不再考虑锚点\n */\n linkCenter: false,\n\n /**\n * 默认的节点配置,data 上定义的配置会覆盖这些配置。例如:\n * defaultNode: {\n * type: 'rect',\n * size: [60, 40],\n * style: {\n * //... 样式配置项\n * }\n * }\n * 若数据项为 { id: 'node', x: 100, y: 100 }\n * 实际创建的节点模型是 { id: 'node', x: 100, y: 100, type: 'rect', size: [60, 40] }\n * 若数据项为 { id: 'node', x: 100, y: 100, type: 'circle' }\n * 实际创建的节点模型是 { id: 'node', x: 100, y: 100, type: 'circle', size: [60, 40] }\n */\n defaultNode: {},\n\n /**\n * 默认边配置,data 上定义的配置会覆盖这些配置。用法同 defaultNode\n */\n defaultEdge: {},\n\n /**\n * 节点默认样式,也可以添加状态样式\n * 例如:\n * const graph = new G6.Graph({\n * nodeStateStyles: {\n * selected: { fill: '#ccc', stroke: '#666' },\n * active: { lineWidth: 2 }\n * },\n * ...\n * });\n *\n */\n nodeStateStyles: {},\n\n /**\n * 边默认样式,用法同nodeStateStyle\n */\n edgeStateStyles: {},\n\n /**\n * graph 状态\n */\n states: {},\n\n /**\n * 是否启用全局动画\n */\n animate: false,\n\n /**\n * 动画设置,仅在 animate 为 true 时有效\n */\n animateCfg: {\n /**\n * 帧回调函数,用于自定义节点运动路径,为空时线性运动\n */\n onFrame: undefined,\n\n /**\n * 动画时长(ms)\n */\n duration: 500,\n\n /**\n * 指定动画动效\n */\n easing: 'easeLinear'\n },\n callback: undefined,\n // 默认不启用 undo & redo 功能\n enabledStack: false,\n // 只有当 enabledStack 为 true 时才起作用\n maxStep: 10,\n // 存储图上的 tooltip dom,方便销毁\n tooltips: []\n };\n };\n /**\n * 将值设置到 this.cfg 变量上面\n * @param key 键 或 对象值\n * @param val 值\n */\n\n\n AbstractGraph.prototype.set = function (key, val) {\n if (Object(esm[\"isPlainObject\"])(key)) {\n this.cfg = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, this.cfg), key);\n } else {\n this.cfg[key] = val;\n }\n\n return this;\n };\n /**\n * 获取 this.cfg 中的值\n * @param key 键\n */\n\n\n AbstractGraph.prototype.get = function (key) {\n var _a;\n\n return (_a = this.cfg) === null || _a === void 0 ? void 0 : _a[key];\n };\n /**\n * 获取 graph 的根图形分组\n * @return 根 group\n */\n\n\n AbstractGraph.prototype.getGroup = function () {\n return this.get('group');\n };\n /**\n * 获取 graph 的 DOM 容器\n * @return DOM 容器\n */\n\n\n AbstractGraph.prototype.getContainer = function () {\n return this.get('container');\n };\n /**\n * 获取 graph 的最小缩放比例\n * @return minZoom\n */\n\n\n AbstractGraph.prototype.getMinZoom = function () {\n return this.get('minZoom');\n };\n /**\n * 设置 graph 的最小缩放比例\n * @return minZoom\n */\n\n\n AbstractGraph.prototype.setMinZoom = function (ratio) {\n return this.set('minZoom', ratio);\n };\n /**\n * 获取 graph 的最大缩放比例\n * @param maxZoom\n */\n\n\n AbstractGraph.prototype.getMaxZoom = function () {\n return this.get('maxZoom');\n };\n /**\n * 设置 graph 的最大缩放比例\n * @param maxZoom\n */\n\n\n AbstractGraph.prototype.setMaxZoom = function (ratio) {\n return this.set('maxZoom', ratio);\n };\n /**\n * 获取 graph 的宽度\n * @return width\n */\n\n\n AbstractGraph.prototype.getWidth = function () {\n return this.get('width');\n };\n /**\n * 获取 graph 的高度\n * @return width\n */\n\n\n AbstractGraph.prototype.getHeight = function () {\n return this.get('height');\n };\n /**\n * 清理元素多个状态\n * @param {string|Item} item 元素id或元素实例\n * @param {string[]} states 状态\n */\n\n\n AbstractGraph.prototype.clearItemStates = function (item, states) {\n if (Object(esm[\"isString\"])(item)) {\n item = this.findById(item);\n }\n\n var itemController = this.get('itemController');\n\n if (!states) {\n states = item.get('states');\n }\n\n itemController.clearItemStates(item, states);\n var stateController = this.get('stateController');\n stateController.updateStates(item, states, false);\n };\n /**\n * 设置各个节点样式,以及在各种状态下节点 keyShape 的样式。\n * 若是自定义节点切在各种状态下\n * graph.node(node => {\n * return {\n * type: 'rect',\n * label: node.id,\n * style: { fill: '#666' },\n * stateStyles: {\n * selected: { fill: 'blue' },\n * custom: { fill: 'green' }\n * }\n * }\n * });\n * @param {function} nodeFn 指定每个节点样式\n */\n\n\n AbstractGraph.prototype.node = function (nodeFn) {\n if (typeof nodeFn === 'function') {\n this.set('nodeMapper', nodeFn);\n }\n };\n /**\n * 设置各个边样式\n * @param {function} edgeFn 指定每个边的样式,用法同 node\n */\n\n\n AbstractGraph.prototype.edge = function (edgeFn) {\n if (typeof edgeFn === 'function') {\n this.set('edgeMapper', edgeFn);\n }\n };\n /**\n * 设置各个 combo 的配置\n * @param comboFn\n */\n\n\n AbstractGraph.prototype.combo = function (comboFn) {\n if (typeof comboFn === 'function') {\n this.set('comboMapper', comboFn);\n }\n };\n /**\n * 根据 ID 查询图元素实例\n * @param id 图元素 ID\n */\n\n\n AbstractGraph.prototype.findById = function (id) {\n return this.get('itemMap')[id];\n };\n /**\n * 根据对应规则查找单个元素\n * @param {ITEM_TYPE} type 元素类型(node | edge | group)\n * @param {(item: T, index: number) => T} fn 指定规则\n * @return {T} 元素实例\n */\n\n\n AbstractGraph.prototype.find = function (type, fn) {\n var result;\n var items = this.get(type + \"s\"); // eslint-disable-next-line consistent-return\n\n Object(esm[\"each\"])(items, function (item, i) {\n if (fn(item, i)) {\n result = item;\n return result;\n }\n });\n return result;\n };\n /**\n * 查找所有满足规则的元素\n * @param {string} type 元素类型(node|edge)\n * @param {string} fn 指定规则\n * @return {array} 元素实例\n */\n\n\n AbstractGraph.prototype.findAll = function (type, fn) {\n var result = [];\n Object(esm[\"each\"])(this.get(type + \"s\"), function (item, i) {\n if (fn(item, i)) {\n result.push(item);\n }\n });\n return result;\n };\n /**\n * 查找所有处于指定状态的元素\n * @param {string} type 元素类型(node|edge)\n * @param {string} state 状态\n * @return {object} 元素实例\n */\n\n\n AbstractGraph.prototype.findAllByState = function (type, state) {\n return this.findAll(type, function (item) {\n return item.hasState(state);\n });\n };\n /**\n * 平移画布\n * @param dx 水平方向位移\n * @param dy 垂直方向位移\n */\n\n\n AbstractGraph.prototype.translate = function (dx, dy) {\n var group = this.get('group');\n var matrix = Object(esm[\"clone\"])(group.getMatrix());\n\n if (!matrix) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n matrix = graph_transform(matrix, [['t', dx, dy]]);\n group.setMatrix(matrix);\n this.emit('viewportchange', {\n action: 'translate',\n matrix: group.getMatrix()\n });\n this.autoPaint();\n };\n /**\n * 平移画布到某点\n * @param {number} x 水平坐标\n * @param {number} y 垂直坐标\n */\n\n\n AbstractGraph.prototype.moveTo = function (x, y, animate, animateCfg) {\n var group = this.get('group');\n move(group, {\n x: x,\n y: y\n }, animate, animateCfg || {\n duration: 500,\n easing: 'easeCubic'\n });\n this.emit('viewportchange', {\n action: 'move',\n matrix: group.getMatrix()\n });\n };\n /**\n * 调整视口适应视图\n * @param {object} padding 四周围边距\n * @param {FitViewRules} rules fitView的规则\n */\n\n\n AbstractGraph.prototype.fitView = function (padding, rules) {\n if (padding) {\n this.set('fitViewPadding', padding);\n }\n\n var viewController = this.get('viewController');\n\n if (rules) {\n viewController.fitViewByRules(rules);\n } else {\n viewController.fitView();\n }\n\n this.autoPaint();\n };\n /**\n * 调整视口适应视图,不缩放,仅将图 bbox 中心对齐到画布中心\n */\n\n\n AbstractGraph.prototype.fitCenter = function () {\n var viewController = this.get('viewController');\n viewController.fitCenter();\n this.autoPaint();\n };\n /**\n * 新增行为\n * @param {string | ModeOption | ModeType[]} behaviors 添加的行为\n * @param {string | string[]} modes 添加到对应的模式\n * @return {Graph} Graph\n */\n\n\n AbstractGraph.prototype.addBehaviors = function (behaviors, modes) {\n var modeController = this.get('modeController');\n modeController.manipulateBehaviors(behaviors, modes, true);\n return this;\n };\n /**\n * 移除行为\n * @param {string | ModeOption | ModeType[]} behaviors 移除的行为\n * @param {string | string[]} modes 从指定的模式中移除\n * @return {Graph} Graph\n */\n\n\n AbstractGraph.prototype.removeBehaviors = function (behaviors, modes) {\n var modeController = this.get('modeController');\n modeController.manipulateBehaviors(behaviors, modes, false);\n return this;\n };\n /**\n * 更新行为参数\n * @param {string | ModeOption | ModeType} behavior 需要更新的行为\n * @param {string | string[]} modes 指定的模式中的行为,不指定则为 default\n * @return {Graph} Graph\n */\n\n\n AbstractGraph.prototype.updateBehavior = function (behavior, newCfg, mode) {\n var modeController = this.get('modeController');\n modeController.updateBehavior(behavior, newCfg, mode);\n return this;\n };\n /**\n * 伸缩窗口\n * @param ratio 伸缩比例\n * @param center 以center的x, y坐标为中心缩放\n * @param {boolean} animate 是否带有动画地移动\n * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项\n * @return {boolean} 缩放是否成功\n */\n\n\n AbstractGraph.prototype.zoom = function (ratio, center, animate, animateCfg) {\n var _this = this;\n\n var group = this.get('group');\n var matrix = Object(esm[\"clone\"])(group.getMatrix());\n var minZoom = this.get('minZoom');\n var maxZoom = this.get('maxZoom');\n\n if (!matrix) {\n matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n if (center) {\n matrix = graph_transform(matrix, [['t', -center.x, -center.y], ['s', ratio, ratio], ['t', center.x, center.y]]);\n } else {\n matrix = graph_transform(matrix, [['s', ratio, ratio]]);\n }\n\n if (minZoom && matrix[0] < minZoom || maxZoom && matrix[0] > maxZoom) {\n return false;\n } // matrix = [2, 0, 0, 0, 2, 0, -125, -125, 1];\n\n\n if (animate) {\n // Clone the original matrix to perform the animation\n var aniMatrix_1 = Object(esm[\"clone\"])(group.getMatrix());\n\n if (!aniMatrix_1) {\n aniMatrix_1 = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n }\n\n var initialRatio_1 = aniMatrix_1[0];\n var targetRatio_1 = initialRatio_1 * ratio;\n var animateConfig = void 0;\n\n if (!animateCfg) {\n animateConfig = {\n duration: 500,\n callback: function callback() {\n _this.emit('viewportchange', {\n action: 'zoom',\n matrix: aniMatrix_1\n });\n }\n };\n } else if (animateCfg.callback) {\n // This is to prevent modifying the original animateCfg.callback\n var callback_1 = animateCfg.callback;\n animateConfig = Object(esm[\"clone\"])(animateCfg);\n\n animateConfig.callback = function () {\n _this.emit('viewportchange', {\n action: 'zoom',\n matrix: aniMatrix_1\n });\n\n callback_1();\n };\n } else {\n animateConfig = animateCfg;\n }\n\n group.animate(function (ratio) {\n if (ratio === 1) {\n // Reuse the first transformation\n aniMatrix_1 = matrix;\n } else {\n var scale = lerp(initialRatio_1, targetRatio_1, ratio) / aniMatrix_1[0];\n\n if (center) {\n aniMatrix_1 = graph_transform(aniMatrix_1, [['t', -center.x, -center.y], ['s', scale, scale], ['t', center.x, center.y]]);\n } else {\n aniMatrix_1 = graph_transform(aniMatrix_1, [['s', scale, scale]]);\n }\n }\n\n return {\n matrix: aniMatrix_1\n };\n }, animateConfig);\n } else {\n group.setMatrix(matrix);\n this.emit('viewportchange', {\n action: 'zoom',\n matrix: matrix\n });\n this.autoPaint();\n }\n\n return true;\n };\n /**\n * 伸缩视口到一固定比例\n * @param {number} toRatio 伸缩比例\n * @param {Point} center 以center的x, y坐标为中心缩放\n * @return {boolean} 缩放是否成功\n */\n\n\n AbstractGraph.prototype.zoomTo = function (toRatio, center) {\n var ratio = toRatio / this.getZoom();\n return this.zoom(ratio, center);\n };\n /**\n * 将元素移动到视口中心\n * @param {Item} item 指定元素\n * @param {boolean} animate 是否带有动画地移动\n * @param {GraphAnimateConfig} animateCfg 若带有动画,动画的配置项\n */\n\n\n AbstractGraph.prototype.focusItem = function (item, animate, animateCfg) {\n var viewController = this.get('viewController');\n var isAnimate = false;\n if (animate) isAnimate = true;else if (animate === undefined) isAnimate = this.get('animate');\n var curAniamteCfg = {};\n if (animateCfg) curAniamteCfg = animateCfg;else if (animateCfg === undefined) curAniamteCfg = this.get('animateCfg');\n viewController.focus(item, isAnimate, curAniamteCfg);\n this.autoPaint();\n };\n /**\n * 自动重绘\n * @internal 仅供内部更新机制调用,外部根据需求调用 render 或 paint 接口\n */\n\n\n AbstractGraph.prototype.autoPaint = function () {\n if (this.get('autoPaint')) {\n this.paint();\n }\n };\n /**\n * 仅画布重新绘制\n */\n\n\n AbstractGraph.prototype.paint = function () {\n this.emit('beforepaint');\n this.get('canvas').draw();\n this.emit('afterpaint');\n };\n /**\n * 将屏幕坐标转换为视口坐标\n * @param {number} clientX 屏幕x坐标\n * @param {number} clientY 屏幕y坐标\n * @return {Point} 视口坐标\n */\n\n\n AbstractGraph.prototype.getPointByClient = function (clientX, clientY) {\n var viewController = this.get('viewController');\n return viewController.getPointByClient(clientX, clientY);\n };\n /**\n * 将绘制坐标转换为屏幕坐标\n * @param {number} x 绘制坐标 x\n * @param {number} y 绘制坐标 y\n * @return {Point} 绘制坐标\n */\n\n\n AbstractGraph.prototype.getClientByPoint = function (x, y) {\n var viewController = this.get('viewController');\n return viewController.getClientByPoint(x, y);\n };\n /**\n * 将画布坐标转换为绘制坐标\n * @param {number} canvasX 画布 x 坐标\n * @param {number} canvasY 画布 y 坐标\n * @return {object} 绘制坐标\n */\n\n\n AbstractGraph.prototype.getPointByCanvas = function (canvasX, canvasY) {\n var viewController = this.get('viewController');\n return viewController.getPointByCanvas(canvasX, canvasY);\n };\n /**\n * 将绘制坐标转换为画布坐标\n * @param {number} x 绘制坐标 x\n * @param {number} y 绘制坐标 y\n * @return {object} 画布坐标\n */\n\n\n AbstractGraph.prototype.getCanvasByPoint = function (x, y) {\n var viewController = this.get('viewController');\n return viewController.getCanvasByPoint(x, y);\n };\n /**\n * 获取图内容的中心绘制坐标\n * @return {object} 中心绘制坐标\n */\n\n\n AbstractGraph.prototype.getGraphCenterPoint = function () {\n var bbox = this.get('group').getCanvasBBox();\n return {\n x: (bbox.minX + bbox.maxX) / 2,\n y: (bbox.minY + bbox.maxY) / 2\n };\n };\n /**\n * 获取视口中心绘制坐标\n * @return {object} 视口中心绘制坐标\n */\n\n\n AbstractGraph.prototype.getViewPortCenterPoint = function () {\n return this.getPointByCanvas(this.get('width') / 2, this.get('height') / 2);\n };\n /**\n * 显示元素\n * @param {Item} item 指定元素\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n */\n\n\n AbstractGraph.prototype.showItem = function (item, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n var itemController = this.get('itemController');\n var object = itemController.changeItemVisibility(item, true);\n\n if (stack && this.get('enabledStack')) {\n var id = object.getID();\n var type = object.getType();\n var before = {};\n var after = {};\n\n switch (type) {\n case 'node':\n before.nodes = [{\n id: id,\n visible: false\n }];\n after.nodes = [{\n id: id,\n visible: true\n }];\n break;\n\n case 'edge':\n before.nodes = [{\n id: id,\n visible: false\n }];\n after.edges = [{\n id: id,\n visible: true\n }];\n break;\n\n case 'combo':\n before.nodes = [{\n id: id,\n visible: false\n }];\n after.combos = [{\n id: id,\n visible: true\n }];\n break;\n\n default:\n break;\n }\n\n this.pushStack('visible', {\n before: before,\n after: after\n });\n }\n };\n /**\n * 隐藏元素\n * @param {Item} item 指定元素\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n */\n\n\n AbstractGraph.prototype.hideItem = function (item, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n var itemController = this.get('itemController');\n var object = itemController.changeItemVisibility(item, false);\n\n if (stack && this.get('enabledStack')) {\n var id = object.getID();\n var type = object.getType();\n var before = {};\n var after = {};\n\n switch (type) {\n case 'node':\n before.nodes = [{\n id: id,\n visible: true\n }];\n after.nodes = [{\n id: id,\n visible: false\n }];\n break;\n\n case 'edge':\n before.nodes = [{\n id: id,\n visible: true\n }];\n after.edges = [{\n id: id,\n visible: false\n }];\n break;\n\n case 'combo':\n before.nodes = [{\n id: id,\n visible: true\n }];\n after.combos = [{\n id: id,\n visible: false\n }];\n break;\n\n default:\n break;\n }\n\n this.pushStack('visible', {\n before: before,\n after: after\n });\n }\n };\n /**\n * 刷新元素\n * @param {string|object} item 元素id或元素实例\n */\n\n\n AbstractGraph.prototype.refreshItem = function (item) {\n var itemController = this.get('itemController');\n itemController.refreshItem(item);\n };\n /**\n * 设置是否在更新/刷新后自动重绘\n * @param {boolean} auto 自动重绘\n */\n\n\n AbstractGraph.prototype.setAutoPaint = function (auto) {\n var self = this;\n self.set('autoPaint', auto);\n var canvas = self.get('canvas');\n canvas.set('autoDraw', auto);\n };\n /**\n * 删除元素\n * @param {Item} item 元素id或元素实例\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n */\n\n\n AbstractGraph.prototype.remove = function (item, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n this.removeItem(item, stack);\n };\n /**\n * 删除元素\n * @param {Item} item 元素id或元素实例\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n */\n\n\n AbstractGraph.prototype.removeItem = function (item, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n var nodeItem = item;\n if (Object(esm[\"isString\"])(item)) nodeItem = this.findById(item);\n\n if (!nodeItem && Object(esm[\"isString\"])(item)) {\n console.warn('The item to be removed does not exist!');\n } else if (nodeItem) {\n var type = '';\n if (nodeItem.getType) type = nodeItem.getType(); // 将删除的元素入栈\n\n if (stack && this.get('enabledStack')) {\n var deletedModel = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, nodeItem.getModel()), {\n itemType: type\n });\n\n var before = {};\n\n switch (type) {\n case 'node':\n {\n before.nodes = [deletedModel];\n before.edges = [];\n var edges = nodeItem.getEdges();\n\n for (var i = edges.length - 1; i >= 0; i--) {\n before.edges.push(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, edges[i].getModel()), {\n itemType: 'edge'\n }));\n }\n\n break;\n }\n\n case 'edge':\n before.edges = [deletedModel];\n break;\n\n case 'combo':\n before.combos = [deletedModel];\n break;\n\n default:\n break;\n }\n\n this.pushStack('delete', {\n before: before,\n after: {}\n });\n }\n\n if (type === 'node') {\n var model = nodeItem.getModel(); // 如果删除的是节点,且该节点存在于某个 Combo 中,则需要先将 node 从 combo 中移除,否则删除节点后,操作 combo 会出错\n\n if (model.comboId) {\n this.updateComboTree(nodeItem, undefined, false);\n }\n }\n\n var itemController = this.get('itemController');\n itemController.removeItem(nodeItem);\n\n if (type === 'combo') {\n var newComboTrees = reconstructTree(this.get('comboTrees'));\n this.set('comboTrees', newComboTrees);\n }\n }\n };\n /**\n * 新增元素\n * @param {ITEM_TYPE} type 元素类型(node | edge)\n * @param {ModelConfig} model 元素数据模型\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n * @param {boolean} sortCombo 本次操作是否需要更新 combo 层级顺序,内部参数,用户在外部使用 addItem 时始终时需要更新\n * @return {Item} 元素实例\n */\n\n\n AbstractGraph.prototype.addItem = function (type, model, stack, sortCombo) {\n if (stack === void 0) {\n stack = true;\n }\n\n if (sortCombo === void 0) {\n sortCombo = true;\n }\n\n var currentComboSorted = this.get('comboSorted');\n this.set('comboSorted', currentComboSorted && !sortCombo);\n var itemController = this.get('itemController'); // 添加节点、边或combo之前,先验证数据是否符合规范\n\n if (!validation_singleDataValidation(type, model)) {\n return false;\n }\n\n if (model.id && this.findById(model.id)) {\n console.warn(\"This item exists already. Be sure the id %c\" + model.id + \"%c is unique.\", 'font-size: 20px; color: red;', '');\n return;\n }\n\n var item;\n var comboTrees = this.get('comboTrees');\n if (!comboTrees) comboTrees = [];\n\n if (type === 'combo') {\n var itemMap_1 = this.get('itemMap');\n var foundParent_1 = false;\n comboTrees.forEach(function (ctree) {\n if (foundParent_1) return; // terminate the forEach after the tree containing the item is done\n\n traverseTreeUp(ctree, function (child) {\n // find the parent\n if (model.parentId === child.id) {\n foundParent_1 = true;\n\n var newCombo = Object(tslib_es6[\"__assign\"])({\n id: model.id,\n depth: child.depth + 2\n }, model);\n\n if (child.children) child.children.push(newCombo);else child.children = [newCombo];\n model.depth = newCombo.depth;\n item = itemController.addItem(type, model);\n }\n\n var childItem = itemMap_1[child.id]; // after the parent is found, update all the ancestors\n\n if (foundParent_1 && childItem && childItem.getType && childItem.getType() === 'combo') {\n itemController.updateCombo(childItem, child.children);\n }\n\n return true;\n });\n }); // if the parent is not found, add it to the root\n\n if (!foundParent_1) {\n var newCombo = Object(tslib_es6[\"__assign\"])({\n id: model.id,\n depth: 0\n }, model);\n\n model.depth = newCombo.depth;\n comboTrees.push(newCombo);\n item = itemController.addItem(type, model);\n }\n\n this.set('comboTrees', comboTrees);\n } else if (type === 'node' && Object(esm[\"isString\"])(model.comboId) && comboTrees) {\n var parentCombo = this.findById(model.comboId);\n\n if (parentCombo && parentCombo.getType && parentCombo.getType() !== 'combo') {\n console.warn(\"'\" + model.comboId + \"' is not a id of a combo in the graph, the node will be added without combo.\");\n }\n\n item = itemController.addItem(type, model);\n var itemMap_2 = this.get('itemMap');\n var foundParent_2 = false,\n foundNode_1 = false;\n (comboTrees || []).forEach(function (ctree) {\n if (foundNode_1 || foundParent_2) return; // terminate the forEach\n\n traverseTreeUp(ctree, function (child) {\n if (child.id === model.id) {\n // if the item exists in the tree already, terminate\n foundNode_1 = true;\n return false;\n }\n\n if (model.comboId === child.id && !foundNode_1) {\n // found the parent, add the item to the children of its parent in the tree\n foundParent_2 = true;\n var cloneNode = Object(esm[\"clone\"])(model);\n cloneNode.itemType = 'node';\n if (child.children) child.children.push(cloneNode);else child.children = [cloneNode];\n cloneNode.depth = child.depth + 1;\n } // update the size of all the ancestors\n\n\n if (foundParent_2 && itemMap_2[child.id].getType && itemMap_2[child.id].getType() === 'combo') {\n itemController.updateCombo(itemMap_2[child.id], child.children);\n }\n\n return true;\n });\n });\n } else {\n item = itemController.addItem(type, model);\n }\n\n if (type === 'node' && model.comboId || type === 'combo' && model.parentId) {\n // add the combo to the parent's children array\n var parentCombo = this.findById(model.comboId || model.parentId);\n if (parentCombo && parentCombo.getType && parentCombo.getType() === 'combo') parentCombo.addChild(item);\n }\n\n var combos = this.get('combos');\n\n if (combos && combos.length > 0) {\n this.sortCombos();\n }\n\n this.autoPaint();\n\n if (stack && this.get('enabledStack')) {\n var addedModel = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, item.getModel()), {\n itemType: type\n });\n\n var after = {};\n\n switch (type) {\n case 'node':\n after.nodes = [addedModel];\n break;\n\n case 'edge':\n after.edges = [addedModel];\n break;\n\n case 'combo':\n after.combos = [addedModel];\n break;\n\n default:\n break;\n }\n\n this.pushStack('add', {\n before: {},\n after: after\n });\n }\n\n return item;\n };\n /**\n * 新增元素\n * @param {ITEM_TYPE} type 元素类型(node | edge)\n * @param {ModelConfig} model 元素数据模型\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n * @return {Item} 元素实例\n */\n\n\n AbstractGraph.prototype.add = function (type, model, stack, sortCombo) {\n if (stack === void 0) {\n stack = true;\n }\n\n if (sortCombo === void 0) {\n sortCombo = true;\n }\n\n return this.addItem(type, model, stack, sortCombo);\n };\n /**\n * 更新元素\n * @param {Item} item 元素id或元素实例\n * @param {Partial | EdgeConfig} cfg 需要更新的数据\n */\n\n\n AbstractGraph.prototype.updateItem = function (item, cfg, stack) {\n var _this = this;\n\n if (stack === void 0) {\n stack = true;\n }\n\n var itemController = this.get('itemController');\n var currentItem;\n\n if (Object(esm[\"isString\"])(item)) {\n currentItem = this.findById(item);\n } else {\n currentItem = item;\n }\n\n var UnupdateModel = Object(esm[\"clone\"])(currentItem.getModel());\n var type = '';\n if (currentItem.getType) type = currentItem.getType();\n\n var states = Object(tslib_es6[\"__spreadArray\"])([], currentItem.getStates(), true);\n\n if (type === 'combo') {\n Object(esm[\"each\"])(states, function (state) {\n return _this.setItemState(currentItem, state, false);\n });\n }\n\n itemController.updateItem(currentItem, cfg);\n\n if (type === 'combo') {\n Object(esm[\"each\"])(states, function (state) {\n return _this.setItemState(currentItem, state, true);\n });\n }\n\n if (stack && this.get('enabledStack')) {\n var before = {\n nodes: [],\n edges: [],\n combos: []\n };\n var after = {\n nodes: [],\n edges: [],\n combos: []\n };\n\n var afterModel = Object(tslib_es6[\"__assign\"])({\n id: UnupdateModel.id\n }, cfg);\n\n switch (type) {\n case 'node':\n before.nodes.push(UnupdateModel);\n after.nodes.push(afterModel);\n break;\n\n case 'edge':\n before.edges.push(UnupdateModel);\n after.edges.push(afterModel);\n break;\n\n case 'combo':\n before.combos.push(UnupdateModel);\n after.combos.push(afterModel);\n break;\n\n default:\n break;\n }\n\n if (type === 'node') {\n before.nodes.push(UnupdateModel);\n }\n\n this.pushStack('update', {\n before: before,\n after: after\n });\n }\n };\n /**\n * 更新元素\n * @param {Item} item 元素id或元素实例\n * @param {Partial | EdgeConfig} cfg 需要更新的数据\n * @param {boolean} stack 本次操作是否入栈,默认为 true\n */\n\n\n AbstractGraph.prototype.update = function (item, cfg, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n this.updateItem(item, cfg, stack);\n };\n /**\n * 设置元素状态\n * @param {Item} item 元素id或元素实例\n * @param {string} state 状态名称\n * @param {string | boolean} value 是否启用状态 或 状态值\n */\n\n\n AbstractGraph.prototype.setItemState = function (item, state, value) {\n if (Object(esm[\"isString\"])(item)) {\n item = this.findById(item);\n }\n\n var itemController = this.get('itemController');\n itemController.setItemState(item, state, value);\n var stateController = this.get('stateController');\n\n if (Object(esm[\"isString\"])(value)) {\n stateController.updateState(item, state + \":\" + value, true);\n } else {\n stateController.updateState(item, state, value);\n }\n };\n /**\n * 将指定状态的优先级提升为最高优先级\n * @param {Item} item 元素id或元素实例\n * @param state 状态名称\n */\n\n\n AbstractGraph.prototype.priorityState = function (item, state) {\n var itemController = this.get('itemController');\n itemController.priorityState(item, state);\n };\n /**\n * 设置视图初始化数据\n * @param {GraphData} data 初始化数据\n */\n\n\n AbstractGraph.prototype.data = function (data) {\n validation_dataValidation(data);\n this.set('data', data);\n };\n /**\n * 根据data接口的数据渲染视图\n */\n\n\n AbstractGraph.prototype.render = function () {\n var self = this;\n this.set('comboSorted', false);\n var data = this.get('data');\n\n if (this.get('enabledStack')) {\n // render 之前清空 redo 和 undo 栈\n this.clearStack();\n }\n\n if (!data) {\n throw new Error('data must be defined first');\n }\n\n var _a = data.nodes,\n nodes = _a === void 0 ? [] : _a,\n _b = data.edges,\n edges = _b === void 0 ? [] : _b,\n _c = data.combos,\n combos = _c === void 0 ? [] : _c;\n this.clear(true);\n this.emit('beforerender');\n Object(esm[\"each\"])(nodes, function (node) {\n self.add('node', node, false, false);\n }); // process the data to tree structure\n\n if (combos && combos.length !== 0) {\n var comboTrees = graphic_plainCombosToTrees(combos, nodes);\n this.set('comboTrees', comboTrees); // add combos\n\n self.addCombos(combos);\n }\n\n Object(esm[\"each\"])(edges, function (edge) {\n self.add('edge', edge, false, false);\n });\n var animate = self.get('animate');\n\n if (self.get('fitView') || self.get('fitCenter')) {\n self.set('animate', false);\n } // layout\n\n\n var layoutController = self.get('layoutController');\n\n if (layoutController) {\n layoutController.layout(success);\n if (this.destroyed) return;\n } else {\n if (self.get('fitView')) {\n self.fitView();\n }\n\n if (self.get('fitCenter')) {\n self.fitCenter();\n }\n\n self.emit('afterrender');\n self.set('animate', animate);\n } // 将在 onLayoutEnd 中被调用\n\n\n function success() {\n // fitView 与 fitCenter 共存时,fitView 优先,fitCenter 不再执行\n if (self.get('fitView')) {\n self.fitView();\n } else if (self.get('fitCenter')) {\n self.fitCenter();\n }\n\n self.autoPaint();\n self.emit('afterrender');\n\n if (self.get('fitView') || self.get('fitCenter')) {\n self.set('animate', animate);\n }\n }\n\n if (!this.get('groupByTypes')) {\n if (combos && combos.length !== 0) {\n this.sortCombos();\n } else {\n // 为提升性能,选择数量少的进行操作\n if (data.nodes && data.edges && data.nodes.length < data.edges.length) {\n var nodesArr = this.getNodes(); // 遍历节点实例,将所有节点提前。\n\n nodesArr.forEach(function (node) {\n node.toFront();\n });\n } else {\n var edgesArr = this.getEdges(); // 遍历节点实例,将所有节点提前。\n\n edgesArr.forEach(function (edge) {\n edge.toBack();\n });\n }\n }\n }\n\n if (this.get('enabledStack')) {\n this.pushStack('render');\n }\n };\n /**\n * 接收数据进行渲染\n * @Param {Object} data 初始化数据\n */\n\n\n AbstractGraph.prototype.read = function (data) {\n this.data(data);\n this.render();\n }; // 比较item\n\n\n AbstractGraph.prototype.diffItems = function (type, items, models) {\n var self = this;\n var item;\n var itemMap = this.get('itemMap');\n Object(esm[\"each\"])(models, function (model) {\n item = itemMap[model.id];\n\n if (item) {\n if (self.get('animate') && type === graph_NODE) {\n var containerMatrix = item.getContainer().getMatrix();\n if (!containerMatrix) containerMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n item.set('originAttrs', {\n x: containerMatrix[6],\n y: containerMatrix[7]\n });\n }\n\n self.updateItem(item, model, false);\n } else {\n item = self.addItem(type, model, false);\n }\n\n if (item) items[type + \"s\"].push(item);\n });\n };\n /**\n * 更改源数据,根据新数据重新渲染视图\n * @param {GraphData | TreeGraphData} data 源数据\n * @param {boolean} 是否入栈,默认为true\n * @return {object} this\n */\n\n\n AbstractGraph.prototype.changeData = function (data, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n var self = this;\n\n if (!validation_dataValidation(data)) {\n return this;\n }\n\n if (stack && this.get('enabledStack')) {\n this.pushStack('changedata', {\n before: self.save(),\n after: data\n });\n }\n\n this.set('comboSorted', false); // 删除 hulls\n\n this.removeHulls(); // 更改数据源后,取消所有状态\n\n this.getNodes().map(function (node) {\n return self.clearItemStates(node);\n });\n this.getEdges().map(function (edge) {\n return self.clearItemStates(edge);\n });\n var canvas = this.get('canvas');\n var localRefresh = canvas.get('localRefresh');\n canvas.set('localRefresh', false);\n\n if (!self.get('data')) {\n self.data(data);\n self.render();\n }\n\n var itemMap = this.get('itemMap');\n var items = {\n nodes: [],\n edges: []\n };\n var combosData = data.combos;\n\n if (combosData) {\n var comboTrees = graphic_plainCombosToTrees(combosData, data.nodes);\n this.set('comboTrees', comboTrees);\n } else {\n this.set('comboTrees', []);\n }\n\n this.diffItems('node', items, data.nodes);\n Object(esm[\"each\"])(itemMap, function (item, id) {\n itemMap[id].getModel().depth = 0;\n if (item.getType && item.getType() === 'edge') return;\n\n if (item.getType && item.getType() === 'combo') {\n delete itemMap[id];\n item.destroy();\n } else if (items.nodes.indexOf(item) < 0) {\n delete itemMap[id];\n self.remove(item, false);\n }\n }); // clear the destroyed combos here to avoid removing sub nodes before removing the parent combo\n\n var comboItems = this.getCombos();\n var combosLength = comboItems.length;\n\n for (var i = combosLength - 1; i >= 0; i--) {\n if (comboItems[i].destroyed) {\n comboItems.splice(i, 1);\n }\n } // process the data to tree structure\n\n\n if (combosData) {\n // add combos\n self.addCombos(combosData);\n\n if (!this.get('groupByTypes')) {\n this.sortCombos();\n }\n }\n\n this.diffItems('edge', items, data.edges);\n Object(esm[\"each\"])(itemMap, function (item, id) {\n if (item.getType && (item.getType() === 'node' || item.getType() === 'combo')) return;\n\n if (items.edges.indexOf(item) < 0) {\n delete itemMap[id];\n self.remove(item, false);\n }\n });\n this.set({\n nodes: items.nodes,\n edges: items.edges\n });\n var layoutController = this.get('layoutController');\n\n if (layoutController) {\n layoutController.changeData();\n\n if (self.get('animate') && !layoutController.getLayoutType()) {\n // 如果没有指定布局\n self.positionsAnimate();\n } else {\n self.autoPaint();\n }\n }\n\n setTimeout(function () {\n canvas.set('localRefresh', localRefresh);\n }, 16);\n return this;\n };\n /**\n * 私有方法,在 render 和 changeData 的时候批量添加数据中所有平铺的 combos\n * @param {ComboConfig[]} combos 平铺的 combos 数据\n */\n\n\n AbstractGraph.prototype.addCombos = function (combos) {\n var self = this;\n var comboTrees = self.get('comboTrees');\n var itemController = this.get('itemController');\n itemController.addCombos(comboTrees, combos);\n };\n /**\n * 根据已经存在的节点或 combo 创建新的 combo\n * @param combo combo ID 或 Combo 配置\n * @param children 添加到 Combo 中的元素,包括节点和 combo\n */\n\n\n AbstractGraph.prototype.createCombo = function (combo, children) {\n var _this = this;\n\n this.set('comboSorted', false); // step 1: 创建新的 Combo\n\n var comboId = '';\n var comboConfig;\n if (!combo) return;\n\n if (Object(esm[\"isString\"])(combo)) {\n comboId = combo;\n comboConfig = {\n id: combo\n };\n } else {\n comboId = combo.id;\n\n if (!comboId) {\n console.warn('Create combo failed. Please assign a unique string id for the adding combo.');\n return;\n }\n\n comboConfig = combo;\n } // step2: 更新 children,根据类型添加 comboId 或 parentId\n\n\n var trees = children.map(function (elementId) {\n var item = _this.findById(elementId);\n\n var model = item.getModel();\n var type = '';\n if (item.getType) type = item.getType();\n var cItem = {\n id: item.getID(),\n itemType: type\n };\n\n if (type === 'combo') {\n cItem.parentId = comboId;\n model.parentId = comboId;\n } else if (type === 'node') {\n cItem.comboId = comboId;\n model.comboId = comboId;\n }\n\n return cItem;\n });\n comboConfig.children = trees; // step 3: 添加 Combo,addItem 时会将子将元素添加到 Combo 中\n\n this.addItem('combo', comboConfig, false);\n this.set('comboSorted', false); // step4: 更新 comboTrees 结构\n\n var comboTrees = this.get('comboTrees');\n (comboTrees || []).forEach(function (ctree) {\n traverseTreeUp(ctree, function (child) {\n if (child.id === comboId) {\n child.itemType = 'combo';\n child.children = trees;\n return false;\n }\n\n return true;\n });\n });\n\n if (comboTrees) {\n this.sortCombos();\n }\n };\n /**\n * 解散 combo\n * @param {String | INode | ICombo} combo 需要被解散的 Combo item 或 id\n */\n\n\n AbstractGraph.prototype.uncombo = function (combo) {\n var _this = this;\n\n var _a;\n\n var self = this;\n var comboItem = combo;\n\n if (Object(esm[\"isString\"])(combo)) {\n comboItem = this.findById(combo);\n }\n\n if (!comboItem || comboItem.getType && comboItem.getType() !== 'combo') {\n console.warn('The item is not a combo!');\n return;\n }\n\n var parentId = comboItem.getModel().parentId;\n var comboTrees = self.get('comboTrees');\n if (!comboTrees) comboTrees = [];\n var itemMap = this.get('itemMap');\n var comboId = comboItem.get('id');\n var treeToBeUncombo;\n var brothers = [];\n var comboItems = this.get('combos');\n var parentItem = this.findById(parentId);\n comboTrees.forEach(function (ctree) {\n if (treeToBeUncombo) return; // terminate the forEach\n\n traverseTreeUp(ctree, function (subtree) {\n var _a; // find the combo to be uncomboed, delete the combo from map and cache\n\n\n if (subtree.id === comboId) {\n treeToBeUncombo = subtree; // delete the related edges\n\n var edges = comboItem.getEdges();\n edges.forEach(function (edge) {\n _this.removeItem(edge, false);\n });\n var index = comboItems.indexOf(comboItem);\n comboItems.splice(index, 1);\n delete itemMap[comboId];\n comboItem.destroy();\n\n _this.emit('afterremoveitem', {\n item: comboItem\n });\n } // find the parent to remove the combo from the combo's brothers array and add the combo's children to the combo's brothers array in the tree\n\n\n if (parentId && treeToBeUncombo && subtree.id === parentId) {\n parentItem.removeCombo(comboItem);\n brothers = subtree.children; // the combo's brothers\n // remove the combo from its brothers array\n\n var index = brothers.indexOf(treeToBeUncombo);\n\n if (index !== -1) {\n brothers.splice(index, 1);\n } // append the combo's children to the combo's brothers array\n\n\n (_a = treeToBeUncombo.children) === null || _a === void 0 ? void 0 : _a.forEach(function (child) {\n var item = _this.findById(child.id);\n\n var childModel = item.getModel();\n\n if (item.getType && item.getType() === 'combo') {\n child.parentId = parentId;\n delete child.comboId;\n childModel.parentId = parentId; // update the parentId of the model\n\n delete childModel.comboId;\n } else if (item.getType && item.getType() === 'node') {\n child.comboId = parentId;\n childModel.comboId = parentId; // update the parentId of the model\n }\n\n parentItem.addChild(item);\n brothers.push(child);\n });\n return false;\n }\n\n return true;\n });\n }); // if the parentId is not found, remove the combo from the roots\n\n if (!parentId && treeToBeUncombo) {\n var index = comboTrees.indexOf(treeToBeUncombo);\n comboTrees.splice(index, 1); // modify the parentId of the children\n\n (_a = treeToBeUncombo.children) === null || _a === void 0 ? void 0 : _a.forEach(function (child) {\n child.parentId = undefined;\n\n var childModel = _this.findById(child.id).getModel();\n\n delete childModel.parentId; // update the parentId of the model\n\n delete childModel.comboId; // update the comboId of the model\n\n if (child.itemType !== 'node') comboTrees.push(child);\n });\n }\n };\n /**\n * 根据节点的 bbox 更新所有 combos 的绘制,包括 combos 的位置和范围\n */\n\n\n AbstractGraph.prototype.updateCombos = function () {\n var _this = this;\n\n var self = this;\n var comboTrees = this.get('comboTrees');\n var itemController = self.get('itemController');\n var itemMap = self.get('itemMap');\n (comboTrees || []).forEach(function (ctree) {\n traverseTreeUp(ctree, function (child) {\n if (!child) {\n return true;\n }\n\n var childItem = itemMap[child.id];\n\n if (childItem && childItem.getType && childItem.getType() === 'combo') {\n // 更新具体的 Combo 之前先清除所有的已有状态,以免将 state 中的样式更新为 Combo 的样式\n var states = Object(tslib_es6[\"__spreadArray\"])([], childItem.getStates(), true);\n\n Object(esm[\"each\"])(states, function (state) {\n return _this.setItemState(childItem, state, false);\n }); // 更新具体的 Combo\n\n itemController.updateCombo(childItem, child.children); // 更新 Combo 后,还原已有的状态\n\n Object(esm[\"each\"])(states, function (state) {\n return _this.setItemState(childItem, state, true);\n });\n }\n\n return true;\n });\n });\n self.sortCombos();\n };\n /**\n * 根据节点的 bbox 更新 combo 及其祖先 combos 的绘制,包括 combos 的位置和范围\n * @param {String | ICombo} combo 需要被更新的 Combo 或 id,若指定,则该 Combo 及所有祖先 Combod 都会被更新\n */\n\n\n AbstractGraph.prototype.updateCombo = function (combo) {\n var _this = this;\n\n var self = this;\n var comboItem = combo;\n var comboId;\n\n if (Object(esm[\"isString\"])(combo)) {\n comboItem = this.findById(combo);\n }\n\n if (!comboItem || comboItem.getType && comboItem.getType() !== 'combo') {\n console.warn('The item to be updated is not a combo!');\n return;\n }\n\n comboId = comboItem.get('id');\n var comboTrees = this.get('comboTrees');\n var itemController = self.get('itemController');\n var itemMap = self.get('itemMap');\n (comboTrees || []).forEach(function (ctree) {\n traverseTreeUp(ctree, function (child) {\n if (!child) {\n return true;\n }\n\n var childItem = itemMap[child.id];\n\n if (comboId === child.id && childItem && childItem.getType && childItem.getType() === 'combo') {\n // 更新具体的 Combo 之前先清除所有的已有状态,以免将 state 中的样式更新为 Combo 的样式\n var states = Object(tslib_es6[\"__spreadArray\"])([], childItem.getStates(), true); // || !item.getStateStyle(stateName)\n\n\n Object(esm[\"each\"])(states, function (state) {\n if (childItem.getStateStyle(state)) {\n _this.setItemState(childItem, state, false);\n }\n }); // 更新具体的 Combo\n\n itemController.updateCombo(childItem, child.children); // 更新 Combo 后,还原已有的状态\n\n Object(esm[\"each\"])(states, function (state) {\n if (childItem.getStateStyle(state)) {\n _this.setItemState(childItem, state, true);\n }\n });\n if (comboId) comboId = child.parentId;\n }\n\n return true;\n });\n });\n };\n /**\n * 更新树结构,例如移动子树等\n * @param {String | INode | ICombo} item 需要被更新的 Combo 或 节点 id\n * @param {string | undefined} parentId 新的父 combo id,undefined 代表没有父 combo\n */\n\n\n AbstractGraph.prototype.updateComboTree = function (item, parentId, stack) {\n if (stack === void 0) {\n stack = true;\n }\n\n var self = this;\n this.set('comboSorted', false);\n var uItem;\n\n if (Object(esm[\"isString\"])(item)) {\n uItem = self.findById(item);\n } else {\n uItem = item;\n }\n\n var model = uItem.getModel();\n var oldParentId = model.comboId || model.parentId;\n var type = '';\n if (uItem.getType) type = uItem.getType(); // 若 item 是 Combo,且 parentId 是其子孙 combo 的 id,则警告并终止\n\n if (parentId && type === 'combo') {\n var comboTrees = this.get('comboTrees');\n var valid_1 = true;\n var itemSubTree_1;\n (comboTrees || []).forEach(function (ctree) {\n if (itemSubTree_1) return;\n traverseTree(ctree, function (subTree) {\n if (itemSubTree_1) return; // 找到从 item 开始的子树\n\n if (subTree.id === uItem.getID()) {\n itemSubTree_1 = subTree;\n }\n\n return true;\n });\n }); // 在以 item 为根的子树中寻找与 parentId 相同的后继元素\n\n traverseTree(itemSubTree_1, function (subTree) {\n if (subTree.id === parentId) {\n valid_1 = false;\n return false;\n }\n\n return true;\n }); // parentId 是 item 的一个后继元素,不能进行更新\n\n if (!valid_1) {\n console.warn('Failed to update the combo tree! The parentId points to a descendant of the combo!');\n return;\n }\n }\n\n if (stack && this.get('enabledStack')) {\n var beforeData = {},\n afterData = {};\n\n if (type === 'combo') {\n beforeData.combos = [{\n id: model.id,\n parentId: model.parentId\n }];\n afterData.combos = [{\n id: model.id,\n parentId: parentId\n }];\n } else if (type === 'node') {\n beforeData.nodes = [{\n id: model.id,\n parentId: model.comboId\n }];\n afterData.nodes = [{\n id: model.id,\n parentId: parentId\n }];\n }\n\n this.pushStack('updateComboTree', {\n before: beforeData,\n after: afterData\n });\n } // 当 combo 存在 parentId 或 comboId 时,才将其移除\n\n\n if (model.parentId || model.comboId) {\n var combo = this.findById(model.parentId || model.comboId);\n\n if (combo) {\n combo.removeChild(uItem);\n }\n }\n\n if (type === 'combo') {\n model.parentId = parentId;\n } else if (type === 'node') {\n model.comboId = parentId;\n } // 只有当移入到指定 combo 时才添加\n\n\n if (parentId) {\n var parentCombo = this.findById(parentId);\n\n if (parentCombo) {\n // 将元素添加到 parentCombo 中\n parentCombo.addChild(uItem);\n }\n } // 如果原先有父亲 combo,则从原父 combo 的子元素数组中删除\n\n\n if (oldParentId) {\n var parentCombo = this.findById(oldParentId);\n\n if (parentCombo) {\n // 将元素从 parentCombo 中移除\n parentCombo.removeChild(uItem);\n }\n }\n\n var newComboTrees = reconstructTree(this.get('comboTrees'), model.id, parentId);\n this.set('comboTrees', newComboTrees);\n this.updateCombos();\n };\n /**\n * 导出图数据\n * @return {object} data\n */\n\n\n AbstractGraph.prototype.save = function () {\n var nodes = [];\n var edges = [];\n var combos = [];\n Object(esm[\"each\"])(this.get('nodes'), function (node) {\n nodes.push(node.getModel());\n });\n Object(esm[\"each\"])(this.get('edges'), function (edge) {\n edges.push(edge.getModel());\n });\n Object(esm[\"each\"])(this.get('combos'), function (combo) {\n combos.push(combo.getModel());\n });\n return {\n nodes: nodes,\n edges: edges,\n combos: combos\n };\n };\n /**\n * 改变画布大小\n * @param {number} width 画布宽度\n * @param {number} height 画布高度\n * @return {object} this\n */\n\n\n AbstractGraph.prototype.changeSize = function (width, height) {\n var viewController = this.get('viewController');\n viewController.changeSize(width, height);\n return this;\n };\n /**\n * 当源数据在外部发生变更时,根据新数据刷新视图。但是不刷新节点位置\n */\n\n\n AbstractGraph.prototype.refresh = function () {\n var self = this;\n self.emit('beforegraphrefresh');\n\n if (self.get('animate')) {\n self.positionsAnimate();\n } else {\n var nodes = self.get('nodes');\n var edges = self.get('edges');\n var vedges = self.get('edges');\n Object(esm[\"each\"])(nodes, function (node) {\n node.refresh();\n });\n Object(esm[\"each\"])(edges, function (edge) {\n edge.refresh();\n });\n Object(esm[\"each\"])(vedges, function (vedge) {\n vedge.refresh();\n });\n }\n\n self.emit('aftergraphrefresh');\n self.autoPaint();\n };\n /**\n * 获取当前图中所有节点的item实例\n * @return {INode} item数组\n */\n\n\n AbstractGraph.prototype.getNodes = function () {\n return this.get('nodes');\n };\n /**\n * 获取当前图中所有边的item实例\n * @return {IEdge} item数组\n */\n\n\n AbstractGraph.prototype.getEdges = function () {\n return this.get('edges');\n };\n /**\n * 获取图中所有的 combo 实例\n */\n\n\n AbstractGraph.prototype.getCombos = function () {\n return this.get('combos');\n };\n /**\n * 获取指定 Combo 中所有的节点\n * @param comboId combo ID\n */\n\n\n AbstractGraph.prototype.getComboChildren = function (combo) {\n if (Object(esm[\"isString\"])(combo)) {\n combo = this.findById(combo);\n }\n\n if (!combo || combo.getType && combo.getType() !== 'combo') {\n console.warn('The combo does not exist!');\n return;\n }\n\n return combo.getChildren();\n };\n /**\n * 根据 graph 上的 animateCfg 进行视图中节点位置动画接口\n */\n\n\n AbstractGraph.prototype.positionsAnimate = function () {\n var self = this;\n self.emit('beforeanimate');\n var animateCfg = self.get('animateCfg');\n var onFrame = animateCfg.onFrame;\n var nodes = self.getNodes();\n var toNodes = nodes.map(function (node) {\n var model = node.getModel();\n return {\n id: model.id,\n x: model.x,\n y: model.y\n };\n });\n\n if (self.isAnimating()) {\n self.stopAnimate();\n }\n\n var canvas = self.get('canvas');\n canvas.animate(function (ratio) {\n Object(esm[\"each\"])(toNodes, function (data) {\n var node = self.findById(data.id);\n\n if (!node || node.destroyed) {\n return;\n }\n\n var originAttrs = node.get('originAttrs');\n var model = node.get('model');\n\n if (!originAttrs) {\n var containerMatrix = node.getContainer().getMatrix();\n if (!containerMatrix) containerMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n originAttrs = {\n x: containerMatrix[6],\n y: containerMatrix[7]\n };\n node.set('originAttrs', originAttrs);\n }\n\n if (onFrame) {\n var attrs = onFrame(node, ratio, data, originAttrs);\n node.set('model', Object.assign(model, attrs));\n } else {\n model.x = originAttrs.x + (data.x - originAttrs.x) * ratio;\n model.y = originAttrs.y + (data.y - originAttrs.y) * ratio;\n }\n });\n self.refreshPositions();\n }, {\n duration: animateCfg.duration,\n easing: animateCfg.easing,\n callback: function callback() {\n Object(esm[\"each\"])(nodes, function (node) {\n node.set('originAttrs', null);\n });\n\n if (animateCfg.callback) {\n animateCfg.callback();\n }\n\n self.emit('afteranimate');\n self.animating = false;\n }\n });\n };\n /**\n * 当节点位置在外部发生改变时,刷新所有节点位置,重计算边\n */\n\n\n AbstractGraph.prototype.refreshPositions = function () {\n var self = this;\n self.emit('beforegraphrefreshposition');\n var nodes = self.get('nodes');\n var edges = self.get('edges');\n var vedges = self.get('vedges');\n var combos = self.get('combos');\n var model;\n var updatedNodes = {};\n Object(esm[\"each\"])(nodes, function (node) {\n model = node.getModel();\n var originAttrs = node.get('originAttrs');\n\n if (originAttrs && model.x === originAttrs.x && model.y === originAttrs.y) {\n return;\n }\n\n var changed = node.updatePosition({\n x: model.x,\n y: model.y\n });\n updatedNodes[model.id] = changed;\n if (model.comboId) updatedNodes[model.comboId] = updatedNodes[model.comboId] || changed;\n });\n\n if (combos && combos.length !== 0) {\n self.updateCombos();\n }\n\n Object(esm[\"each\"])(edges, function (edge) {\n var sourceModel = edge.getSource().getModel();\n var target = edge.getTarget(); // 避免 target 是纯对象的情况下调用 getModel 方法\n // 拖动生成边的时候 target 会是纯对象\n\n if (!Object(esm[\"isPlainObject\"])(target)) {\n var targetModel = target.getModel();\n\n if (updatedNodes[sourceModel.id] || updatedNodes[targetModel.id] || edge.getModel().isComboEdge) {\n edge.refresh();\n }\n }\n });\n Object(esm[\"each\"])(vedges, function (vedge) {\n vedge.refresh();\n });\n self.emit('aftergraphrefreshposition');\n self.autoPaint();\n };\n\n AbstractGraph.prototype.stopAnimate = function () {\n this.get('canvas').stopAnimate();\n };\n\n AbstractGraph.prototype.isAnimating = function () {\n return this.animating;\n };\n /**\n * 获取当前视口伸缩比例\n * @return {number} 比例\n */\n\n\n AbstractGraph.prototype.getZoom = function () {\n var matrix = this.get('group').getMatrix();\n return matrix ? matrix[0] : 1;\n };\n /**\n * 获取当前的行为模式\n * @return {string} 当前行为模式\n */\n\n\n AbstractGraph.prototype.getCurrentMode = function () {\n var modeController = this.get('modeController');\n return modeController.getMode();\n };\n /**\n * 切换行为模式\n * @param {string} mode 指定模式\n * @return {object} this\n */\n\n\n AbstractGraph.prototype.setMode = function (mode) {\n var modeController = this.get('modeController');\n modeController.setMode(mode);\n return this;\n };\n /**\n * 清除画布元素\n * @return {object} this\n */\n\n\n AbstractGraph.prototype.clear = function (avoidEmit) {\n var _a;\n\n if (avoidEmit === void 0) {\n avoidEmit = false;\n }\n\n (_a = this.get('canvas')) === null || _a === void 0 ? void 0 : _a.clear();\n this.initGroups(); // 清空画布时同时清除数据\n\n this.set({\n itemMap: {},\n nodes: [],\n edges: [],\n groups: [],\n combos: [],\n comboTrees: []\n });\n if (!avoidEmit) this.emit('afterrender');\n return this;\n };\n /**\n * 更换布局配置项\n * @param {object} cfg 新布局配置项\n * @param {'center' | 'begin'} align 对齐方式,可选中心(center)对齐到对齐点,或左上角(begin)对齐到对齐点\n * @param {IPoint} alignPoint 画布上的对齐点,为 Canvas 坐标系(Canvas DOM)\n * 若 cfg 含有 type 字段或为 String 类型,且与现有布局方法不同,则更换布局\n * 若 cfg 不包括 type ,则保持原有布局方法,仅更新布局配置项\n */\n\n\n AbstractGraph.prototype.updateLayout = function (cfg, align, alignPoint) {\n var _this = this;\n\n var layoutController = this.get('layoutController');\n\n if (Object(esm[\"isString\"])(cfg)) {\n cfg = {\n type: cfg\n };\n } // align the graph after layout\n\n\n if (align) {\n var toPoint_1 = alignPoint;\n\n if (!toPoint_1) {\n if (align === 'begin') toPoint_1 = {\n x: 0,\n y: 0\n };else toPoint_1 = {\n x: this.getWidth() / 2,\n y: this.getHeight() / 2\n };\n } // translate to point coordinate system\n\n\n toPoint_1 = this.getPointByCanvas(toPoint_1.x, toPoint_1.y);\n var forceTypes = ['force', 'gForce', 'fruchterman']; // if it is force layout, only center takes effect, and assign center force\n\n if (forceTypes.includes(cfg.type) || !cfg.type && forceTypes.includes(layoutController === null || layoutController === void 0 ? void 0 : layoutController.layoutType)) {\n cfg.center = [toPoint_1.x, toPoint_1.y];\n } else {\n this.once('afterlayout', function (e) {\n var matrix = _this.getGroup().getMatrix() || [1, 0, 0, 0, 1, 0, 0, 0, 1];\n toPoint_1.x = toPoint_1.x * matrix[0] + matrix[6];\n toPoint_1.y = toPoint_1.y * matrix[0] + matrix[7];\n\n var _a = _this.getGroup().getCanvasBBox(),\n minX = _a.minX,\n maxX = _a.maxX,\n minY = _a.minY,\n maxY = _a.maxY;\n\n var bboxPoint = {\n x: (minX + maxX) / 2,\n y: (minY + maxY) / 2\n };\n\n if (align === 'begin') {\n bboxPoint.x = minX;\n bboxPoint.y = minY;\n }\n\n _this.translate(toPoint_1.x - bboxPoint.x, toPoint_1.y - bboxPoint.y);\n });\n }\n }\n\n var oriLayoutCfg = this.get('layout');\n var layoutCfg = {};\n Object.assign(layoutCfg, oriLayoutCfg, cfg);\n this.set('layout', layoutCfg);\n\n if (layoutController.isLayoutTypeSame(layoutCfg) && layoutCfg.gpuEnabled === oriLayoutCfg.gpuEnabled) {\n // no type or same type, or switch the gpu and cpu, update layout\n layoutController.updateLayoutCfg(layoutCfg);\n } else {\n // has different type, change layout\n layoutController.changeLayout(layoutCfg);\n }\n };\n /**\n * 销毁布局,changeData 时不会再使用原来的布局方法对新数据进行布局\n */\n\n\n AbstractGraph.prototype.destroyLayout = function () {\n var layoutController = this.get('layoutController');\n layoutController.destroyLayout();\n };\n /**\n * 重新以当前示例中配置的属性进行一次布局\n */\n\n\n AbstractGraph.prototype.layout = function () {\n var layoutController = this.get('layoutController');\n var layoutCfg = this.get('layout');\n if (!layoutCfg || !layoutController) return;\n\n if (layoutCfg.workerEnabled) {\n // 如果使用web worker布局\n layoutController.layout();\n return;\n }\n\n if (layoutController.layoutMethod) {\n layoutController.relayout(true);\n } else {\n layoutController.layout();\n }\n };\n /**\n * 收起指定的 combo\n * @param {string | ICombo} combo combo ID 或 combo item\n */\n\n\n AbstractGraph.prototype.collapseCombo = function (combo) {\n var _this = this;\n\n if (Object(esm[\"isString\"])(combo)) {\n combo = this.findById(combo);\n }\n\n if (!combo) {\n console.warn('The combo to be collapsed does not exist!');\n return;\n }\n\n this.emit('beforecollapseexpandcombo', {\n action: 'expand',\n item: combo\n });\n var comboModel = combo.getModel();\n var itemController = this.get('itemController');\n itemController.collapseCombo(combo);\n comboModel.collapsed = true; // add virtual edges\n\n var edges = this.getEdges().concat(this.get('vedges')); // find all the descendant nodes and combos\n\n var cnodes = [];\n var ccombos = [];\n var comboTrees = this.get('comboTrees');\n var found = false;\n (comboTrees || []).forEach(function (ctree) {\n if (found) return; // if the combo is found, terminate the forEach\n\n traverseTree(ctree, function (subTree) {\n // if the combo is found and it is traversing the other branches, terminate\n if (found && subTree.depth <= comboModel.depth) return false; // if the combo is found\n\n if (comboModel.id === subTree.id) found = true;\n\n if (found) {\n // if the combo is found, concat the descendant nodes and combos\n var item = _this.findById(subTree.id);\n\n if (item && item.getType && item.getType() === 'combo') {\n cnodes = cnodes.concat(item.getNodes());\n ccombos = ccombos.concat(item.getCombos());\n }\n }\n\n return true;\n });\n });\n var edgeWeightMap = {};\n var addedVEdges = [];\n edges.forEach(function (edge) {\n if (edge.isVisible() && !edge.getModel().isVEdge) return;\n var source = edge.getSource();\n var target = edge.getTarget();\n\n if ((cnodes.includes(source) || ccombos.includes(source)) && !cnodes.includes(target) && !ccombos.includes(target) || source.getModel().id === comboModel.id) {\n var edgeModel = edge.getModel();\n\n if (edgeModel.isVEdge) {\n _this.removeItem(edge, false);\n\n return;\n }\n\n var targetModel = target.getModel();\n\n while (!target.isVisible()) {\n target = _this.findById(targetModel.parentId || targetModel.comboId);\n if (!target || !targetModel.parentId && !targetModel.comboId) return; // all the ancestors are hidden, then ignore the edge\n\n targetModel = target.getModel();\n }\n\n var targetId = targetModel.id;\n\n if (edgeWeightMap[comboModel.id + \"-\" + targetId]) {\n edgeWeightMap[comboModel.id + \"-\" + targetId] += edgeModel.size || 1;\n return;\n } // the source is in the combo, the target is not\n\n\n var vedge = _this.addItem('vedge', {\n source: comboModel.id,\n target: targetId,\n isVEdge: true\n }, false);\n\n edgeWeightMap[comboModel.id + \"-\" + targetId] = edgeModel.size || 1;\n addedVEdges.push(vedge);\n } else if (!cnodes.includes(source) && !ccombos.includes(source) && (cnodes.includes(target) || ccombos.includes(target)) || target.getModel().id === comboModel.id) {\n var edgeModel = edge.getModel();\n\n if (edgeModel.isVEdge) {\n _this.removeItem(edge, false);\n\n return;\n }\n\n var sourceModel = source.getModel();\n\n while (!source.isVisible()) {\n source = _this.findById(sourceModel.parentId || sourceModel.comboId);\n if (!source || !sourceModel.parentId && !sourceModel.comboId) return; // all the ancestors are hidden, then ignore the edge\n\n sourceModel = source.getModel();\n }\n\n var sourceId = sourceModel.id;\n\n if (edgeWeightMap[sourceId + \"-\" + comboModel.id]) {\n edgeWeightMap[sourceId + \"-\" + comboModel.id] += edgeModel.size || 1;\n return;\n } // the target is in the combo, the source is not\n\n\n var vedge = _this.addItem('vedge', {\n target: comboModel.id,\n source: sourceId,\n isVEdge: true\n }, false);\n\n edgeWeightMap[sourceId + \"-\" + comboModel.id] = edgeModel.size || 1;\n addedVEdges.push(vedge);\n }\n }); // update the width of the virtual edges, which is the sum of merged actual edges\n // be attention that the actual edges with same endpoints but different directions will be represented by two different virtual edges\n\n addedVEdges.forEach(function (vedge) {\n var vedgeModel = vedge.getModel();\n\n _this.updateItem(vedge, {\n size: edgeWeightMap[vedgeModel.source + \"-\" + vedgeModel.target]\n }, false);\n });\n this.emit('aftercollapseexpandcombo', {\n action: 'collapse',\n item: combo\n });\n };\n /**\n * 展开指定的 combo\n * @param {string | ICombo} combo combo ID 或 combo item\n */\n\n\n AbstractGraph.prototype.expandCombo = function (combo) {\n var _this = this;\n\n if (Object(esm[\"isString\"])(combo)) {\n combo = this.findById(combo);\n }\n\n if (!combo || combo.getType && combo.getType() !== 'combo') {\n console.warn('The combo to be collapsed does not exist!');\n return;\n }\n\n this.emit('beforecollapseexpandcombo', {\n action: 'expand',\n item: combo\n });\n var comboModel = combo.getModel();\n var itemController = this.get('itemController');\n itemController.expandCombo(combo);\n comboModel.collapsed = false; // add virtual edges\n\n var edges = this.getEdges().concat(this.get('vedges')); // find all the descendant nodes and combos\n\n var cnodes = [];\n var ccombos = [];\n var comboTrees = this.get('comboTrees');\n var found = false;\n (comboTrees || []).forEach(function (ctree) {\n if (found) return; // if the combo is found, terminate\n\n traverseTree(ctree, function (subTree) {\n // if the combo is found and it is traversing the other branches, terminate\n if (found && subTree.depth <= comboModel.depth) return false;\n if (comboModel.id === subTree.id) found = true;\n\n if (found) {\n var item = _this.findById(subTree.id);\n\n if (item && item.getType && item.getType() === 'combo') {\n cnodes = cnodes.concat(item.getNodes());\n ccombos = ccombos.concat(item.getCombos());\n }\n }\n\n return true;\n });\n });\n var edgeWeightMap = {};\n var addedVEdges = {};\n edges.forEach(function (edge) {\n if (edge.isVisible() && !edge.getModel().isVEdge) return;\n var source = edge.getSource();\n var target = edge.getTarget();\n var sourceId = source.get('id');\n var targetId = target.get('id');\n\n if ((cnodes.includes(source) || ccombos.includes(source)) && !cnodes.includes(target) && !ccombos.includes(target) || sourceId === comboModel.id) {\n // the source is in the combo, the target is not\n // ignore the virtual edges\n if (edge.getModel().isVEdge) {\n _this.removeItem(edge, false);\n\n return;\n }\n\n var targetModel = target.getModel(); // find the nearest visible ancestor\n\n while (!target.isVisible()) {\n target = _this.findById(targetModel.comboId || targetModel.parentId);\n\n if (!target || !targetModel.parentId && !targetModel.comboId) {\n return; // if all the ancestors of the oppsite are all hidden, ignore the edge\n }\n\n targetModel = target.getModel();\n }\n\n targetId = targetModel.id;\n var sourceModel = source.getModel(); // find the nearest visible ancestor\n\n while (!source.isVisible()) {\n source = _this.findById(sourceModel.comboId || sourceModel.parentId);\n\n if (!source || !sourceModel.parentId && !sourceModel.comboId) {\n return; // if all the ancestors of the oppsite are all hidden, ignore the edge\n }\n\n if (sourceModel.comboId === comboModel.id || sourceModel.parentId === comboModel.id) {\n break; // if the next ancestor is the combo, break the while\n }\n\n sourceModel = source.getModel();\n }\n\n sourceId = sourceModel.id;\n\n if (targetId) {\n var vedgeId = sourceId + \"-\" + targetId; // update the width of the virtual edges, which is the sum of merged actual edges\n // be attention that the actual edges with same endpoints but different directions will be represented by two different virtual edges\n\n if (edgeWeightMap[vedgeId]) {\n edgeWeightMap[vedgeId] += edge.getModel().size || 1;\n\n _this.updateItem(addedVEdges[vedgeId], {\n size: edgeWeightMap[vedgeId]\n }, false);\n\n return;\n }\n\n var vedge = _this.addItem('vedge', {\n source: sourceId,\n target: targetId,\n isVEdge: true\n }, false);\n\n edgeWeightMap[vedgeId] = edge.getModel().size || 1;\n addedVEdges[vedgeId] = vedge;\n }\n } else if (!cnodes.includes(source) && !ccombos.includes(source) && (cnodes.includes(target) || ccombos.includes(target)) || targetId === comboModel.id) {\n // the target is in the combo, the source is not\n // ignore the virtual edges\n if (edge.getModel().isVEdge) {\n _this.removeItem(edge, false);\n\n return;\n }\n\n var sourceModel = source.getModel(); // find the nearest visible ancestor\n\n while (!source.isVisible()) {\n source = _this.findById(sourceModel.comboId || sourceModel.parentId);\n\n if (!source || !sourceModel.parentId && !sourceModel.comboId) {\n return; // if all the ancestors of the oppsite are all hidden, ignore the edge\n }\n\n sourceModel = source.getModel();\n }\n\n sourceId = sourceModel.id;\n var targetModel = target.getModel(); // find the nearest visible ancestor\n\n while (!target.isVisible()) {\n target = _this.findById(targetModel.comboId || targetModel.parentId);\n\n if (!target || !targetModel.parentId && !targetModel.comboId) {\n return; // if all the ancestors of the oppsite are all hidden, ignore the edge\n }\n\n if (targetModel.comboId === comboModel.id || targetModel.parentId === comboModel.id) {\n break; // if the next ancestor is the combo, break the while\n }\n\n targetModel = target.getModel();\n }\n\n targetId = targetModel.id;\n\n if (sourceId) {\n var vedgeId = sourceId + \"-\" + targetId; // update the width of the virtual edges, which is the sum of merged actual edges\n // be attention that the actual edges with same endpoints but different directions will be represented by two different virtual edges\n\n if (edgeWeightMap[vedgeId]) {\n edgeWeightMap[vedgeId] += edge.getModel().size || 1;\n\n _this.updateItem(addedVEdges[vedgeId], {\n size: edgeWeightMap[vedgeId]\n }, false);\n\n return;\n }\n\n var vedge = _this.addItem('vedge', {\n target: targetId,\n source: sourceId,\n isVEdge: true\n }, false);\n\n edgeWeightMap[vedgeId] = edge.getModel().size || 1;\n addedVEdges[vedgeId] = vedge;\n }\n } else if ((cnodes.includes(source) || ccombos.includes(source)) && (cnodes.includes(target) || ccombos.includes(target))) {\n // both source and target are in the combo, if the target and source are both visible, show the edge\n if (source.isVisible() && target.isVisible()) {\n edge.show();\n }\n }\n });\n this.emit('aftercollapseexpandcombo', {\n action: 'expand',\n item: combo\n });\n };\n\n AbstractGraph.prototype.collapseExpandCombo = function (combo) {\n if (Object(esm[\"isString\"])(combo)) {\n combo = this.findById(combo);\n }\n\n if (!combo || combo.getType && combo.getType() !== 'combo') return;\n var comboModel = combo.getModel(); // if one ancestor combo of the combo is collapsed, it should not be collapsed or expanded\n\n var parentItem = this.findById(comboModel.parentId);\n\n while (parentItem) {\n var parentModel = parentItem.getModel();\n\n if (parentModel.collapsed) {\n console.warn(\"Fail to expand the combo since it's ancestor combo is collapsed.\");\n parentItem = undefined;\n return;\n }\n\n parentItem = this.findById(parentModel.parentId);\n }\n\n var collapsed = comboModel.collapsed; // 该群组已经处于收起状态,需要展开\n\n if (collapsed) {\n this.expandCombo(combo);\n } else {\n this.collapseCombo(combo);\n }\n\n this.updateCombo(combo);\n };\n /**\n * 根据 comboTree 结构整理 Combo 相关的图形绘制层级,包括 Combo 本身、节点、边\n * @param {GraphData} data 数据\n */\n\n\n AbstractGraph.prototype.sortCombos = function () {\n var _this = this;\n\n var comboSorted = this.get('comboSorted');\n if (comboSorted) return;\n this.set('comboSorted', true);\n var depthMap = [];\n var dataDepthMap = {};\n var comboTrees = this.get('comboTrees');\n (comboTrees || []).forEach(function (cTree) {\n traverseTree(cTree, function (child) {\n if (depthMap[child.depth]) depthMap[child.depth].push(child.id);else depthMap[child.depth] = [child.id];\n dataDepthMap[child.id] = child.depth;\n return true;\n });\n });\n var edges = this.getEdges().concat(this.get('vedges'));\n (edges || []).forEach(function (edgeItem) {\n var edge = edgeItem.getModel();\n var sourceDepth = dataDepthMap[edge.source] || 0;\n var targetDepth = dataDepthMap[edge.target] || 0;\n var depth = Math.max(sourceDepth, targetDepth);\n if (depthMap[depth]) depthMap[depth].push(edge.id);else depthMap[depth] = [edge.id];\n });\n depthMap.forEach(function (array) {\n if (!array || !array.length) return;\n\n for (var i = array.length - 1; i >= 0; i--) {\n var item = _this.findById(array[i]);\n\n if (item) item.toFront();\n }\n });\n };\n /**\n * 获取节点所有的邻居节点\n *\n * @param {(string | INode)} node 节点 ID 或实例\n * @returns {INode[]}\n * @memberof IAbstractGraph\n */\n\n\n AbstractGraph.prototype.getNeighbors = function (node, type) {\n var item = node;\n\n if (Object(esm[\"isString\"])(node)) {\n item = this.findById(node);\n }\n\n return item.getNeighbors(type);\n };\n /**\n * 获取 node 的度数\n *\n * @param {(string | INode)} node 节点 ID 或实例\n * @param {('in' | 'out' | 'total' | 'all' | undefined)} 度数类型,in 入度,out 出度,total 总度数,all 返回三种类型度数的对象\n * @returns {Number | Object} 该节点的度数\n * @memberof IAbstractGraph\n */\n\n\n AbstractGraph.prototype.getNodeDegree = function (node, type, refresh) {\n if (type === void 0) {\n type = undefined;\n }\n\n if (refresh === void 0) {\n refresh = false;\n }\n\n var item = node;\n\n if (Object(esm[\"isString\"])(node)) {\n item = this.findById(node);\n }\n\n var degrees = this.get('degrees');\n\n if (!degrees || refresh) {\n degrees = es_degree(this.save());\n this.set('degrees', degrees);\n }\n\n var nodeDegrees = degrees[item.getID()];\n var res = 0; // 如果是通过 addItem 后面新增加的节点,此时它的所有度数都为 0\n\n if (!nodeDegrees) {\n return 0;\n }\n\n switch (type) {\n case 'in':\n res = nodeDegrees.inDegree;\n break;\n\n case 'out':\n res = nodeDegrees.outDegree;\n break;\n\n case 'all':\n res = nodeDegrees;\n break;\n\n default:\n res = nodeDegrees.degree;\n break;\n }\n\n return res;\n };\n\n AbstractGraph.prototype.getUndoStack = function () {\n return this.undoStack;\n };\n\n AbstractGraph.prototype.getRedoStack = function () {\n return this.redoStack;\n };\n /**\n * 获取 undo 和 redo 栈的数据\n */\n\n\n AbstractGraph.prototype.getStackData = function () {\n if (!this.get('enabledStack')) {\n return null;\n }\n\n return {\n undoStack: this.undoStack.toArray(),\n redoStack: this.redoStack.toArray()\n };\n };\n /**\n * 清空 undo stack & redo stack\n */\n\n\n AbstractGraph.prototype.clearStack = function () {\n if (this.get('enabledStack')) {\n this.undoStack.clear();\n this.redoStack.clear();\n }\n };\n /**\n * 将操作类型和操作数据入栈\n * @param action 操作类型\n * @param data 入栈的数据\n * @param stackType 栈的类型\n */\n\n\n AbstractGraph.prototype.pushStack = function (action, data, stackType) {\n if (action === void 0) {\n action = 'update';\n }\n\n if (stackType === void 0) {\n stackType = 'undo';\n }\n\n if (!this.get('enabledStack')) {\n console.warn('请先启用 undo & redo 功能,在实例化 Graph 时候配置 enabledStack: true !');\n return;\n }\n\n var stackData = data ? Object(esm[\"clone\"])(data) : {\n before: {},\n after: Object(esm[\"clone\"])(this.save())\n };\n\n if (stackType === 'redo') {\n this.redoStack.push({\n action: action,\n data: stackData\n });\n } else {\n this.undoStack.push({\n action: action,\n data: stackData\n });\n }\n\n this.emit('stackchange', {\n undoStack: this.undoStack,\n redoStack: this.redoStack\n });\n };\n /**\n * 获取邻接矩阵\n *\n * @param {boolean} cache 是否使用缓存的\n * @param {boolean} directed 是否是有向图,默认取 graph.directed\n * @returns {Matrix} 邻接矩阵\n * @memberof IAbstractGraph\n */\n\n\n AbstractGraph.prototype.getAdjMatrix = function (cache, directed) {\n if (cache === void 0) {\n cache = true;\n }\n\n if (directed === undefined) directed = this.get('directed');\n var currentAdjMatrix = this.get('adjMatrix');\n\n if (!currentAdjMatrix || !cache) {\n currentAdjMatrix = adjacent_matrix(this.save(), directed);\n this.set('adjMatrix', currentAdjMatrix);\n }\n\n return currentAdjMatrix;\n };\n /**\n * 获取最短路径矩阵\n *\n * @param {boolean} cache 是否使用缓存的\n * @param {boolean} directed 是否是有向图,默认取 graph.directed\n * @returns {Matrix} 最短路径矩阵\n * @memberof IAbstractGraph\n */\n\n\n AbstractGraph.prototype.getShortestPathMatrix = function (cache, directed) {\n if (cache === void 0) {\n cache = true;\n }\n\n if (directed === undefined) directed = this.get('directed');\n var currentAdjMatrix = this.get('adjMatrix');\n var currentShourtestPathMatrix = this.get('shortestPathMatrix');\n\n if (!currentAdjMatrix || !cache) {\n currentAdjMatrix = adjacent_matrix(this.save(), directed);\n this.set('adjMatrix', currentAdjMatrix);\n }\n\n if (!currentShourtestPathMatrix || !cache) {\n currentShourtestPathMatrix = es_floydWarshall(this.save(), directed);\n this.set('shortestPathMatrix', currentShourtestPathMatrix);\n }\n\n return currentShourtestPathMatrix;\n };\n /**\n * 重新定义监听函数,复写参数类型\n */\n\n\n AbstractGraph.prototype.on = function (eventName, callback, once) {\n return _super.prototype.on.call(this, eventName, callback, once);\n };\n /**\n * 销毁画布\n */\n\n\n AbstractGraph.prototype.destroy = function () {\n this.clear(); // 清空栈数据\n\n this.clearStack();\n this.get('itemController').destroy();\n this.get('modeController').destroy();\n this.get('viewController').destroy();\n this.get('stateController').destroy();\n this.get('canvas').destroy();\n this.cfg = null;\n this.destroyed = true;\n this.redoStack = null;\n this.undoStack = null;\n };\n /**\n * 创建凸包或凹包轮廓\n * @param cfg HullCfg 轮廓配置项\n */\n\n\n AbstractGraph.prototype.createHull = function (cfg) {\n if (!cfg.members || cfg.members.length < 1) {\n console.warn('Create hull failed! The members is empty.');\n return;\n }\n\n var parent = this.get('hullGroup');\n var hullMap = this.get('hullMap');\n\n if (!hullMap) {\n hullMap = {};\n this.set('hullMap', hullMap);\n }\n\n if (!parent || parent.get('destroyed')) {\n parent = this.get('group').addGroup({\n id: 'hullGroup'\n });\n parent.toBack();\n this.set('hullGroup', parent);\n }\n\n if (hullMap[cfg.id]) {\n console.warn('Existed hull id.');\n return hullMap[cfg.id];\n }\n\n var group = parent.addGroup({\n id: cfg.id + \"-container\"\n });\n var hull = new item_hull(this, Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, cfg), {\n group: group\n }));\n var hullId = hull.id;\n hullMap[hullId] = hull;\n return hull;\n };\n /**\n * 获取当前 graph 中存在的包裹轮廓\n * @return {[key: string]: Hull} Hull 的 map,hullId 对应的 hull 实例\n */\n\n\n AbstractGraph.prototype.getHulls = function () {\n return this.get('hullMap');\n };\n /**\n * 根据 hullId 获取对应的 hull\n * @return Hull\n */\n\n\n AbstractGraph.prototype.getHullById = function (hullId) {\n return this.get('hullMap')[hullId];\n };\n\n AbstractGraph.prototype.removeHull = function (hull) {\n var _a;\n\n var hullInstance;\n\n if (Object(esm[\"isString\"])(hull)) {\n hullInstance = this.getHullById(hull);\n } else {\n hullInstance = hull;\n }\n\n (_a = this.get('hullMap')) === null || _a === void 0 ? true : delete _a[hullInstance.id];\n hullInstance.destroy();\n };\n\n AbstractGraph.prototype.removeHulls = function () {\n var hulls = this.getHulls();\n if (!hulls || !Object.keys(hulls).length) return;\n Object.keys(hulls).forEach(function (key) {\n var hull = hulls[key];\n hull.destroy();\n });\n this.set('hullMap', {});\n };\n\n return AbstractGraph;\n}(event_emitter_esm[\"a\" /* default */]);\n\n/* harmony default export */ var graph_graph = (graph_AbstractGraph);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/shapeBase.js\nfunction shapeBase_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { shapeBase_typeof = function _typeof(obj) { return typeof obj; }; } else { shapeBase_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return shapeBase_typeof(obj); }\n\n\n\n\n\n\nvar shapeBase_transform = matrix_util_esm[\"ext\"].transform;\nvar CLS_SHAPE_SUFFIX = '-shape';\nvar CLS_LABEL_SUFFIX = '-label';\nvar shapeBase_ARROWS = ['startArrow', 'endArrow'];\nvar SHAPE_DEFAULT_ATTRS = {\n lineWidth: 1,\n stroke: undefined,\n fill: undefined,\n lineAppendWidth: 1,\n opacity: undefined,\n strokeOpacity: undefined,\n fillOpacity: undefined,\n x: 0,\n y: 0,\n r: 10,\n width: 20,\n height: 20,\n shadowColor: undefined,\n shadowBlur: 0,\n shadowOffsetX: 0,\n shadowOffsetY: 0\n};\nvar PATH_SHAPE_DEFAULT_ATTRS = {\n lineWidth: 1,\n stroke: '#000',\n lineDash: undefined,\n startArrow: false,\n endArrow: false,\n opacity: undefined,\n strokeOpacity: undefined,\n fillOpacity: undefined,\n shadowColor: undefined,\n shadowBlur: 0,\n shadowOffsetX: 0,\n shadowOffsetY: 0\n};\nvar SHAPES_DEFAULT_ATTRS = {\n edge: PATH_SHAPE_DEFAULT_ATTRS,\n node: SHAPE_DEFAULT_ATTRS,\n combo: SHAPE_DEFAULT_ATTRS\n};\nvar CLS_LABEL_BG_SUFFIX = '-label-bg'; // 单个 shape 带有一个 label,共用这段代码\n\nvar shapeBase = {\n // 默认样式及配置\n options: {\n labelCfg: {\n style: {\n fontFamily: global.windowFontFamily\n }\n },\n descriptionCfg: {\n style: {\n fontFamily: global.windowFontFamily\n }\n }\n },\n itemType: '',\n\n /**\n * 形状的类型,例如 circle,ellipse,polyline...\n */\n type: '',\n getCustomConfig: function getCustomConfig(cfg) {\n return {};\n },\n getOptions: function getOptions(cfg, updateType) {\n if (updateType === 'move' || (updateType === null || updateType === void 0 ? void 0 : updateType.includes('bbox'))) {\n return {};\n }\n\n return Object(esm[\"deepMix\"])({}, this.options, this.getCustomConfig(cfg) || {}, cfg);\n },\n\n /**\n * 绘制节点/边,包含文本\n * @override\n * @param {Object} cfg 节点的配置项\n * @param {G.Group} group 节点的容器\n * @return {IShape} 绘制的图形\n */\n draw: function draw(cfg, group) {\n group['shapeMap'] = {};\n this.mergeStyle = this.getOptions(cfg);\n var shape = this.drawShape(cfg, group);\n shape.set('className', this.itemType + CLS_SHAPE_SUFFIX);\n group['shapeMap'][this.itemType + CLS_SHAPE_SUFFIX] = shape;\n\n if (cfg.label) {\n var label = this.drawLabel(cfg, group);\n label.set('className', this.itemType + CLS_LABEL_SUFFIX);\n group['shapeMap'][this.itemType + CLS_LABEL_SUFFIX] = label;\n }\n\n return shape;\n },\n\n /**\n * 绘制完成后的操作,便于用户继承现有的节点、边\n * @param cfg\n * @param group\n * @param keyShape\n */\n afterDraw: function afterDraw(cfg, group, keyShape) {},\n drawShape: function drawShape(cfg, group) {\n return null;\n },\n drawLabel: function drawLabel(cfg, group) {\n var defaultLabelCfg = (this.mergeStyle || this.getOptions(cfg) || {}).labelCfg; // image的情况下有可能为null\n\n var labelCfg = defaultLabelCfg || {};\n var labelStyle = this.getLabelStyle(cfg, labelCfg, group);\n var rotate = labelStyle.rotate;\n delete labelStyle.rotate;\n var label = group.addShape('text', {\n attrs: labelStyle,\n draggable: true,\n className: 'text-shape',\n name: 'text-shape'\n });\n group['shapeMap']['text-shape'] = label;\n\n if (!isNaN(rotate) && rotate !== '') {\n var labelBBox = label.getBBox();\n var labelMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\n if (labelStyle.rotateCenter) {\n switch (labelStyle.rotateCenter) {\n case 'center':\n labelMatrix = shapeBase_transform(labelMatrix, [['t', -labelBBox.width / 2, -labelBBox.height / 2], ['r', rotate], ['t', labelBBox.width / 2, labelBBox.height / 2]]);\n break;\n\n case 'lefttop':\n labelMatrix = shapeBase_transform(labelMatrix, [['t', -labelStyle.x, -labelStyle.y], ['r', rotate], ['t', labelStyle.x, labelStyle.y]]);\n break;\n\n case 'leftcenter':\n labelMatrix = shapeBase_transform(labelMatrix, [['t', -labelStyle.x, -labelStyle.y - labelBBox.height / 2], ['r', rotate], ['t', labelStyle.x, labelStyle.y + labelBBox.height / 2]]);\n break;\n\n default:\n labelMatrix = shapeBase_transform(labelMatrix, [['t', -labelBBox.width / 2, -labelBBox.height / 2], ['r', rotate], ['t', labelBBox.width / 2, labelBBox.height / 2]]);\n break;\n }\n } else {\n labelMatrix = shapeBase_transform(labelMatrix, [['t', -labelStyle.x, -labelStyle.y - labelBBox.height / 2], ['r', rotate], ['t', labelStyle.x, labelStyle.y + labelBBox.height / 2]]);\n }\n\n label.setMatrix(labelMatrix);\n }\n\n if (labelStyle.background) {\n var rect = this.drawLabelBg(cfg, group, label);\n var labelBgClassname = this.itemType + CLS_LABEL_BG_SUFFIX;\n rect.set('classname', labelBgClassname);\n group['shapeMap'][labelBgClassname] = rect;\n label.toFront();\n }\n\n return label;\n },\n drawLabelBg: function drawLabelBg(cfg, group, label) {\n var defaultLabelCfg = this.options.labelCfg;\n var labelCfg = Object(esm[\"mix\"])({}, defaultLabelCfg, cfg.labelCfg);\n var style = this.getLabelBgStyleByPosition(label, cfg, labelCfg, group);\n var rect = group.addShape('rect', {\n name: 'text-bg-shape',\n attrs: style\n });\n group['shapeMap']['text-bg-shape'] = rect;\n return rect;\n },\n getLabelStyleByPosition: function getLabelStyleByPosition(cfg, labelCfg, group) {\n return {\n text: cfg.label\n };\n },\n getLabelBgStyleByPosition: function getLabelBgStyleByPosition(label, cfg, labelCfg, group) {\n return {};\n },\n\n /**\n * 获取文本的配置项\n * @param cfg 节点的配置项\n * @param labelCfg 文本的配置项\n * @param group 父容器,label 的定位可能与图形相关\n */\n getLabelStyle: function getLabelStyle(cfg, labelCfg, group) {\n var calculateStyle = this.getLabelStyleByPosition(cfg, labelCfg, group);\n var attrName = this.itemType + \"Label\"; // 取 nodeLabel,edgeLabel 的配置项\n\n var defaultStyle = global[attrName] ? global[attrName].style : null;\n return Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, defaultStyle), calculateStyle), labelCfg.style);\n },\n\n /**\n * 获取图形的配置项\n * @param cfg\n */\n getShapeStyle: function getShapeStyle(cfg) {\n return cfg.style;\n },\n\n /**\n * 更新节点,包含文本\n * @override\n * @param {Object} cfg 节点/边的配置项\n * @param {G6.Item} item 节点/边\n */\n update: function update(cfg, item, updateType) {\n this.updateShapeStyle(cfg, item, updateType);\n this.updateLabel(cfg, item, updateType);\n },\n updateShapeStyle: function updateShapeStyle(cfg, item, updateType) {\n var _a;\n\n var group = item.getContainer();\n var shape = item.getKeyShape();\n var shapeStyle = Object(esm[\"mix\"])({}, shape.attr(), cfg.style);\n\n var _loop_1 = function _loop_1(key) {\n var _b;\n\n var style = shapeStyle[key];\n\n if (Object(esm[\"isPlainObject\"])(style)) {\n // 更新图元素样式,支持更新子元素\n var subShape = ((_a = group['shapeMap']) === null || _a === void 0 ? void 0 : _a[key]) || group.find(function (element) {\n return element.get('name') === key;\n });\n subShape === null || subShape === void 0 ? void 0 : subShape.attr(style);\n } else {\n shape.attr((_b = {}, _b[key] = style, _b));\n }\n };\n\n for (var key in shapeStyle) {\n _loop_1(key);\n }\n },\n updateLabel: function updateLabel(cfg, item, updateType) {\n var _a, _b; // 防止 cfg.label = \"\" 的情况\n\n\n if (cfg.label || cfg.label === '') {\n var group = item.getContainer();\n var _c = (this.mergeStyle || this.getOptions({}, updateType) || {}).labelCfg,\n labelCfg = _c === void 0 ? {} : _c;\n var labelClassName_1 = this.itemType + CLS_LABEL_SUFFIX;\n var label = group['shapeMap'][labelClassName_1] || group.find(function (ele) {\n return ele.get('className') === labelClassName_1;\n });\n var labelBgClassname_1 = this.itemType + CLS_LABEL_BG_SUFFIX;\n var labelBg = group['shapeMap'][labelBgClassname_1] || group.find(function (ele) {\n return ele.get('className') === labelBgClassname_1;\n }); // 若传入的新配置中有 label,(用户没传入但原先有 label,label 也会有值)\n\n if (!label) {\n // 若原先不存在 label,则绘制一个新的 label\n var newLabel = this.drawLabel(cfg, group);\n newLabel.set('className', labelClassName_1);\n group['shapeMap'][labelClassName_1] = newLabel;\n } else {\n // 若原先存在 label,则更新样式。与 getLabelStyle 不同在于这里需要融合当前 label 的样式\n // 融合 style 以外的属性:position, offset, ...\n if (!updateType || updateType === 'bbox|label' || this.itemType === 'edge' && updateType !== 'style') {\n labelCfg = Object(esm[\"deepMix\"])(labelCfg, cfg.labelCfg);\n } // 获取位置信息\n\n\n var calculateStyle = this.getLabelStyleByPosition(cfg, labelCfg, group); // 取 nodeLabel,edgeLabel 的配置项\n\n var cfgStyle = (_a = cfg.labelCfg) === null || _a === void 0 ? void 0 : _a.style; // const cfgBgStyle = labelCfg.style?.background;\n // 需要融合当前\b label 的样式 label.attr()。不再需要全局/默认样式,因为已经应用在当前的 label 上\n\n var labelStyle = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, calculateStyle), cfgStyle);\n\n var rotate = labelStyle.rotate;\n delete labelStyle.rotate; // 计算 label 的旋转矩阵\n\n if (!isNaN(rotate) && rotate !== '') {\n // if G 4.x define the rotateAtStart, use it directly instead of using the following codes\n var rotateMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n rotateMatrix = shapeBase_transform(rotateMatrix, [['t', -labelStyle.x, -labelStyle.y], ['r', rotate], ['t', labelStyle.x, labelStyle.y]]);\n labelStyle.matrix = rotateMatrix;\n label.attr(labelStyle);\n } else {\n if (((_b = label.getMatrix()) === null || _b === void 0 ? void 0 : _b[4]) !== 1) {\n label.resetMatrix();\n }\n\n label.attr(labelStyle);\n }\n\n if (!labelBg) {\n if (labelStyle.background) {\n labelBg = this.drawLabelBg(cfg, group, label);\n labelBg.set('classname', labelBgClassname_1);\n group['shapeMap'][labelBgClassname_1] = labelBg;\n label.toFront();\n }\n } else if (labelStyle.background) {\n var calculateBgStyle = this.getLabelBgStyleByPosition(label, cfg, labelCfg, group);\n var labelBgStyle = calculateBgStyle;\n\n if (!isNaN(rotate) && rotate !== '') {\n var bgRotateMatrix = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n bgRotateMatrix = shapeBase_transform(bgRotateMatrix, [['t', -labelBgStyle.x, -labelBgStyle.y], ['r', rotate], ['t', labelBgStyle.x, labelBgStyle.y]]);\n labelBgStyle.matrix = bgRotateMatrix;\n } else {\n labelBg.resetMatrix();\n }\n\n labelBg.attr(labelBgStyle);\n } else {\n group.removeChild(labelBg);\n }\n }\n }\n },\n // update(cfg, item) // 默认不定义\n afterUpdate: function afterUpdate(cfg, item) {},\n\n /**\n * 设置节点的状态,主要是交互状态,业务状态请在 draw 方法中实现\n * 单图形的节点仅考虑 selected、active 状态,有其他状态需求的用户自己复写这个方法\n * @override\n * @param {String} name 状态名称\n * @param {String | Boolean} value 状态值\n * @param {G6.Item} item 节点\n */\n setState: function setState(name, value, item) {\n var _a, _b;\n\n var _c;\n\n var shape = item.get('keyShape');\n if (!shape || shape.destroyed) return;\n var type = item.getType();\n var stateName = Object(esm[\"isBoolean\"])(value) ? name : name + \":\" + value;\n var shapeStateStyle = this.getStateStyle(stateName, item);\n var itemStateStyle = item.getStateStyle(stateName); // const originStyle = item.getOriginStyle();\n // 不允许设置一个不存在的状态\n\n if (!itemStateStyle && !shapeStateStyle) {\n return;\n } // 要设置或取消的状态的样式\n // 当没有 state 状态时,默认使用 model.stateStyles 中的样式\n\n\n var styles = Object(esm[\"mix\"])({}, itemStateStyle || shapeStateStyle);\n var group = item.getContainer(); // 从图元素现有的样式中删除本次要取消的 states 中存在的属性值。使用对象检索更快\n\n var keptAttrs = {\n x: 1,\n y: 1,\n cx: 1,\n cy: 1\n };\n\n if (type === 'combo') {\n keptAttrs.r = 1;\n keptAttrs.width = 1;\n keptAttrs.height = 1;\n }\n\n if (value) {\n var _loop_2 = function _loop_2(key) {\n var _d;\n\n var style = styles[key];\n\n if (Object(esm[\"isPlainObject\"])(style) && !shapeBase_ARROWS.includes(key)) {\n var subShape = ((_c = group['shapeMap']) === null || _c === void 0 ? void 0 : _c[key]) || group.find(function (element) {\n return element.get('name') === key;\n });\n subShape === null || subShape === void 0 ? void 0 : subShape.attr(style);\n } else {\n // 非纯对象,则认为是设置到 keyShape 上面的\n shape.attr((_d = {}, _d[key] = style, _d));\n }\n }; // style 为要设置的状态的样式\n\n\n for (var key in styles) {\n _loop_2(key);\n }\n } else {\n // 所有生效的 state 的样式\n var enableStatesStyle = graphic_cloneBesidesImg(item.getCurrentStatesStyle());\n var model = item.getModel(); // 原始样式\n\n var originStyle_1 = Object(esm[\"mix\"])({}, model.style, graphic_cloneBesidesImg(item.getOriginStyle()));\n var keyShapeName_1 = shape.get('name'); // cloning shape.attr(), keys.forEach to avoid cloning the img attr, which leads to maximum clone heap #2383\n // const keyShapeStyles = clone(shape.attr())\n\n var shapeAttrs_1 = shape.attr();\n var keyShapeStyles_1 = {};\n Object.keys(shapeAttrs_1).forEach(function (key) {\n if (key === 'img') return;\n var attr = shapeAttrs_1[key];\n\n if (attr && shapeBase_typeof(attr) === 'object') {\n keyShapeStyles_1[key] = Object(esm[\"clone\"])(attr);\n } else {\n keyShapeStyles_1[key] = attr;\n }\n }); // 已有样式 - 要取消的状态的样式\n\n var filtetDisableStatesStyle = {};\n\n var _loop_3 = function _loop_3(p) {\n var style = styles[p];\n\n if (Object(esm[\"isPlainObject\"])(style) && !shapeBase_ARROWS.includes(p)) {\n var subShape_1 = group['shapeMap'][p] || group.find(function (ele) {\n return ele.get('name') === p;\n });\n\n if (subShape_1) {\n var subShapeStyles_1 = graphic_cloneBesidesImg(subShape_1.attr());\n Object(esm[\"each\"])(style, function (v, key) {\n if (p === keyShapeName_1 && keyShapeStyles_1[key] && !keptAttrs[key]) {\n delete keyShapeStyles_1[key];\n var value_1 = originStyle_1[p][key] || SHAPES_DEFAULT_ATTRS[type][key];\n shape.attr(key, value_1);\n } else if (subShapeStyles_1[key] || subShapeStyles_1[key] === 0) {\n delete subShapeStyles_1[key];\n var value_2 = originStyle_1[p][key] || SHAPES_DEFAULT_ATTRS[type][key];\n subShape_1.attr(key, value_2);\n }\n });\n filtetDisableStatesStyle[p] = subShapeStyles_1;\n }\n } else {\n if (keyShapeStyles_1[p] && !keptAttrs[p]) {\n delete keyShapeStyles_1[p];\n var value_3 = originStyle_1[p] || (originStyle_1[keyShapeName_1] ? originStyle_1[keyShapeName_1][p] : undefined) || SHAPES_DEFAULT_ATTRS[type][p];\n shape.attr(p, value_3);\n }\n }\n }; // styles 为要取消的状态的样式\n\n\n for (var p in styles) {\n _loop_3(p);\n } // 从图元素现有的样式中删除本次要取消的 states 中存在的属性值后,\n // 如果 keyShape 有 name 属性,则 filtetDisableStatesStyle 的格式为 { keyShapeName: {} }\n // 否则为普通对象\n\n\n if (!keyShapeName_1) {\n Object(esm[\"mix\"])(filtetDisableStatesStyle, keyShapeStyles_1);\n } else {\n filtetDisableStatesStyle[keyShapeName_1] = keyShapeStyles_1;\n }\n\n for (var key in enableStatesStyle) {\n if (keptAttrs[key]) continue;\n var enableStyle = enableStatesStyle[key];\n\n if (!Object(esm[\"isPlainObject\"])(enableStyle) || shapeBase_ARROWS.includes(key)) {\n // 把样式属性merge到keyShape中\n if (!keyShapeName_1) {\n Object(esm[\"mix\"])(originStyle_1, (_a = {}, _a[key] = enableStyle, _a));\n } else {\n Object(esm[\"mix\"])(originStyle_1[keyShapeName_1], (_b = {}, _b[key] = enableStyle, _b));\n delete originStyle_1[key];\n }\n\n delete enableStatesStyle[key];\n }\n }\n\n var originstyles = {};\n Object(esm[\"deepMix\"])(originstyles, originStyle_1, filtetDisableStatesStyle, enableStatesStyle);\n var keyShapeSetted = false;\n\n var _loop_4 = function _loop_4(originKey) {\n var _e, _f;\n\n var style = originstyles[originKey];\n\n if (Object(esm[\"isPlainObject\"])(style) && !shapeBase_ARROWS.includes(originKey)) {\n var subShape = group['shapeMap'][originKey] || group.find(function (ele) {\n return ele.get('name') === originKey;\n });\n\n if (subShape) {\n // The text's position and matrix is not allowed to be affected by states\n if (subShape.get('type') === 'text') {\n delete style.x;\n delete style.y;\n delete style.matrix;\n }\n\n if (originKey === keyShapeName_1) {\n if (type === 'combo') {\n delete style.r;\n delete style.width;\n delete style.height;\n }\n\n keyShapeSetted = true;\n }\n\n subShape.attr(style);\n }\n } else if (!keyShapeSetted) {\n var value_4 = style || SHAPES_DEFAULT_ATTRS[type][originKey]; // 当更新 combo 状态时,当不存在 keyShapeName 时候,则认为是设置到 keyShape 上面的\n\n if (type === 'combo') {\n if (!keyShapeName_1) {\n shape.attr((_e = {}, _e[originKey] = value_4, _e));\n }\n } else {\n shape.attr((_f = {}, _f[originKey] = value_4, _f));\n }\n }\n };\n\n for (var originKey in originstyles) {\n _loop_4(originKey);\n }\n }\n },\n\n /**\n * 获取不同状态下的样式\n *\n * @param {string} name 状态名称\n * @param {Item} item Node或Edge的实例\n * @return {object} 样式\n */\n getStateStyle: function getStateStyle(name, item) {\n var model = item.getModel();\n var type = item.getType();\n\n var _a = this.getOptions(model),\n stateStyles = _a.stateStyles,\n _b = _a.style,\n style = _b === void 0 ? {} : _b;\n\n var modelStateStyle = model.stateStyles ? model.stateStyles[name] : stateStyles && stateStyles[name];\n\n if (type === 'combo') {\n return Object(esm[\"clone\"])(modelStateStyle);\n }\n\n return Object(esm[\"mix\"])({}, style, modelStateStyle);\n },\n\n /**\n * 获取控制点\n * @param {Object} cfg 节点、边的配置项\n * @return {Array|null} 控制点的数组,如果为 null,则没有控制点\n */\n getControlPoints: function getControlPoints(cfg) {\n return cfg.controlPoints;\n },\n\n /**\n * 获取控制点\n * @param {Object} cfg 节点、边的配置项\n * @return {Array|null} 锚点的数组,如果为 null,则没有锚点\n */\n getAnchorPoints: function getAnchorPoints(cfg) {\n var _a, _b;\n\n var anchorPoints = (cfg === null || cfg === void 0 ? void 0 : cfg.anchorPoints) || ((_a = this.getCustomConfig(cfg)) === null || _a === void 0 ? void 0 : _a.anchorPoints) || ((_b = this.options) === null || _b === void 0 ? void 0 : _b.anchorPoints);\n return anchorPoints;\n }\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/node.js\n\n\n\n\n\n\nvar singleNode = {\n itemType: 'node',\n // 单个图形的类型\n shapeType: 'single-node',\n\n /**\n * 文本相对图形的位置,默认以中心点\n * 位置包括: top, bottom, left, right, center\n * @type {String}\n */\n labelPosition: 'center',\n\n /**\n * 文本相对偏移,当 labelPosition 不为 center 时有效\n * @type {Number}\n */\n offset: global.nodeLabel.offset,\n\n /**\n * 获取节点宽高\n * @internal 返回节点的大小,以 [width, height] 的方式维护\n * @param {Object} cfg 节点的配置项\n * @return {Array} 宽高\n */\n getSize: function getSize(cfg) {\n var _a;\n\n var size = ((_a = this.mergeStyle) === null || _a === void 0 ? void 0 : _a.size) || cfg.size || this.getOptions({}).size || global.defaultNode.size; // Global.defaultNode.size; // \n // size 是数组,但长度为1,则补长度为2\n\n if (Object(esm[\"isArray\"])(size) && size.length === 1) {\n size = [size[0], size[0]];\n } // size 为数字,则转换为数组\n\n\n if (!Object(esm[\"isArray\"])(size)) {\n size = [size, size];\n }\n\n return size;\n },\n // 私有方法,不希望扩展的节点复写这个方法\n getLabelStyleByPosition: function getLabelStyleByPosition(cfg, labelCfg) {\n var labelPosition = labelCfg.position || this.labelPosition; // 默认的位置(最可能的情形),所以放在最上面\n\n if (labelPosition === 'center') {\n return {\n x: 0,\n y: 0,\n text: cfg.label\n };\n }\n\n var offset = labelCfg.offset;\n\n if (Object(esm[\"isNil\"])(offset)) {\n // 考虑 offset = 0 的场景,不用用 labelCfg.offset || Global.nodeLabel.offset\n offset = this.offset; // 不居中时的偏移量\n }\n\n var size = this.getSize(cfg);\n var style;\n\n switch (labelPosition) {\n case 'top':\n style = {\n x: 0,\n y: -size[1] / 2 - offset,\n textBaseline: 'bottom' // 文本在图形的上面\n\n };\n break;\n\n case 'bottom':\n style = {\n x: 0,\n y: size[1] / 2 + offset,\n textBaseline: 'top'\n };\n break;\n\n case 'left':\n style = {\n x: -size[0] / 2 - offset,\n y: 0,\n textAlign: 'right'\n };\n break;\n\n default:\n style = {\n x: size[0] / 2 + offset,\n y: 0,\n textAlign: 'left'\n };\n break;\n }\n\n style.text = cfg.label;\n return style;\n },\n getLabelBgStyleByPosition: function getLabelBgStyleByPosition(label, cfg, labelCfg, group) {\n var _a;\n\n if (!label) return {};\n var backgroundStyle = (_a = labelCfg.style) === null || _a === void 0 ? void 0 : _a.background;\n if (!backgroundStyle) return {};\n var bbox = label.getBBox();\n var padding = base_formatPadding(backgroundStyle.padding);\n var backgroundWidth = bbox.width + padding[1] + padding[3];\n var backgroundHeight = bbox.height + padding[0] + padding[2];\n return Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({\n x: bbox.minX - padding[3],\n y: bbox.minY - padding[0]\n }, backgroundStyle), {\n width: backgroundWidth,\n height: backgroundHeight\n });\n },\n drawShape: function drawShape(cfg, group) {\n var shapeType = this.shapeType; // || this.type,都已经加了 shapeType\n\n var style = this.getShapeStyle(cfg);\n var shape = group.addShape(shapeType, {\n attrs: style,\n draggable: true,\n name: 'node-shape'\n });\n group['shapeMap']['node-shape'] = shape;\n return shape;\n },\n\n /**\n * 更新linkPoints\n * @param {Object} cfg 节点数据配置项\n * @param {Group} group Item所在的group\n */\n updateLinkPoints: function updateLinkPoints(cfg, group) {\n var defaultLinkPoints = (this.mergeStyle || this.getOptions(cfg)).linkPoints;\n var markLeft = group['shapeMap']['link-point-left'] || group.find(function (element) {\n return element.get('className') === 'link-point-left';\n });\n var markRight = group['shapeMap']['link-point-right'] || group.find(function (element) {\n return element.get('className') === 'link-point-right';\n });\n var markTop = group['shapeMap']['link-point-top'] || group.find(function (element) {\n return element.get('className') === 'link-point-top';\n });\n var markBottom = group['shapeMap']['link-point-bottom'] || group.find(function (element) {\n return element.get('className') === 'link-point-bottom';\n });\n var currentLinkPoints;\n\n if (markLeft) {\n currentLinkPoints = markLeft.attr();\n }\n\n if (markRight && !currentLinkPoints) {\n currentLinkPoints = markRight.attr();\n }\n\n if (markTop && !currentLinkPoints) {\n currentLinkPoints = markTop.attr();\n }\n\n if (markBottom && !currentLinkPoints) {\n currentLinkPoints = markBottom.attr();\n }\n\n if (!currentLinkPoints) currentLinkPoints = defaultLinkPoints;\n var linkPoints = Object(esm[\"mix\"])({}, currentLinkPoints, cfg.linkPoints);\n var markFill = linkPoints.fill,\n markStroke = linkPoints.stroke,\n borderWidth = linkPoints.lineWidth;\n var markSize = linkPoints.size / 2;\n if (!markSize) markSize = linkPoints.r;\n\n var _a = cfg.linkPoints ? cfg.linkPoints : {\n left: undefined,\n right: undefined,\n top: undefined,\n bottom: undefined\n },\n left = _a.left,\n right = _a.right,\n top = _a.top,\n bottom = _a.bottom;\n\n var size = this.getSize(cfg);\n var width = size[0];\n var height = size[1];\n var styles = {\n r: markSize,\n fill: markFill,\n stroke: markStroke,\n lineWidth: borderWidth\n };\n\n if (markLeft) {\n if (!left && left !== undefined) {\n markLeft.remove();\n delete group['shapeMap']['link-point-left'];\n } else {\n markLeft.attr(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: -width / 2,\n y: 0\n }));\n }\n } else if (left) {\n var name_1 = 'link-point-left';\n group['shapeMap'][name_1] = group.addShape('circle', {\n attrs: Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: -width / 2,\n y: 0\n }),\n className: name_1,\n name: name_1,\n isAnchorPoint: true\n });\n }\n\n if (markRight) {\n if (!right && right !== undefined) {\n markRight.remove();\n delete group['shapeMap']['link-point-right'];\n }\n\n markRight.attr(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: width / 2,\n y: 0\n }));\n } else if (right) {\n var name_2 = 'link-point-right';\n group['shapeMap'][name_2] = group.addShape('circle', {\n attrs: Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: width / 2,\n y: 0\n }),\n className: name_2,\n name: name_2,\n isAnchorPoint: true\n });\n }\n\n if (markTop) {\n if (!top && top !== undefined) {\n markTop.remove();\n delete group['shapeMap']['link-point-top'];\n }\n\n markTop.attr(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: 0,\n y: -height / 2\n }));\n } else if (top) {\n var name_3 = 'link-point-top';\n group['shapeMap'][name_3] = group.addShape('circle', {\n attrs: Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: 0,\n y: -height / 2\n }),\n className: name_3,\n name: name_3,\n isAnchorPoint: true\n });\n }\n\n if (markBottom) {\n if (!bottom && bottom !== undefined) {\n markBottom.remove();\n delete group['shapeMap']['link-point-bottom'];\n } else {\n markBottom.attr(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: 0,\n y: height / 2\n }));\n }\n } else if (bottom) {\n var name_4 = 'link-point-bottom';\n group['shapeMap'][name_4] = group.addShape('circle', {\n attrs: Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, styles), {\n x: 0,\n y: height / 2\n }),\n className: name_4,\n name: name_4,\n isAnchorPoint: true\n });\n }\n },\n updateShape: function updateShape(cfg, item, keyShapeStyle, hasIcon, updateType) {\n var keyShape = item.get('keyShape');\n keyShape.attr(Object(tslib_es6[\"__assign\"])({}, keyShapeStyle));\n\n if (!undefined || (updateType === null || updateType === void 0 ? void 0 : updateType.includes('label'))) {\n this.updateLabel(cfg, item, updateType);\n }\n\n if (hasIcon) {\n this.updateIcon(cfg, item);\n }\n },\n updateIcon: function updateIcon(cfg, item) {\n var _this = this;\n\n var group = item.getContainer();\n var icon = (this.mergeStyle || this.getOptions(cfg)).icon;\n var show = (cfg.icon ? cfg.icon : {\n show: undefined\n }).show;\n var iconShape = group['shapeMap'][this.type + \"-icon\"] || group.find(function (ele) {\n return ele.get('name') === _this.type + \"-icon\";\n });\n\n if (iconShape) {\n // 若原先存在 icon\n if (show || show === undefined) {\n // 若传入 show: true, 或没有设置,则更新原有的 icon 样式\n var iconConfig = Object(esm[\"mix\"])({}, iconShape.attr(), icon);\n var _a = iconConfig.width,\n w = _a === void 0 ? 20 : _a,\n _b = iconConfig.height,\n h = _b === void 0 ? 20 : _b;\n iconShape.attr(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, iconConfig), {\n x: -w / 2,\n y: -h / 2\n }));\n } else {\n // 若传入了 show: false 则删除原先的 icon\n iconShape.remove();\n }\n } else if (show) {\n // 如果原先不存在 icon,但传入了 show: true,则新增 icon\n var w = icon.width,\n h = icon.height;\n var name_5 = this.type + \"-icon\";\n group['shapeMap'][name_5] = group.addShape('image', {\n attrs: Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, icon), {\n x: -w / 2,\n y: -h / 2\n }),\n className: name_5,\n name: name_5\n }); // to ensure the label is on the top of all the shapes\n\n var labelShape = group['shapeMap']['node-label'] || group.find(function (ele) {\n return ele.get('name') === 'node-label';\n });\n\n if (labelShape) {\n labelShape.toFront();\n }\n }\n }\n};\n\nvar singleNodeDef = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, shapeBase), singleNode);\n\nelement_shape.registerNode('single-node', singleNodeDef);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/edge.js\n/**\n * @fileOverview 自定义边\n * @description 自定义边中有大量逻辑同自定义节点重复,虽然可以提取成为 mixin ,但是考虑到代码的可读性,还是单独实现。\n */\n\n\n\n\n\n\n\n\nvar CLS_SHAPE = 'edge-shape'; // start,end 倒置,center 不变\n\nfunction revertAlign(labelPosition) {\n var textAlign = labelPosition;\n\n if (labelPosition === 'start') {\n textAlign = 'end';\n } else if (labelPosition === 'end') {\n textAlign = 'start';\n }\n\n return textAlign;\n}\n\nvar singleEdge = {\n itemType: 'edge',\n\n /**\n * 文本的位置\n * @type {String}\n */\n labelPosition: 'center',\n\n /**\n * 文本的 x 偏移\n * @type {Number}\n */\n refX: 0,\n\n /**\n * 文本的 y 偏移\n * @type {Number}\n */\n refY: 0,\n\n /**\n * 文本是否跟着线自动旋转,默认 false\n * @type {Boolean}\n */\n labelAutoRotate: false,\n // 自定义边时的配置\n options: {\n size: global.defaultEdge.size,\n style: {\n x: 0,\n y: 0,\n stroke: global.defaultEdge.style.stroke,\n lineAppendWidth: global.defaultEdge.style.lineAppendWidth\n },\n labelCfg: {\n style: {\n fill: global.edgeLabel.style.fill,\n fontSize: global.edgeLabel.style.fontSize,\n fontFamily: global.windowFontFamily\n }\n },\n stateStyles: Object(tslib_es6[\"__assign\"])({}, global.edgeStateStyles)\n },\n\n /**\n * 获取边的 path\n * @internal 供扩展的边覆盖\n * @param {Array} points 构成边的点的集合\n * @return {Array} 构成 path 的数组\n */\n getPath: function getPath(points) {\n var path = [];\n Object(esm[\"each\"])(points, function (point, index) {\n if (index === 0) {\n path.push(['M', point.x, point.y]);\n } else {\n path.push(['L', point.x, point.y]);\n }\n });\n return path;\n },\n getShapeStyle: function getShapeStyle(cfg) {\n var defaultStyle = this.options.style;\n var strokeStyle = {\n stroke: cfg.color\n }; // 如果设置了color,则覆盖默认的stroke属性\n\n var style = Object(esm[\"mix\"])({}, defaultStyle, strokeStyle, cfg.style);\n var size = cfg.size || global.defaultEdge.size;\n cfg = this.getPathPoints(cfg);\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n var controlPoints = this.getControlPoints(cfg);\n var points = [startPoint]; // 添加起始点\n // 添加控制点\n\n if (controlPoints) {\n points = points.concat(controlPoints);\n } // 添加结束点\n\n\n points.push(endPoint);\n var path = this.getPath(points);\n var styles = Object(esm[\"mix\"])({}, global.defaultEdge.style, {\n stroke: global.defaultEdge.color,\n lineWidth: size,\n path: path\n }, style);\n return styles;\n },\n updateShapeStyle: function updateShapeStyle(cfg, item, updateType) {\n var _a;\n\n var group = item.getContainer(); // const strokeStyle: ShapeStyle = {\n // stroke: cfg.color,\n // };\n\n var shape = ((_a = item.getKeyShape) === null || _a === void 0 ? void 0 : _a.call(item)) || group['shapeMap']['edge-shape']; // group.find((element) => element.get('className') === 'edge-shape');\n\n var size = cfg.size;\n cfg = this.getPathPoints(cfg);\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n var controlPoints = this.getControlPoints(cfg); // || cfg.controlPoints;\n\n var points = [startPoint]; // 添加起始点\n // 添加控制点\n\n if (controlPoints) {\n points = points.concat(controlPoints);\n } // 添加结束点\n\n\n points.push(endPoint);\n var currentAttr = shape.attr(); // const previousStyle = mix({}, strokeStyle, currentAttr, cfg.style);\n\n var previousStyle = cfg.style || {};\n\n if (previousStyle.stroke === undefined) {\n previousStyle.stroke = cfg.color;\n }\n\n var source = cfg.sourceNode;\n var target = cfg.targetNode;\n var routeCfg = {\n radius: previousStyle.radius\n };\n\n if (!controlPoints) {\n routeCfg = {\n source: source,\n target: target,\n offset: previousStyle.offset,\n radius: previousStyle.radius\n };\n }\n\n var path = this.getPath(points, routeCfg);\n var style = {};\n\n if (updateType === 'move') {\n style = {\n path: path\n };\n } else {\n if (currentAttr.endArrow && previousStyle.endArrow === false) {\n cfg.style.endArrow = {\n path: ''\n };\n }\n\n if (currentAttr.startArrow && previousStyle.startArrow === false) {\n cfg.style.startArrow = {\n path: ''\n };\n }\n\n style = Object(tslib_es6[\"__assign\"])({}, cfg.style);\n if (style.lineWidth === undefined) style.lineWdith = (Object(esm[\"isNumber\"])(size) ? size : size === null || size === void 0 ? void 0 : size[0]) || currentAttr.lineWidth;\n if (style.path === undefined) style.path = path;\n if (style.stroke === undefined) style.stroke = currentAttr.stroke || cfg.color;\n }\n\n if (shape) {\n shape.attr(style);\n }\n },\n getLabelStyleByPosition: function getLabelStyleByPosition(cfg, labelCfg, group) {\n var labelPosition = labelCfg.position || this.labelPosition; // 文本的位置用户可以传入\n\n var style = {};\n var pathShape = group === null || group === void 0 ? void 0 : group['shapeMap'][CLS_SHAPE]; // group?.find((element) => element.get('className') === CLS_SHAPE);\n // 不对 pathShape 进行判空,如果线不存在,说明有问题了\n\n var pointPercent;\n\n if (labelPosition === 'start') {\n pointPercent = 0;\n } else if (labelPosition === 'end') {\n pointPercent = 1;\n } else {\n pointPercent = 0.5;\n } // 偏移量\n\n\n var offsetX = labelCfg.refX || this.refX;\n var offsetY = labelCfg.refY || this.refY; // 如果两个节点重叠,线就变成了一个点,这时候label的位置,就是这个点 + 绝对偏移\n\n if (cfg.startPoint.x === cfg.endPoint.x && cfg.startPoint.y === cfg.endPoint.y) {\n style.x = cfg.startPoint.x + offsetX;\n style.y = cfg.startPoint.y + offsetY;\n style.text = cfg.label;\n return style;\n }\n\n var autoRotate;\n if (Object(esm[\"isNil\"])(labelCfg.autoRotate)) autoRotate = this.labelAutoRotate;else autoRotate = labelCfg.autoRotate;\n var offsetStyle = graphic_getLabelPosition(pathShape, pointPercent, offsetX, offsetY, autoRotate);\n style.x = offsetStyle.x;\n style.y = offsetStyle.y;\n style.rotate = offsetStyle.rotate;\n style.textAlign = this._getTextAlign(labelPosition, offsetStyle.angle);\n style.text = cfg.label;\n return style;\n },\n getLabelBgStyleByPosition: function getLabelBgStyleByPosition(label, cfg, labelCfg, group) {\n if (!label) {\n return {};\n }\n\n var bbox = label.getBBox();\n var backgroundStyle = labelCfg.style && labelCfg.style.background;\n\n if (!backgroundStyle) {\n return {};\n }\n\n var padding = backgroundStyle.padding;\n var backgroundWidth = bbox.width + padding[1] + padding[3];\n var backgroundHeight = bbox.height + padding[0] + padding[2];\n var labelPosition = labelCfg.position || this.labelPosition;\n\n var style = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, backgroundStyle), {\n width: backgroundWidth,\n height: backgroundHeight,\n x: bbox.minX - padding[2],\n y: bbox.minY - padding[0],\n rotate: 0\n });\n\n var autoRotate;\n if (Object(esm[\"isNil\"])(labelCfg.autoRotate)) autoRotate = this.labelAutoRotate;else autoRotate = labelCfg.autoRotate;\n var pathShape = group === null || group === void 0 ? void 0 : group['shapeMap'][CLS_SHAPE]; // group?.find((element) => element.get('className') === CLS_SHAPE);\n // 不对 pathShape 进行判空,如果线不存在,说明有问题了\n\n var pointPercent;\n\n if (labelPosition === 'start') {\n pointPercent = 0;\n } else if (labelPosition === 'end') {\n pointPercent = 1;\n } else {\n pointPercent = 0.5;\n } // 偏移量\n\n\n var offsetX = labelCfg.refX || this.refX;\n var offsetY = labelCfg.refY || this.refY; // // 如果两个节点重叠,线就变成了一个点,这时候label的位置,就是这个点 + 绝对偏移\n\n if (cfg.startPoint.x === cfg.endPoint.x && cfg.startPoint.y === cfg.endPoint.y) {\n style.x = cfg.startPoint.x + offsetX - backgroundWidth / 2;\n style.y = cfg.startPoint.y + offsetY - backgroundHeight / 2;\n return style;\n }\n\n var bgOffsetX = offsetX - backgroundWidth / 2;\n\n if (labelCfg.position === 'start') {\n bgOffsetX = offsetX - padding[2];\n } else if (labelCfg.position === 'end') {\n bgOffsetX = offsetX - backgroundWidth;\n }\n\n var offsetStyle = graphic_getLabelPosition(pathShape, pointPercent, bgOffsetX, offsetY + backgroundHeight / 2, autoRotate);\n\n if (autoRotate) {\n style.x = offsetStyle.x;\n style.y = offsetStyle.y;\n }\n\n style.rotate = offsetStyle.rotate;\n return style;\n },\n // 获取文本对齐方式\n _getTextAlign: function _getTextAlign(labelPosition, angle) {\n var textAlign = 'center';\n\n if (!angle) {\n return labelPosition;\n }\n\n angle = angle % (Math.PI * 2); // 取模\n\n if (labelPosition !== 'center') {\n if (angle >= 0 && angle <= Math.PI / 2 || angle >= 3 / 2 * Math.PI && angle < 2 * Math.PI) {\n textAlign = labelPosition;\n } else {\n textAlign = revertAlign(labelPosition);\n }\n }\n\n return textAlign;\n },\n\n /**\n * @internal 获取边的控制点\n * @param {Object} cfg 边的配置项\n * @return {Array} 控制点的数组\n */\n getControlPoints: function getControlPoints(cfg) {\n return cfg.controlPoints;\n },\n\n /**\n * @internal 处理需要重计算点和边的情况\n * @param {Object} cfg 边的配置项\n * @return {Object} 边的配置项\n */\n getPathPoints: function getPathPoints(cfg) {\n return cfg;\n },\n\n /**\n * 绘制边\n * @override\n * @param {Object} cfg 边的配置项\n * @param {G.Group} group 边的容器\n * @return {IShape} 图形\n */\n drawShape: function drawShape(cfg, group) {\n var shapeStyle = this.getShapeStyle(cfg);\n var shape = group.addShape('path', {\n className: CLS_SHAPE,\n name: CLS_SHAPE,\n attrs: shapeStyle\n });\n group['shapeMap'][CLS_SHAPE] = shape;\n return shape;\n },\n drawLabel: function drawLabel(cfg, group) {\n var defaultLabelCfg = this.options.labelCfg;\n var labelCfg = Object(esm[\"deepMix\"])({}, defaultLabelCfg, cfg.labelCfg);\n var labelStyle = this.getLabelStyle(cfg, labelCfg, group);\n var rotate = labelStyle.rotate;\n delete labelStyle.rotate;\n var label = group.addShape('text', {\n attrs: labelStyle,\n name: 'text-shape'\n });\n group['shapeMap']['text-shape'] = label;\n\n if (!isNaN(rotate) && rotate !== '') {\n label.rotateAtStart(rotate);\n }\n\n if (labelStyle.background) {\n var rect = this.drawLabelBg(cfg, group, label, labelStyle, rotate);\n var labelBgClassname = this.itemType + CLS_LABEL_BG_SUFFIX;\n rect.set('classname', labelBgClassname);\n group['shapeMap'][labelBgClassname] = rect;\n label.toFront();\n }\n\n return label;\n },\n drawLabelBg: function drawLabelBg(cfg, group, label, labelStyle, rotate) {\n var defaultLabelCfg = this.options.labelCfg;\n var labelCfg = Object(esm[\"deepMix\"])({}, defaultLabelCfg, cfg.labelCfg);\n var style = this.getLabelBgStyleByPosition(label, cfg, labelCfg, group);\n delete style.rotate;\n var rect = group.addShape('rect', {\n name: 'text-bg-shape',\n attrs: style\n });\n group['shapeMap']['text-bg-shape'] = rect;\n if (!isNaN(rotate)) rect.rotateAtStart(rotate);\n return rect;\n }\n};\n\nvar singleEdgeDef = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, shapeBase), singleEdge);\n\nelement_shape.registerEdge('single-edge', singleEdgeDef); // 直线, 不支持控制点\n\nelement_shape.registerEdge('line', {\n // 控制点不生效\n getControlPoints: function getControlPoints() {\n return undefined;\n }\n}, 'single-edge'); // 直线\n\nelement_shape.registerEdge('spline', {\n getPath: function getPath(points) {\n var path = path_getSpline(points);\n return path;\n }\n}, 'single-edge');\nelement_shape.registerEdge('arc', {\n curveOffset: 20,\n clockwise: 1,\n getControlPoints: function getControlPoints(cfg) {\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n var midPoint = {\n x: (startPoint.x + endPoint.x) / 2,\n y: (startPoint.y + endPoint.y) / 2\n };\n var center;\n var arcPoint; // 根据给定点计算圆弧\n\n if (cfg.controlPoints !== undefined) {\n arcPoint = cfg.controlPoints[0];\n center = getCircleCenterByPoints(startPoint, arcPoint, endPoint); // 根据控制点和直线关系决定 clockwise值\n\n if (startPoint.x <= endPoint.x && startPoint.y > endPoint.y) {\n this.clockwise = center.x > arcPoint.x ? 0 : 1;\n } else if (startPoint.x <= endPoint.x && startPoint.y < endPoint.y) {\n this.clockwise = center.x > arcPoint.x ? 1 : 0;\n } else if (startPoint.x > endPoint.x && startPoint.y <= endPoint.y) {\n this.clockwise = center.y < arcPoint.y ? 0 : 1;\n } else {\n this.clockwise = center.y < arcPoint.y ? 1 : 0;\n } // 若给定点和两端点共线,无法生成圆弧,绘制直线\n\n\n if ((arcPoint.x - startPoint.x) / (arcPoint.y - startPoint.y) === (endPoint.x - startPoint.x) / (endPoint.y - startPoint.y)) {\n return [];\n }\n } else {\n // 根据直线连线中点的的偏移计算圆弧\n // 若用户给定偏移量则根据其计算,否则按照默认偏移值计算\n if (cfg.curveOffset === undefined) {\n cfg.curveOffset = this.curveOffset;\n }\n\n if (Object(esm[\"isArray\"])(cfg.curveOffset)) {\n cfg.curveOffset = cfg.curveOffset[0];\n }\n\n if (cfg.curveOffset < 0) {\n this.clockwise = 0;\n } else {\n this.clockwise = 1;\n }\n\n var vec = {\n x: endPoint.x - startPoint.x,\n y: endPoint.y - startPoint.y\n };\n var edgeAngle = Math.atan2(vec.y, vec.x);\n arcPoint = {\n x: cfg.curveOffset * Math.cos(-Math.PI / 2 + edgeAngle) + midPoint.x,\n y: cfg.curveOffset * Math.sin(-Math.PI / 2 + edgeAngle) + midPoint.y\n };\n center = getCircleCenterByPoints(startPoint, arcPoint, endPoint);\n }\n\n var radius = math_distance(startPoint, center);\n var controlPoints = [{\n x: radius,\n y: radius\n }];\n return controlPoints;\n },\n getPath: function getPath(points) {\n var path = [];\n path.push(['M', points[0].x, points[0].y]); // 控制点与端点共线\n\n if (points.length === 2) {\n path.push(['L', points[1].x, points[1].y]);\n } else {\n path.push(['A', points[1].x, points[1].y, 0, 0, this.clockwise, points[2].x, points[2].y]);\n }\n\n return path;\n }\n}, 'single-edge');\nelement_shape.registerEdge('quadratic', {\n curvePosition: 0.5,\n curveOffset: -20,\n getControlPoints: function getControlPoints(cfg) {\n var controlPoints = cfg.controlPoints; // 指定controlPoints\n\n if (!controlPoints || !controlPoints.length) {\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n if (cfg.curveOffset === undefined) cfg.curveOffset = this.curveOffset;\n if (cfg.curvePosition === undefined) cfg.curvePosition = this.curvePosition;\n if (Object(esm[\"isArray\"])(this.curveOffset)) cfg.curveOffset = cfg.curveOffset[0];\n if (Object(esm[\"isArray\"])(this.curvePosition)) cfg.curvePosition = cfg.curveOffset[0];\n var innerPoint = path_getControlPoint(startPoint, endPoint, cfg.curvePosition, cfg.curveOffset);\n controlPoints = [innerPoint];\n }\n\n return controlPoints;\n },\n getPath: function getPath(points) {\n var path = [];\n path.push(['M', points[0].x, points[0].y]);\n path.push(['Q', points[1].x, points[1].y, points[2].x, points[2].y]);\n return path;\n }\n}, 'single-edge');\nelement_shape.registerEdge('cubic', {\n curvePosition: [1 / 2, 1 / 2],\n curveOffset: [-20, 20],\n getControlPoints: function getControlPoints(cfg) {\n var controlPoints = cfg.controlPoints; // 指定 controlPoints\n\n if (cfg.curveOffset === undefined) cfg.curveOffset = this.curveOffset;\n if (cfg.curvePosition === undefined) cfg.curvePosition = this.curvePosition;\n if (Object(esm[\"isNumber\"])(cfg.curveOffset)) cfg.curveOffset = [cfg.curveOffset, -cfg.curveOffset];\n if (Object(esm[\"isNumber\"])(cfg.curvePosition)) cfg.curvePosition = [cfg.curvePosition, 1 - cfg.curvePosition];\n\n if (!controlPoints || !controlPoints.length || controlPoints.length < 2) {\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n var innerPoint1 = path_getControlPoint(startPoint, endPoint, cfg.curvePosition[0], cfg.curveOffset[0]);\n var innerPoint2 = path_getControlPoint(startPoint, endPoint, cfg.curvePosition[1], cfg.curveOffset[1]);\n controlPoints = [innerPoint1, innerPoint2];\n }\n\n return controlPoints;\n },\n getPath: function getPath(points) {\n var path = [];\n path.push(['M', points[0].x, points[0].y]);\n path.push(['C', points[1].x, points[1].y, points[2].x, points[2].y, points[3].x, points[3].y]);\n return path;\n }\n}, 'single-edge'); // 垂直方向的三阶贝塞尔曲线,不再考虑用户外部传入的控制点\n\nelement_shape.registerEdge('cubic-vertical', {\n curvePosition: [1 / 2, 1 / 2],\n minCurveOffset: [0, 0],\n curveOffset: undefined,\n getControlPoints: function getControlPoints(cfg) {\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n if (cfg.curvePosition === undefined) cfg.curvePosition = this.curvePosition;\n if (cfg.curveOffset === undefined) cfg.curveOffset = this.curveOffset;\n if (cfg.minCurveOffset === undefined) cfg.minCurveOffset = this.minCurveOffset;\n if (Object(esm[\"isNumber\"])(cfg.curveOffset)) cfg.curveOffset = [cfg.curveOffset, -cfg.curveOffset];\n if (Object(esm[\"isNumber\"])(cfg.minCurveOffset)) cfg.minCurveOffset = [cfg.minCurveOffset, -cfg.minCurveOffset];\n if (Object(esm[\"isNumber\"])(cfg.curvePosition)) cfg.curvePosition = [cfg.curvePosition, 1 - cfg.curvePosition];\n var yDist = endPoint.y - startPoint.y;\n var curveOffset = [0, 0];\n\n if (cfg.curveOffset) {\n curveOffset = cfg.curveOffset;\n } else if (Math.abs(yDist) < Math.abs(cfg.minCurveOffset[0])) {\n curveOffset = cfg.minCurveOffset;\n }\n\n var innerPoint1 = {\n x: startPoint.x,\n y: startPoint.y + yDist * this.curvePosition[0] + curveOffset[0]\n };\n var innerPoint2 = {\n x: endPoint.x,\n y: endPoint.y - yDist * this.curvePosition[1] + curveOffset[1]\n };\n return [innerPoint1, innerPoint2];\n }\n}, 'cubic'); // 水平方向的三阶贝塞尔曲线,不再考虑用户外部传入的控制点\n\nelement_shape.registerEdge('cubic-horizontal', {\n curvePosition: [1 / 2, 1 / 2],\n minCurveOffset: [0, 0],\n curveOffset: undefined,\n getControlPoints: function getControlPoints(cfg) {\n var startPoint = cfg.startPoint,\n endPoint = cfg.endPoint;\n if (cfg.curvePosition === undefined) cfg.curvePosition = this.curvePosition;\n if (cfg.curveOffset === undefined) cfg.curveOffset = this.curveOffset;\n if (cfg.minCurveOffset === undefined) cfg.minCurveOffset = this.minCurveOffset;\n if (Object(esm[\"isNumber\"])(cfg.curveOffset)) cfg.curveOffset = [cfg.curveOffset, -cfg.curveOffset];\n if (Object(esm[\"isNumber\"])(cfg.minCurveOffset)) cfg.minCurveOffset = [cfg.minCurveOffset, -cfg.minCurveOffset];\n if (Object(esm[\"isNumber\"])(cfg.curvePosition)) cfg.curvePosition = [cfg.curvePosition, 1 - cfg.curvePosition];\n var xDist = endPoint.x - startPoint.x;\n var curveOffset = [0, 0];\n\n if (cfg.curveOffset) {\n curveOffset = cfg.curveOffset;\n } else if (Math.abs(xDist) < Math.abs(cfg.minCurveOffset[0])) {\n curveOffset = cfg.minCurveOffset;\n }\n\n var innerPoint1 = {\n x: startPoint.x + xDist * this.curvePosition[0] + curveOffset[0],\n y: startPoint.y\n };\n var innerPoint2 = {\n x: endPoint.x - xDist * this.curvePosition[1] + curveOffset[1],\n y: endPoint.y\n };\n var controlPoints = [innerPoint1, innerPoint2];\n return controlPoints;\n }\n}, 'cubic');\nelement_shape.registerEdge('loop', {\n getPathPoints: function getPathPoints(cfg) {\n return graphic_getLoopCfgs(cfg);\n },\n getControlPoints: function getControlPoints(cfg) {\n return cfg.controlPoints;\n },\n afterDraw: function afterDraw(cfg) {\n cfg.controlPoints = undefined;\n },\n afterUpdate: function afterUpdate(cfg) {\n cfg.controlPoints = undefined;\n }\n}, 'cubic');\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/combo.js\n\n\n\n\n\nvar singleCombo = {\n itemType: 'combo',\n // 单个图形的类型\n shapeType: 'single-combo',\n\n /**\n * Combo 标题文本相对图形的位置,默认为 top\n * 位置包括: top, bottom, left, right, center\n * @type {String}\n */\n labelPosition: 'top',\n\n /**\n * 标题文本相对偏移,当 labelPosition 不为 center 时有效\n * @type {Number}\n */\n refX: global.comboLabel.refX,\n refY: global.comboLabel.refY,\n options: {\n style: {\n stroke: global.defaultCombo.style.stroke,\n fill: global.defaultCombo.style.fill,\n lineWidth: global.defaultCombo.style.lineWidth\n },\n labelCfg: {\n style: {\n fill: global.comboLabel.style.fill,\n fontSize: global.comboLabel.style.fontSize,\n fontFamily: global.windowFontFamily\n }\n },\n stateStyles: Object(tslib_es6[\"__assign\"])({}, global.comboStateStyles)\n },\n\n /**\n * 获取 Combo 宽高\n * @internal 返回 Combo 的大小,以 [width, height] 的方式维护\n * @param {Object} cfg Combo 的配置项\n * @return {Array} 宽高\n */\n getSize: function getSize(cfg) {\n var size = Object(esm[\"clone\"])(cfg.size || this.options.size || global.defaultCombo.size); // size 是数组,若长度为 1,则补长度为 2\n\n if (Object(esm[\"isArray\"])(size) && size.length === 1) {\n size = [size[0], size[0]];\n } // size 为数字,则转换为数组\n\n\n if (!Object(esm[\"isArray\"])(size)) {\n size = [size, size];\n }\n\n return size;\n },\n // 私有方法,不希望扩展的 Combo 复写这个方法\n getLabelStyleByPosition: function getLabelStyleByPosition(cfg, labelCfg) {\n var labelPosition = labelCfg.position || this.labelPosition;\n var cfgStyle = cfg.style;\n var padding = cfg.padding || this.options.padding;\n if (Object(esm[\"isArray\"])(padding)) padding = padding[0];\n var refX = labelCfg.refX,\n refY = labelCfg.refY; // 考虑 refX 和 refY = 0 的场景,不用用 labelCfg.refX || Global.nodeLabel.refX\n\n if (Object(esm[\"isNil\"])(refX)) {\n refX = this.refX; // 不居中时的偏移量\n }\n\n if (Object(esm[\"isNil\"])(refY)) {\n refY = this.refY; // 不居中时的偏移量\n }\n\n var size = this.getSize(cfg);\n var r = Math.max(cfgStyle.r, size[0] / 2) || size[0] / 2;\n var dis = r + padding;\n var style;\n\n switch (labelPosition) {\n case 'top':\n style = {\n x: 0,\n y: -dis - refY,\n textBaseline: 'bottom',\n textAlign: 'center'\n };\n break;\n\n case 'bottom':\n style = {\n x: 0,\n y: dis + refY,\n textBaseline: 'bottom',\n textAlign: 'center'\n };\n break;\n\n case 'left':\n style = {\n x: -dis + refX,\n y: 0,\n textAlign: 'left'\n };\n break;\n\n case 'center':\n style = {\n x: 0,\n y: 0,\n text: cfg.label,\n textAlign: 'center'\n };\n break;\n\n default:\n style = {\n x: dis + refX,\n y: 0,\n textAlign: 'right'\n };\n break;\n }\n\n style.text = cfg.label;\n return style;\n },\n drawShape: function drawShape(cfg, group) {\n var shapeType = this.shapeType; // || this.type,都已经加了 shapeType\n\n var style = this.getShapeStyle(cfg);\n var shape = group.addShape(shapeType, {\n attrs: style,\n draggable: true,\n name: 'combo-shape'\n });\n return shape;\n },\n updateShape: function updateShape(cfg, item, keyShapeStyle) {\n var keyShape = item.get('keyShape');\n var animate = cfg.animate === undefined ? this.options.animate : cfg.animate;\n\n if (animate && keyShape.animate) {\n keyShape.animate(keyShapeStyle, {\n duration: 200,\n easing: 'easeLinear'\n });\n } else {\n keyShape.attr(Object(tslib_es6[\"__assign\"])({}, keyShapeStyle));\n }\n\n this.updateLabel(cfg, item); // special for some types of nodes\n }\n};\n\nvar singleComboDef = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, shapeBase), singleCombo);\n\nelement_shape.registerCombo('single-combo', singleComboDef);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/combos/circle.js\n\n\n\n // 圆形 Combo\n\nelement_shape.registerCombo('circle', {\n // 自定义节点时的配置\n options: {\n size: [global.defaultCombo.size[0], global.defaultCombo.size[0]],\n padding: global.defaultCombo.padding[0],\n animate: true,\n style: {\n stroke: global.defaultCombo.style.stroke,\n fill: global.defaultCombo.style.fill,\n lineWidth: global.defaultCombo.style.lineWidth\n },\n labelCfg: {\n style: {\n fill: global.comboLabel.style.fill,\n fontSize: global.comboLabel.style.fontSize\n },\n refX: 0,\n refY: 0\n },\n stateStyles: Object(tslib_es6[\"__assign\"])({}, global.comboStateStyles)\n },\n shapeType: 'circle',\n // 文本位置\n labelPosition: 'top',\n drawShape: function drawShape(cfg, group) {\n var style = this.getShapeStyle(cfg);\n delete style.height;\n delete style.width;\n var keyShape = group.addShape('circle', {\n attrs: style,\n className: 'circle-combo',\n name: 'circle-combo',\n draggable: true\n });\n return keyShape;\n },\n\n /**\n * 获取 Combo 的样式,供基于该 Combo 自定义时使用\n * @param {Object} cfg Combo 数据模型\n * @return {Object} Combo 的样式\n */\n getShapeStyle: function getShapeStyle(cfg) {\n var defaultStyle = this.options.style;\n var padding = cfg.padding || this.options.padding;\n if (Object(esm[\"isArray\"])(padding)) padding = padding[0];\n var strokeStyle = {\n stroke: cfg.color\n }; // 如果设置了color,则覆盖默认的stroke属性\n\n var style = Object(esm[\"mix\"])({}, defaultStyle, strokeStyle, cfg.style);\n var r;\n\n if (cfg.fixSize) {\n r = Object(esm[\"isNumber\"])(cfg.fixSize) ? cfg.fixSize : cfg.fixSize[0];\n } else {\n var size = this.getSize(cfg);\n if (!Object(esm[\"isNumber\"])(style.r) || isNaN(style.r)) r = size[0] / 2 || global.defaultCombo.style.r;else r = Math.max(style.r, size[0] / 2) || size[0] / 2;\n }\n\n style.r = r + padding;\n\n var styles = Object(tslib_es6[\"__assign\"])({\n x: 0,\n y: 0\n }, style);\n\n if (cfg.style) cfg.style.r = r;else {\n cfg.style = {\n r: r\n };\n }\n return styles;\n },\n update: function update(cfg, item) {\n var size = this.getSize(cfg);\n var padding = cfg.padding || this.options.padding;\n if (Object(esm[\"isArray\"])(padding)) padding = padding[0];\n var cfgStyle = Object(esm[\"clone\"])(cfg.style);\n var r;\n\n if (cfg.fixSize) {\n r = Object(esm[\"isNumber\"])(cfg.fixSize) ? cfg.fixSize : cfg.fixSize[0];\n } else {\n r = Math.max(cfgStyle.r, size[0] / 2) || size[0] / 2;\n }\n\n cfgStyle.r = r + padding;\n var itemCacheSize = item.get('sizeCache');\n\n if (itemCacheSize) {\n itemCacheSize.r = cfgStyle.r;\n } // 下面这些属性需要覆盖默认样式与目前样式,但若在 cfg 中有指定则应该被 cfg 的相应配置覆盖。\n\n\n var strokeStyle = {\n stroke: cfg.color\n }; // 与 getShapeStyle 不同在于,update 时需要获取到当前的 style 进行融合。即新传入的配置项中没有涉及的属性,保留当前的配置。\n\n var keyShape = item.get('keyShape');\n var style = Object(esm[\"mix\"])({}, keyShape.attr(), strokeStyle, cfgStyle);\n if (cfg.style) cfg.style.r = r;else {\n cfg.style = {\n r: r\n };\n }\n this.updateShape(cfg, item, style, true);\n }\n}, 'single-combo');\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/combos/rect.js\n\n\n\n\nelement_shape.registerCombo('rect', {\n // 自定义 Combo 时的配置\n options: {\n size: [40, 5],\n padding: [25, 20, 15, 20],\n animate: true,\n style: {\n radius: 0,\n stroke: global.defaultCombo.style.stroke,\n fill: global.defaultCombo.style.fill,\n lineWidth: global.defaultCombo.style.lineWidth\n },\n // 文本样式配置\n labelCfg: {\n style: {\n fill: global.comboLabel.style.fill,\n fontSize: global.comboLabel.style.fontSize,\n fontFamily: global.windowFontFamily\n }\n },\n // 连接点,默认为左右\n anchorPoints: [[0, 0.5], [1, 0.5]],\n stateStyles: Object(tslib_es6[\"__assign\"])({}, global.comboStateStyles)\n },\n shapeType: 'rect',\n labelPosition: 'top',\n drawShape: function drawShape(cfg, group) {\n var style = this.getShapeStyle(cfg);\n var keyShape = group.addShape('rect', {\n attrs: style,\n className: 'rect-combo',\n name: 'rect-combo',\n draggable: true\n });\n return keyShape;\n },\n // 私有方法,不希望扩展的 Combo 复写这个方法\n getLabelStyleByPosition: function getLabelStyleByPosition(cfg, labelCfg) {\n var labelPosition = labelCfg.position || this.labelPosition;\n var cfgStyle = cfg.style;\n var padding = cfg.padding || this.options.padding;\n if (Object(esm[\"isNumber\"])(padding)) padding = [padding, padding, padding, padding];\n var refX = labelCfg.refX,\n refY = labelCfg.refY; // 考虑 refX 和 refY = 0 的场景,不用用 labelCfg.refX || Global.nodeLabel.refY\n\n if (Object(esm[\"isNil\"])(refX)) {\n refX = this.refX; // 不居中时的偏移量\n }\n\n if (Object(esm[\"isNil\"])(refY)) {\n refY = this.refY; // 不居中时的偏移量\n }\n\n var leftDis = cfgStyle.width / 2 + padding[3];\n var topDis = cfgStyle.height / 2 + padding[0];\n var style;\n\n switch (labelPosition) {\n case 'top':\n style = {\n x: 0 - leftDis + refX,\n y: 0 - topDis + refY,\n textBaseline: 'top',\n textAlign: 'left'\n };\n break;\n\n case 'bottom':\n style = {\n x: 0,\n y: topDis + refY,\n textBaseline: 'bottom',\n textAlign: 'center'\n };\n break;\n\n case 'left':\n style = {\n x: 0 - leftDis + refY,\n y: 0,\n textAlign: 'left'\n };\n break;\n\n case 'center':\n style = {\n x: 0,\n y: 0,\n text: cfg.label,\n textAlign: 'center'\n };\n break;\n\n default:\n style = {\n x: leftDis + refX,\n y: 0,\n textAlign: 'right'\n };\n break;\n }\n\n style.text = cfg.label;\n return style;\n },\n\n /**\n * 获取节点的样式,供基于该节点自定义时使用\n * @param {Object} cfg 节点数据模型\n * @return {Object} 节点的样式\n */\n getShapeStyle: function getShapeStyle(cfg) {\n var defaultStyle = this.options.style;\n var padding = cfg.padding || this.options.padding;\n if (Object(esm[\"isNumber\"])(padding)) padding = [padding, padding, padding, padding];\n var strokeStyle = {\n stroke: cfg.color\n }; // 如果设置了color,则覆盖默认的stroke属性\n\n var style = Object(esm[\"mix\"])({}, defaultStyle, strokeStyle, cfg.style);\n var size = this.getSize(cfg);\n var width;\n var height;\n var fixSize = cfg.collapsed && cfg.fixCollapseSize ? cfg.fixCollapseSize : cfg.fixSize;\n\n if (fixSize) {\n if (Object(esm[\"isNumber\"])(fixSize)) {\n width = fixSize;\n height = fixSize;\n } else {\n width = fixSize[0];\n height = fixSize[1];\n }\n } else {\n if (!Object(esm[\"isNumber\"])(style.width) || isNaN(style.width)) width = size[0] || global.defaultCombo.style.width;else width = Math.max(style.width, size[0]) || size[0];\n if (!Object(esm[\"isNumber\"])(style.height) || isNaN(style.height)) height = size[1] || global.defaultCombo.style.height;else height = Math.max(style.height, size[1]) || size[1];\n }\n\n var x = -width / 2 - padding[3];\n var y = -height / 2 - padding[0];\n style.width = width + padding[1] + padding[3];\n style.height = height + padding[0] + padding[2];\n\n var styles = Object(tslib_es6[\"__assign\"])({\n x: x,\n y: y\n }, style);\n\n if (!cfg.style) {\n cfg.style = {\n width: width,\n height: height\n };\n } else {\n cfg.style.width = width;\n cfg.style.height = height;\n }\n\n return styles;\n },\n update: function update(cfg, item) {\n var size = this.getSize(cfg);\n var padding = cfg.padding || this.options.padding;\n if (Object(esm[\"isNumber\"])(padding)) padding = [padding, padding, padding, padding];\n var cfgStyle = Object(esm[\"clone\"])(cfg.style);\n var width, height;\n var fixSize = cfg.collapsed && cfg.fixCollapseSize ? cfg.fixCollapseSize : cfg.fixSize;\n\n if (fixSize) {\n if (Object(esm[\"isNumber\"])(fixSize)) {\n width = fixSize;\n height = fixSize;\n } else {\n width = fixSize[0];\n height = fixSize[1];\n }\n } else {\n width = Math.max(cfgStyle.width, size[0]) || size[0];\n height = Math.max(cfgStyle.height, size[1]) || size[1];\n }\n\n cfgStyle.width = width + padding[1] + padding[3];\n cfgStyle.height = height + padding[0] + padding[2];\n var itemCacheSize = item.get('sizeCache');\n\n if (itemCacheSize) {\n itemCacheSize.width = cfgStyle.width;\n itemCacheSize.height = cfgStyle.height;\n }\n\n cfgStyle.x = -width / 2 - padding[3];\n cfgStyle.y = -height / 2 - padding[0]; // 下面这些属性需要覆盖默认样式与目前样式,但若在 cfg 中有指定则应该被 cfg 的相应配置覆盖。\n\n var strokeStyle = {\n stroke: cfg.color\n }; // 与 getShapeStyle 不同在于,update 时需要获取到当前的 style 进行融合。即新传入的配置项中没有涉及的属性,保留当前的配置。\n\n var keyShape = item.get('keyShape');\n var style = Object(esm[\"mix\"])({}, keyShape.attr(), strokeStyle, cfgStyle);\n\n if (cfg.style) {\n cfg.style.width = width;\n cfg.style.height = height;\n } else {\n cfg.style = {\n width: width,\n height: height\n };\n }\n\n this.updateShape(cfg, item, style, false);\n },\n updateShape: function updateShape(cfg, item, keyShapeStyle) {\n var keyShape = item.get('keyShape');\n var animate = cfg.animate === undefined ? this.options.animate : cfg.animate;\n\n if (animate && keyShape.animate) {\n keyShape.animate(keyShapeStyle, {\n duration: 200,\n easing: 'easeLinear'\n });\n } else {\n keyShape.attr(Object(tslib_es6[\"__assign\"])({}, keyShapeStyle));\n }\n\n this.updateLabel(cfg, item);\n }\n}, 'single-combo');\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/combos/index.js\n\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/nodes/simple-circle.js\n\n\n\n // 带有图标的圆,可用于拓扑图中\n\nelement_shape.registerNode('simple-circle', {\n // 自定义节点时的配置\n options: {\n size: global.defaultNode.size,\n style: {\n x: 0,\n y: 0,\n stroke: global.defaultNode.style.stroke,\n fill: global.defaultNode.style.fill,\n lineWidth: global.defaultNode.style.lineWidth\n },\n labelCfg: {\n style: {\n fill: global.nodeLabel.style.fill,\n fontSize: global.nodeLabel.style.fontSize,\n fontFamily: global.windowFontFamily\n }\n },\n stateStyles: Object(tslib_es6[\"__assign\"])({}, global.nodeStateStyles)\n },\n shapeType: 'simple-circle',\n // 文本位置\n labelPosition: 'center',\n shapeMap: {},\n drawShape: function drawShape(cfg, group) {\n var style = this.getShapeStyle(cfg);\n var name = this.type + \"-keyShape\";\n var keyShape = group.addShape('circle', {\n attrs: style,\n className: this.type + \"-keyShape\",\n name: name,\n draggable: true\n });\n group['shapeMap'][name] = keyShape;\n return keyShape;\n },\n\n /**\n * 获取节点的样式,供基于该节点自定义时使用\n * @param {Object} cfg 节点数据模型\n * @return {Object} 节点的样式\n */\n getShapeStyle: function getShapeStyle(cfg) {\n var defaultStyle = (this.mergeStyle || this.getOptions(cfg)).style;\n var strokeStyle = {\n stroke: cfg.color\n }; // 如果设置了color,则覆盖默认的stroke属性\n\n var style = Object(esm[\"deepMix\"])({}, defaultStyle, strokeStyle);\n var size = this.getSize(cfg);\n var r = size[0] / 2;\n\n var styles = Object(tslib_es6[\"__assign\"])({\n x: 0,\n y: 0,\n r: r\n }, style);\n\n return styles;\n },\n update: function update(cfg, item, updateType) {\n var size = this.getSize(cfg); // 下面这些属性需要覆盖默认样式与目前样式,但若在 cfg 中有指定则应该被 cfg 的相应配置覆盖。\n\n var strokeStyle = {\n stroke: cfg.color,\n r: size[0] / 2\n }; // 与 getShapeStyle 不同在于,update 时需要获取到当前的 style 进行融合。即新传入的配置项中没有涉及的属性,保留当前的配置。\n\n var keyShape = item.get('keyShape');\n var style = Object(esm[\"deepMix\"])({}, keyShape.attr(), strokeStyle, cfg.style);\n this.updateShape(cfg, item, style, true, updateType);\n }\n}, 'single-node');\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/nodes/simple-rect.js\n\n\n\n\nelement_shape.registerNode('simple-rect', {\n // 自定义节点时的配置\n options: {\n size: [100, 30],\n style: {\n radius: 0,\n stroke: global.defaultNode.style.stroke,\n fill: global.defaultNode.style.fill,\n lineWidth: global.defaultNode.style.lineWidth\n },\n // 文本样式配置\n labelCfg: {\n style: {\n fill: global.nodeLabel.style.fill,\n fontSize: global.nodeLabel.style.fontSize,\n fontFamily: global.windowFontFamily\n }\n },\n // 连接点,默认为左右\n // anchorPoints: [{ x: 0, y: 0.5 }, { x: 1, y: 0.5 }]\n anchorPoints: [[0, 0.5], [1, 0.5]],\n stateStyles: Object(tslib_es6[\"__assign\"])({}, global.nodeStateStyles)\n },\n shapeType: 'simple-rect',\n labelPosition: 'center',\n drawShape: function drawShape(cfg, group) {\n var style = this.getShapeStyle(cfg);\n var keyShape = group.addShape('rect', {\n attrs: style,\n className: this.type + \"-keyShape\",\n name: this.type + \"-keyShape\",\n draggable: true\n });\n return keyShape;\n },\n\n /**\n * 获取节点的样式,供基于该节点自定义时使用\n * @param {Object} cfg 节点数据模型\n * @return {Object} 节点的样式\n */\n getShapeStyle: function getShapeStyle(cfg) {\n var defaultStyle = (this.mergeStyle || this.getOptions(cfg)).style;\n var strokeStyle = {\n stroke: cfg.color\n }; // 如果设置了color,则覆盖默认的stroke属性\n\n var style = Object(esm[\"mix\"])({}, defaultStyle, strokeStyle);\n var size = this.getSize(cfg);\n var width = style.width || size[0];\n var height = style.height || size[1];\n\n var styles = Object(tslib_es6[\"__assign\"])({\n x: -width / 2,\n y: -height / 2,\n width: width,\n height: height\n }, style);\n\n return styles;\n },\n update: function update(cfg, item, updateType) {\n var group = item.getContainer(); // 这里不传 cfg 参数是因为 cfg.style 需要最后覆盖样式\n\n var defaultStyle = (this.mergeStyle || this.getOptions(cfg)).style;\n var size = this.getSize(cfg);\n var keyShape = item.get('keyShape');\n\n if (!cfg.size) {\n size[0] = keyShape.attr('width') || defaultStyle.width;\n size[1] = keyShape.attr('height') || defaultStyle.height;\n } // 下面这些属性需要覆盖默认样式与目前样式,但若在 cfg 中有指定则应该被 cfg 的相应配置覆盖。\n\n\n var strokeStyle = {\n stroke: cfg.color,\n x: -size[0] / 2,\n y: -size[1] / 2,\n width: size[0],\n height: size[1]\n }; // 与 getShapeStyle 不同在于,update 时需要获取到当前的 style 进行融合。即新传入的配置项中没有涉及的属性,保留当前的配置。\n\n var style = Object(esm[\"mix\"])({}, defaultStyle, keyShape.attr(), strokeStyle);\n style = Object(esm[\"mix\"])(style, cfg.style);\n this.updateShape(cfg, item, style, false, updateType);\n }\n}, 'single-node');\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/nodes/image.js\n\n\n\n/**\n * 基本的图片,可以添加文本,默认文本在图片的下面\n */\n\nelement_shape.registerNode('image', {\n options: {\n img: 'https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*eD7nT6tmYgAAAAAAAAAAAABkARQnAQ',\n size: 200,\n labelCfg: {\n style: {\n fontFamily: global.windowFontFamily\n }\n },\n clipCfg: {\n show: false,\n type: 'circle',\n // circle\n r: 50,\n // ellipse\n rx: 50,\n ry: 35,\n // rect\n width: 50,\n height: 35,\n // polygon\n points: [[30, 12], [12, 30], [30, 48], [48, 30]],\n // path\n path: [['M', 25, 25], ['L', 50, 25], ['A', 12.5, 12.5, 0, 1, 1, 50, 50], ['A', 12.5, 12.5, 0, 1, 0, 50, 50], ['L', 25, 75], ['Z']],\n // 坐标\n x: 0,\n y: 0 // clip 的属性样式\n // style: {\n // lineWidth: 1\n // },\n\n }\n },\n shapeType: 'image',\n labelPosition: 'bottom',\n drawShape: function drawShape(cfg, group) {\n var shapeType = this.shapeType;\n var style = this.getShapeStyle(cfg);\n delete style.fill;\n var shape = group.addShape(shapeType, {\n attrs: style,\n className: this.type + \"-keyShape\",\n name: this.type + \"-keyShape\",\n draggable: true\n });\n this.drawClip(cfg, shape);\n return shape;\n },\n drawClip: function drawClip(cfg, shape) {\n var clip = (this.mergeStyle || this.getOptions(cfg)).clipCfg;\n\n if (!clip.show) {\n return;\n } // 支持 circle、rect、ellipse、Polygon 及自定义 path clip\n\n\n var type = clip.type,\n x = clip.x,\n y = clip.y,\n style = clip.style;\n\n if (type === 'circle') {\n var r = clip.r;\n shape.setClip({\n type: 'circle',\n attrs: Object(tslib_es6[\"__assign\"])({\n r: r,\n x: x,\n y: y\n }, style)\n });\n } else if (type === 'rect') {\n var width = clip.width,\n height = clip.height;\n var rectX = x - width / 2;\n var rectY = y - height / 2;\n shape.setClip({\n type: 'rect',\n attrs: Object(tslib_es6[\"__assign\"])({\n x: rectX,\n y: rectY,\n width: width,\n height: height\n }, style)\n });\n } else if (type === 'ellipse') {\n var rx = clip.rx,\n ry = clip.ry;\n shape.setClip({\n type: 'ellipse',\n attrs: Object(tslib_es6[\"__assign\"])({\n x: x,\n y: y,\n rx: rx,\n ry: ry\n }, style)\n });\n } else if (type === 'polygon') {\n var points = clip.points;\n shape.setClip({\n type: 'polygon',\n attrs: Object(tslib_es6[\"__assign\"])({\n points: points\n }, style)\n });\n } else if (type === 'path') {\n var path = clip.path;\n shape.setClip({\n type: 'path',\n attrs: Object(tslib_es6[\"__assign\"])({\n path: path\n }, style)\n });\n }\n },\n getShapeStyle: function getShapeStyle(cfg) {\n var _a = this.mergeStyle || this.getOptions(cfg),\n defaultStyle = _a.style,\n img = _a.img;\n\n var size = this.getSize(cfg);\n var width = size[0];\n var height = size[1];\n\n if (defaultStyle) {\n width = defaultStyle.width || size[0];\n height = defaultStyle.height || size[1];\n }\n\n var style = Object(tslib_es6[\"__assign\"])({\n x: -width / 2,\n y: -height / 2,\n width: width,\n height: height,\n img: img\n }, defaultStyle);\n\n return style;\n },\n updateShapeStyle: function updateShapeStyle(cfg, item) {\n var group = item.getContainer();\n var shapeClassName = this.itemType + \"-shape\";\n var shape = group['shapeMap'][shapeClassName] || group.find(function (element) {\n return element.get('className') === shapeClassName;\n }) || item.getKeyShape();\n var shapeStyle = this.getShapeStyle(cfg);\n\n if (shape && !shape.destroyed) {\n shape.attr(shapeStyle);\n }\n }\n}, 'single-node');\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/nodes/index.js\n\n\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/arrow.js\n/* harmony default export */ var element_arrow = ({\n triangle: function triangle(width, length, d) {\n if (width === void 0) {\n width = 10;\n }\n\n if (length === void 0) {\n length = 15;\n }\n\n if (d === void 0) {\n d = 0;\n }\n\n var begin = d * 2;\n var path = \"M \" + begin + \",0 L \" + (begin + length) + \",-\" + width / 2 + \" L \" + (begin + length) + \",\" + width / 2 + \" Z\";\n return path;\n },\n vee: function vee(width, length, d) {\n if (width === void 0) {\n width = 15;\n }\n\n if (length === void 0) {\n length = 20;\n }\n\n if (d === void 0) {\n d = 0;\n }\n\n var begin = d * 2;\n var path = \"M \" + begin + \",0 L \" + (begin + length) + \",-\" + width / 2 + \"\\n L \" + (begin + 2 * length / 3) + \",0 L \" + (begin + length) + \",\" + width / 2 + \" Z\";\n return path;\n },\n circle: function circle(r, d) {\n if (r === void 0) {\n r = 5;\n }\n\n if (d === void 0) {\n d = 0;\n }\n\n var begin = d * 2;\n var path = \"M \" + begin + \", 0\\n a \" + r + \",\" + r + \" 0 1,0 \" + r * 2 + \",0\\n a \" + r + \",\" + r + \" 0 1,0 \" + -r * 2 + \",0\";\n return path;\n },\n rect: function rect(width, length, d) {\n if (width === void 0) {\n width = 10;\n }\n\n if (length === void 0) {\n length = 10;\n }\n\n if (d === void 0) {\n d = 0;\n }\n\n var begin = d * 2;\n var path = \"M \" + begin + \",\" + -width / 2 + \" \\n L \" + (begin + length) + \",\" + -width / 2 + \" \\n L \" + (begin + length) + \",\" + width / 2 + \" \\n L \" + begin + \",\" + width / 2 + \" Z\";\n return path;\n },\n diamond: function diamond(width, length, d) {\n if (width === void 0) {\n width = 15;\n }\n\n if (length === void 0) {\n length = 15;\n }\n\n if (d === void 0) {\n d = 0;\n }\n\n var begin = d * 2;\n var path = \"M \" + begin + \",0 \\n L \" + (begin + length / 2) + \",\" + -width / 2 + \" \\n L \" + (begin + length) + \",0 \\n L \" + (begin + length / 2) + \",\" + width / 2 + \" Z\";\n return path;\n },\n triangleRect: function triangleRect(tWidth, tLength, rWidth, rLength, gap, d) {\n if (tWidth === void 0) {\n tWidth = 15;\n }\n\n if (tLength === void 0) {\n tLength = 15;\n }\n\n if (rWidth === void 0) {\n rWidth = 15;\n }\n\n if (rLength === void 0) {\n rLength = 3;\n }\n\n if (gap === void 0) {\n gap = 5;\n }\n\n if (d === void 0) {\n d = 0;\n }\n\n var begin = d * 2;\n var rectBegin = begin + tLength + gap;\n var path = \"M \" + begin + \",0 L \" + (begin + tLength) + \",-\" + tWidth / 2 + \" L \" + (begin + tLength) + \",\" + tWidth / 2 + \" Z\\n M \" + rectBegin + \", -\" + rWidth / 2 + \"\\n L \" + (rectBegin + rLength) + \" -\" + rWidth / 2 + \"\\n L \" + (rectBegin + rLength) + \" \" + rWidth / 2 + \"\\n L \" + rectBegin + \" \" + rWidth / 2 + \"\\n Z\";\n return path;\n }\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/marker.js\n/* harmony default export */ var marker = ({\n collapse: function collapse(x, y, r) {\n return [['M', x - r, y], ['a', r, r, 0, 1, 0, r * 2, 0], ['a', r, r, 0, 1, 0, -r * 2, 0], ['M', x - r + 4, y], ['L', x + r - 4, y]];\n },\n expand: function expand(x, y, r) {\n return [['M', x - r, y], ['a', r, r, 0, 1, 0, r * 2, 0], ['a', r, r, 0, 1, 0, -r * 2, 0], ['M', x - r + 4, y], ['L', x - r + 2 * r - 4, y], ['M', x - r + r, y - r + 4], ['L', x, y + r - 4]];\n },\n upTriangle: function upTriangle(x, y, r) {\n var l1 = r * Math.cos(Math.PI / 6);\n var l2 = r * Math.sin(Math.PI / 6);\n return [['M', x - l1, y + l2], ['L', x + l1, y + l2], ['L', x, y - r], ['Z']];\n },\n downTriangle: function downTriangle(x, y, r) {\n var l1 = r * Math.cos(Math.PI / 6);\n var l2 = r * Math.sin(Math.PI / 6);\n return [['M', x - l1, y - l2], ['L', x + l1, y - l2], ['L', x, y + r], ['Z']];\n }\n});\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/element/index.js\n\n\n\n\n\n\n\n\n/* harmony default export */ var es_element = (element_shape);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/color.js\nvar defaultSubjectColors = ['#5F95FF', '#61DDAA', '#65789B', '#F6BD16', '#7262FD', '#78D3F8', '#9661BC', '#F6903D', '#008685', '#F08BB4'];\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/util/index.js\n\n\n\n\n\n\n\nvar util_transform = matrix_util_esm[\"ext\"].transform;\n\nvar Util = Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])(Object(tslib_es6[\"__assign\"])({}, base_namespaceObject), graphic_namespaceObject), path_namespaceObject), math_namespaceObject), color_namespaceObject), {\n transform: util_transform,\n mat3: matrix_util_esm[\"mat3\"]\n});\n\n/* harmony default export */ var util = (Util);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/layout.js\n\n\n\n\nvar layout_LayoutController =\n/** @class */\nfunction () {\n function LayoutController(graph) {\n this.graph = graph;\n this.layoutCfg = graph.get('layout') || {};\n this.layoutType = this.getLayoutType();\n this.layoutMethods = [];\n this.initLayout();\n } // eslint-disable-next-line class-methods-use-this\n\n\n LayoutController.prototype.initLayout = function () {// no data before rendering\n };\n\n LayoutController.prototype.getLayoutType = function () {\n return this.getLayoutCfgType(this.layoutCfg);\n };\n\n LayoutController.prototype.getLayoutCfgType = function (layoutCfg) {\n var type = layoutCfg.type; // type should be top priority\n\n if (type) {\n return type;\n }\n\n var pipes = layoutCfg.pipes;\n\n if (Array.isArray(pipes)) {\n return pipes.map(function (pipe) {\n return (pipe === null || pipe === void 0 ? void 0 : pipe.type) || '';\n });\n }\n\n return null;\n };\n\n LayoutController.prototype.isLayoutTypeSame = function (cfg) {\n var current = this.getLayoutCfgType(cfg); // already has pipes\n\n if (Array.isArray(this.layoutType)) {\n return this.layoutType.every(function (type, index) {\n return type === current[index];\n });\n }\n\n return (cfg === null || cfg === void 0 ? void 0 : cfg.type) === this.layoutType;\n }; // 绘制\n\n\n LayoutController.prototype.refreshLayout = function () {\n var graph = this.graph;\n if (!graph) return;\n\n if (graph.get('animate')) {\n graph.positionsAnimate();\n } else {\n graph.refreshPositions();\n }\n }; // 更换布局\n\n\n LayoutController.prototype.changeLayout = function (cfg) {\n this.layoutCfg = cfg;\n this.destoryLayoutMethods();\n this.layout();\n }; // 更换数据\n\n\n LayoutController.prototype.changeData = function () {\n this.destoryLayoutMethods();\n this.layout();\n };\n\n LayoutController.prototype.destoryLayoutMethods = function () {\n var layoutMethods = this.layoutMethods;\n layoutMethods === null || layoutMethods === void 0 ? void 0 : layoutMethods.forEach(function (layoutMethod) {\n layoutMethod.destroy();\n });\n this.layoutMethods = [];\n }; // 销毁布局,不能使用 this.destroy,因为 controller 还需要被使用,只是把布局算法销毁\n\n\n LayoutController.prototype.destroyLayout = function () {\n var graph = this.graph;\n this.destoryLayoutMethods();\n graph.set('layout', undefined);\n this.layoutCfg = undefined;\n this.layoutType = undefined;\n this.layoutMethods = undefined;\n }; // 从 this.graph 获取数据\n\n\n LayoutController.prototype.setDataFromGraph = function () {\n var nodes = [];\n var hiddenNodes = [];\n var edges = [];\n var hiddenEdges = [];\n var comboEdges = [];\n var combos = [];\n var hiddenCombos = [];\n var nodeItems = this.graph.getNodes();\n var edgeItems = this.graph.getEdges();\n var comboItems = this.graph.getCombos();\n var nodeLength = nodeItems.length;\n\n for (var i = 0; i < nodeLength; i++) {\n var nodeItem = nodeItems[i];\n if (!nodeItem || nodeItem.destroyed) continue;\n var model = nodeItem.getModel();\n\n if (!nodeItem.isVisible()) {\n hiddenNodes.push(model);\n continue;\n }\n\n nodes.push(model);\n }\n\n var edgeLength = edgeItems.length;\n\n for (var i = 0; i < edgeLength; i++) {\n var edgeItem = edgeItems[i];\n if (!edgeItem || edgeItem.destroyed) continue;\n var model = edgeItem.getModel();\n\n if (!edgeItem.isVisible()) {\n hiddenEdges.push(model);\n continue;\n }\n\n if (!model.isComboEdge) edges.push(model);else comboEdges.push(model);\n }\n\n var comboLength = comboItems.length;\n\n for (var i = 0; i < comboLength; i++) {\n var comboItem = comboItems[i];\n if (comboItem.destroyed) continue;\n var model = comboItem.getModel();\n\n if (!comboItem.isVisible()) {\n hiddenEdges.push(model);\n continue;\n }\n\n combos.push(model);\n }\n\n return {\n nodes: nodes,\n hiddenNodes: hiddenNodes,\n edges: edges,\n hiddenEdges: hiddenEdges,\n combos: combos,\n hiddenCombos: hiddenCombos,\n comboEdges: comboEdges\n };\n };\n\n LayoutController.prototype.reLayoutMethod = function (layoutMethod, layoutCfg) {\n var _this = this;\n\n return new Promise(function (reslove, reject) {\n var graph = _this.graph;\n var layoutType = layoutCfg === null || layoutCfg === void 0 ? void 0 : layoutCfg.type; // 每个布局方法都需要注册\n\n layoutCfg.onLayoutEnd = function () {\n graph.emit('aftersublayout', {\n type: layoutType\n });\n reslove();\n };\n\n layoutMethod.init(_this.data);\n\n if (layoutType === 'force') {\n layoutMethod.ticking = false;\n layoutMethod.forceSimulation.stop();\n }\n\n graph.emit('beforesublayout', {\n type: layoutType\n });\n layoutMethod.execute();\n if (layoutMethod.isCustomLayout && layoutCfg.onLayoutEnd) layoutCfg.onLayoutEnd();\n });\n }; // 重新布局\n\n\n LayoutController.prototype.relayout = function (reloadData) {\n var _this = this;\n\n var _a = this,\n graph = _a.graph,\n layoutMethods = _a.layoutMethods,\n layoutCfg = _a.layoutCfg;\n\n if (reloadData) {\n this.data = this.setDataFromGraph();\n var nodes = this.data.nodes;\n\n if (!nodes) {\n return false;\n }\n\n this.initPositions(layoutCfg.center, nodes);\n }\n\n graph.emit('beforelayout');\n var start = Promise.resolve();\n layoutMethods === null || layoutMethods === void 0 ? void 0 : layoutMethods.forEach(function (layoutMethod, index) {\n var currentCfg = layoutCfg[index];\n start = start.then(function () {\n return _this.reLayoutMethod(layoutMethod, currentCfg);\n });\n });\n start.then(function () {\n if (layoutCfg.onAllLayoutEnd) layoutCfg.onAllLayoutEnd();\n }).catch(function (error) {\n console.warn('relayout failed', error);\n });\n }; // 筛选参与布局的nodes和edges\n\n\n LayoutController.prototype.filterLayoutData = function (data, cfg) {\n var nodes = data.nodes,\n edges = data.edges,\n rest = Object(tslib_es6[\"__rest\"])(data, [\"nodes\", \"edges\"]);\n\n if (!nodes) {\n return data;\n }\n\n var nodesFilter;\n var edegsFilter;\n\n if (Object(esm[\"isFunction\"])(cfg === null || cfg === void 0 ? void 0 : cfg.nodesFilter)) {\n nodesFilter = cfg.nodesFilter;\n } else {\n nodesFilter = function nodesFilter() {\n return true;\n };\n }\n\n var fNodes = nodes.filter(nodesFilter);\n\n if (Object(esm[\"isFunction\"])(cfg === null || cfg === void 0 ? void 0 : cfg.edgesFilter)) {\n edegsFilter = cfg.edgesFilter;\n } else {\n var nodesMap_1 = fNodes.reduce(function (acc, cur) {\n acc[cur.id] = true;\n return acc;\n }, {});\n\n edegsFilter = function edegsFilter(edge) {\n return nodesMap_1[edge.source] && nodesMap_1[edge.target];\n };\n }\n\n return Object(tslib_es6[\"__assign\"])({\n nodes: fNodes,\n edges: edges.filter(edegsFilter)\n }, rest);\n };\n\n LayoutController.prototype.getLayoutBBox = function (nodes) {\n var graph = this.graph;\n var graphGroupNodes = Object(esm[\"groupBy\"])(graph.getNodes(), function (n) {\n return n.getModel().layoutOrder;\n });\n var layoutNodes = Object.values(graphGroupNodes).map(function (value) {\n var bbox = calculationItemsBBox(value);\n bbox.size = [bbox.width, bbox.height];\n return bbox;\n });\n var groupNodes = Object.values(Object(esm[\"groupBy\"])(nodes, 'layoutOrder'));\n return {\n groupNodes: groupNodes,\n layoutNodes: layoutNodes\n };\n }; // 控制布局动画\n // eslint-disable-next-line class-methods-use-this\n\n\n LayoutController.prototype.layoutAnimate = function () {}; // 将当前节点的平均中心移动到原点\n\n\n LayoutController.prototype.moveToZero = function () {\n var graph = this.graph;\n var data = graph.get('data');\n var nodes = data.nodes;\n\n if (nodes[0].x === undefined || nodes[0].x === null || base_isNaN(nodes[0].x)) {\n return;\n }\n\n var meanCenter = [0, 0];\n var nodeLength = nodes.length;\n\n for (var i = 0; i < nodeLength; i++) {\n var node = nodes[i];\n meanCenter[0] += node.x;\n meanCenter[1] += node.y;\n }\n\n meanCenter[0] /= nodes.length;\n meanCenter[1] /= nodes.length;\n\n for (var i = 0; i < nodeLength; i++) {\n var node = nodes[i];\n node.x -= meanCenter[0];\n node.y -= meanCenter[1];\n }\n }; // 初始化节点到 center 附近\n\n\n LayoutController.prototype.initPositions = function (center, nodes) {\n var graph = this.graph;\n\n if (!nodes) {\n return false;\n }\n\n var nodeLength = nodes ? nodes.length : 0;\n if (!nodeLength) return;\n var width = graph.get('width') * 0.85;\n var height = graph.get('height') * 0.85;\n var horiNum = Math.ceil(Math.sqrt(nodeLength) * (width / height));\n var vertiNum = Math.ceil(nodeLength / horiNum);\n var horiGap = width / (horiNum - 1);\n var vertiGap = height / (vertiNum - 1);\n if (!isFinite(horiGap) || !horiGap) horiGap = 0;\n if (!isFinite(vertiGap) || !horiGap) vertiGap = 0;\n var beginX = center[0] - width / 2;\n var beginY = center[1] - height / 2;\n var allHavePos = true;\n\n for (var i = 0; i < nodeLength; i++) {\n var node = nodes[i];\n\n if (base_isNaN(+node.x)) {\n allHavePos = false;\n node.x = i % horiNum * horiGap + beginX;\n }\n\n if (base_isNaN(+node.y)) {\n allHavePos = false;\n node.y = Math.floor(i / horiNum) * vertiGap + beginY;\n }\n }\n\n return allHavePos;\n };\n\n LayoutController.prototype.destroy = function () {\n this.graph = null;\n this.destoryLayoutMethods();\n this.destroyed = true;\n };\n\n return LayoutController;\n}();\n\n/* harmony default export */ var controller_layout = (layout_LayoutController);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/graph/controller/event.js\nvar event_EventController =\n/** @class */\nfunction () {\n function EventController(graph) {\n this.graph = graph;\n this.destroyed = false;\n this.initEvents();\n }\n\n return EventController;\n}();\n\n/* harmony default export */ var controller_event = (event_EventController);\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/interface/graph.js\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/interface/item.js\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/interface/shape.js\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/interface/index.js\n\n\n\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/types/index.js\n // Behavior type file\n\nvar G6Event;\n\n(function (G6Event) {\n // common events\n G6Event[\"CLICK\"] = \"click\";\n G6Event[\"DBLCLICK\"] = \"dblclick\";\n G6Event[\"MOUSEDOWN\"] = \"mousedown\";\n G6Event[\"MOUDEUP\"] = \"mouseup\";\n G6Event[\"CONTEXTMENU\"] = \"contextmenu\";\n G6Event[\"MOUSEENTER\"] = \"mouseenter\";\n G6Event[\"MOUSEOUT\"] = \"mouseout\";\n G6Event[\"MOUSEOVER\"] = \"mouseover\";\n G6Event[\"MOUSEMOVE\"] = \"mousemove\";\n G6Event[\"MOUSELEAVE\"] = \"mouseleave\";\n G6Event[\"DRAGSTART\"] = \"dragstart\";\n G6Event[\"DRAGEND\"] = \"dragend\";\n G6Event[\"DRAG\"] = \"drag\";\n G6Event[\"DRAGENTER\"] = \"dragenter\";\n G6Event[\"DRAGLEAVE\"] = \"dragleave\";\n G6Event[\"DRAGOVER\"] = \"dragover\";\n G6Event[\"DRAGOUT\"] = \"dragout\";\n G6Event[\"DDROP\"] = \"drop\";\n G6Event[\"KEYUP\"] = \"keyup\";\n G6Event[\"KEYDOWN\"] = \"keydown\";\n G6Event[\"WHEEL\"] = \"wheel\";\n G6Event[\"FOCUS\"] = \"focus\";\n G6Event[\"BLUR\"] = \"blur\"; // touch events\n\n G6Event[\"TOUCHSTART\"] = \"touchstart\";\n G6Event[\"TOUCHMOVE\"] = \"touchmove\";\n G6Event[\"TOUCHEND\"] = \"touchend\";\n G6Event[\"CANVAS_TOUCHSTART\"] = \"canvas:touchstart\";\n G6Event[\"CANVAS_TOUCHMOVE\"] = \"canvas:touchmove\";\n G6Event[\"CANVAS_TOUCHEND\"] = \"canvas:touchend\";\n G6Event[\"NODE_TOUCHSTART\"] = \"node:touchstart\";\n G6Event[\"NODE_TOUCHMOVE\"] = \"node:touchmove\";\n G6Event[\"NODE_TOUCHEND\"] = \"node:touchend\";\n G6Event[\"COMBO_TOUCHSTART\"] = \"combo:touchstart\";\n G6Event[\"COMBO_TOUCHMOVE\"] = \"combo:touchmove\";\n G6Event[\"COMBO_TOUCHEND\"] = \"combo:touchend\";\n G6Event[\"EDGE_TOUCHSTART\"] = \"edge:touchstart\";\n G6Event[\"EDGE_TOUCHMOVE\"] = \"edge:touchmove\";\n G6Event[\"EDGE_TOUCHEND\"] = \"edge:touchend\"; // node events\n\n G6Event[\"NODE_CONTEXTMENU\"] = \"node:contextmenu\";\n G6Event[\"NODE_CLICK\"] = \"node:click\";\n G6Event[\"NODE_DBLCLICK\"] = \"node:dblclick\";\n G6Event[\"NODE_MOUSEDOWN\"] = \"node:mousedown\";\n G6Event[\"NODE_MOUSEUP\"] = \"node:mouseup\";\n G6Event[\"NODE_MOUSEENTER\"] = \"node:mouseenter\";\n G6Event[\"NODE_MOUSELEAVE\"] = \"node:mouseleave\";\n G6Event[\"NODE_MOUSEMOVE\"] = \"node:mousemove\";\n G6Event[\"NODE_MOUSEOUT\"] = \"node:mouseout\";\n G6Event[\"NODE_MOUSEOVER\"] = \"node:mouseover\";\n G6Event[\"NODE_DROP\"] = \"node:drop\";\n G6Event[\"NODE_DRAGOVER\"] = \"node:dragover\";\n G6Event[\"NODE_DRAGENTER\"] = \"node:dragenter\";\n G6Event[\"NODE_DRAGLEAVE\"] = \"node:dragleave\";\n G6Event[\"NODE_DRAGSTART\"] = \"node:dragstart\";\n G6Event[\"NODE_DRAG\"] = \"node:drag\";\n G6Event[\"NODE_DRAGEND\"] = \"node:dragend\";\n G6Event[\"NODE_TAP\"] = \"node:tap\";\n G6Event[\"NODE_PANSTART\"] = \"node:panstart\";\n G6Event[\"NODE_PANMOVE\"] = \"node:panmove\";\n G6Event[\"NODE_PANEND\"] = \"node:panend\"; // combo, extends from nodes\n\n G6Event[\"COMBO_CONTEXTMENU\"] = \"combo:contextmenu\";\n G6Event[\"COMBO_CLICK\"] = \"combo:click\";\n G6Event[\"COMBO_DBLCLICK\"] = \"combo:dblclick\";\n G6Event[\"COMBO_MOUSEDOWN\"] = \"combo:mousedown\";\n G6Event[\"COMBO_MOUSEUP\"] = \"combo:mouseup\";\n G6Event[\"COMBO_MOUSEENTER\"] = \"combo:mouseenter\";\n G6Event[\"COMBO_MOUSELEAVE\"] = \"combo:mouseleave\";\n G6Event[\"COMBO_MOUSEMOVE\"] = \"combo:mousemove\";\n G6Event[\"COMBO_MOUSEOUT\"] = \"combo:mouseout\";\n G6Event[\"COMBO_MOUSEOVER\"] = \"combo:mouseover\";\n G6Event[\"COMBO_DROP\"] = \"combo:drop\";\n G6Event[\"COMBO_DRAGOVER\"] = \"combo:dragover\";\n G6Event[\"COMBO_DRAGENTER\"] = \"combo:dragenter\";\n G6Event[\"COMBO_DRAGLEAVE\"] = \"combo:dragleave\";\n G6Event[\"COMBO_DRAGSTART\"] = \"combo:dragstart\";\n G6Event[\"COMBO_DRAG\"] = \"combo:drag\";\n G6Event[\"COMBO_DRAGEND\"] = \"combo:dragend\";\n G6Event[\"COMBO_TAP\"] = \"combo:tap\";\n G6Event[\"COMBO_PANSTART\"] = \"combo:panstart\";\n G6Event[\"COMBO_PANMOVE\"] = \"combo:panmove\";\n G6Event[\"COMBO_PANEND\"] = \"combo:panend\"; // edge events\n\n G6Event[\"EDGE_CONTEXTMENU\"] = \"edge:contextmenu\";\n G6Event[\"EDGE_CLICK\"] = \"edge:click\";\n G6Event[\"EDGE_DBLCLICK\"] = \"edge:dblclick\";\n G6Event[\"EDGE_MOUSEDOWN\"] = \"edge:mousedown\";\n G6Event[\"EDGE_MOUSEUP\"] = \"edge:mouseup\";\n G6Event[\"EDGE_MOUSEENTER\"] = \"edge:mouseenter\";\n G6Event[\"EDGE_MOUSELEAVE\"] = \"edge:mouseleave\";\n G6Event[\"EDGE_MOUSEMOVE\"] = \"edge:mousemove\";\n G6Event[\"EDGE_MOUSEOUT\"] = \"edge:mouseout\";\n G6Event[\"EDGE_MOUSEOVER\"] = \"edge:mouseover\";\n G6Event[\"EDGE_DROP\"] = \"edge:drop\";\n G6Event[\"EDGE_DRAGOVER\"] = \"edge:dragover\";\n G6Event[\"EDGE_DRAGENTER\"] = \"edge:dragenter\";\n G6Event[\"EDGE_DRAGLEAVE\"] = \"edge:dragleave\"; // canvas events\n\n G6Event[\"CANVAS_CONTEXTMENU\"] = \"canvas:contextmenu\";\n G6Event[\"CANVAS_CLICK\"] = \"canvas:click\";\n G6Event[\"CANVAS_DBLCLICK\"] = \"canvas:dblclick\";\n G6Event[\"CANVAS_MOUSEDOWN\"] = \"canvas:mousedown\";\n G6Event[\"CANVAS_MOUSEUP\"] = \"canvas:mouseup\";\n G6Event[\"CANVAS_MOUSEENTER\"] = \"canvas:mouseenter\";\n G6Event[\"CANVAS_MOUSELEAVE\"] = \"canvas:mouseleave\";\n G6Event[\"CANVAS_MOUSEMOVE\"] = \"canvas:mousemove\";\n G6Event[\"CANVAS_MOUSEOUT\"] = \"canvas:mouseout\";\n G6Event[\"CANVAS_MOUSEOVER\"] = \"canvas:mouseover\";\n G6Event[\"CANVAS_DROP\"] = \"canvas:drop\";\n G6Event[\"CANVAS_DRAGENTER\"] = \"canvas:dragenter\";\n G6Event[\"CANVAS_DRAGLEAVE\"] = \"canvas:dragleave\";\n G6Event[\"CANVAS_DRAGSTART\"] = \"canvas:dragstart\";\n G6Event[\"CANVAS_DRAG\"] = \"canvas:drag\";\n G6Event[\"CANVAS_DRAGEND\"] = \"canvas:dragend\";\n G6Event[\"CANVAS_TAP\"] = \"canvas:tap\";\n G6Event[\"CANVAS_PANSTART\"] = \"canvas:panstart\";\n G6Event[\"CANVAS_PANMOVE\"] = \"canvas:panmove\";\n G6Event[\"CANVAS_PANEND\"] = \"canvas:panend\"; // timing events\n\n G6Event[\"BEFORERENDER\"] = \"beforerender\";\n G6Event[\"AFTERRENDER\"] = \"afterrender\";\n G6Event[\"BEFOREADDITEM\"] = \"beforeadditem\";\n G6Event[\"AFTERADDITEM\"] = \"afteradditem\";\n G6Event[\"BEFOREREMOVEITEM\"] = \"beforeremoveitem\";\n G6Event[\"AFTERREMOVEITEM\"] = \"afterremoveitem\";\n G6Event[\"BEFOREUPDATEITEM\"] = \"beforeupdateitem\";\n G6Event[\"AFTERUPDATEITEM\"] = \"afterupdateitem\";\n G6Event[\"BEFOREITEMVISIBILITYCHANGE\"] = \"beforeitemvisibilitychange\";\n G6Event[\"AFTERITEMVISIBILITYCHANGE\"] = \"afteritemvisibilitychange\";\n G6Event[\"BEFOREITEMSTATECHANGE\"] = \"beforeitemstatechange\";\n G6Event[\"AFTERITEMSTATECHANGE\"] = \"afteritemstatechange\";\n G6Event[\"BEFOREITEMREFRESH\"] = \"beforeitemrefresh\";\n G6Event[\"AFTERITEMREFRESH\"] = \"afteritemrefresh\";\n G6Event[\"BEFOREITEMSTATESCLEAR\"] = \"beforeitemstatesclear\";\n G6Event[\"AFTERITEMSTATESCLEAR\"] = \"afteritemstatesclear\";\n G6Event[\"BEFOREMODECHANGE\"] = \"beforemodechange\";\n G6Event[\"AFTERMODECHANGE\"] = \"aftermodechange\";\n G6Event[\"BEFORELAYOUT\"] = \"beforelayout\";\n G6Event[\"AFTERLAYOUT\"] = \"afterlayout\";\n G6Event[\"BEFORECREATEEDGE\"] = \"beforecreateedge\";\n G6Event[\"AFTERCREATEEDGE\"] = \"aftercreateedge\";\n G6Event[\"BEFOREGRAPHREFRESHPOSITION\"] = \"beforegraphrefreshposition\";\n G6Event[\"AFTERGRAPHREFRESHPOSITION\"] = \"aftergraphrefreshposition\";\n G6Event[\"BEFOREGRAPHREFRESH\"] = \"beforegraphrefresh\";\n G6Event[\"AFTERGRAPHREFRESH\"] = \"aftergraphrefresh\";\n G6Event[\"BEFOREANIMATE\"] = \"beforeanimate\";\n G6Event[\"AFTERANIMATE\"] = \"afteranimate\";\n G6Event[\"BEFOREPAINT\"] = \"beforepaint\";\n G6Event[\"AFTERPAINT\"] = \"afterpaint\";\n G6Event[\"BEFORECOLLAPSEEXPANDCOMBO\"] = \"beforecollapseexpandcombo\";\n G6Event[\"AFTERCOLLAPSEEXPANDCOMBO\"] = \"aftercollapseexpandcombo\";\n G6Event[\"GRAPHSTATECHANGE\"] = \"graphstatechange\";\n G6Event[\"AFTERACTIVATERELATIONS\"] = \"afteractivaterelations\";\n G6Event[\"NODESELECTCHANGE\"] = \"nodeselectchange\";\n G6Event[\"TOOLTIPCHANGE\"] = \"tooltipchange\";\n G6Event[\"WHEELZOOM\"] = \"wheelzoom\";\n G6Event[\"VIEWPORTCHANGE\"] = \"viewportchange\";\n G6Event[\"DRAGNODEEND\"] = \"dragnodeend\";\n G6Event[\"STACKCHANGE\"] = \"stackchange\"; // Mobile event support\n\n G6Event[\"TAP\"] = \"tap\";\n G6Event[\"PINCHSTART\"] = \"pinchstart\";\n G6Event[\"PINCHMOVE\"] = \"pinchmove\";\n G6Event[\"PANSTART\"] = \"panstart\";\n G6Event[\"PANMOVE\"] = \"panmove\";\n G6Event[\"PANEND\"] = \"panend\";\n})(G6Event || (G6Event = {}));\n// CONCATENATED MODULE: ./node_modules/@antv/g6-core/es/index.js\n\n\n\n\n // 用于 PC 和 Mobile 端分别实现 layout 和 updateLayoutCfg 方法\n\n\n\n\n\n\n\nvar registerNode = es_element.registerNode;\nvar registerEdge = es_element.registerEdge;\nvar registerCombo = es_element.registerCombo;\nvar registerBehavior = es_behavior.registerBehavior;\nvar BaseGlobal = global;\n\n\n/* harmony default export */ var g6_core_es = ({\n version: global.version,\n AbstractGraph: graph_graph,\n BaseGlobal: BaseGlobal,\n Util: util,\n Shape: es_element,\n Node: item_node,\n Edge: item_edge,\n Combo: item_combo,\n Hull: item_hull,\n registerNode: es_element.registerNode,\n registerEdge: es_element.registerEdge,\n registerCombo: es_element.registerCombo,\n registerBehavior: es_behavior.registerBehavior,\n Arrow: element_arrow,\n Marker: marker,\n AbstractLayout: controller_layout,\n AbstractEvent: controller_event\n});\n// EXTERNAL MODULE: ./node_modules/@antv/algorithm/lib/asyncIndex.js\nvar asyncIndex = __webpack_require__(281);\n\n// EXTERNAL MODULE: ./node_modules/@antv/g-canvas/esm/index.js\nvar g_canvas_esm = __webpack_require__(44);\n\n// EXTERNAL MODULE: ./node_modules/@antv/g-svg/esm/index.js\nvar g_svg_esm = __webpack_require__(62);\n\n// EXTERNAL MODULE: ./node_modules/color/index.js\nvar node_modules_color = __webpack_require__(85);\nvar color_default = /*#__PURE__*/__webpack_require__.n(node_modules_color);\n\n// EXTERNAL MODULE: ./node_modules/tinycolor2/tinycolor.js\nvar tinycolor = __webpack_require__(94);\nvar tinycolor_default = /*#__PURE__*/__webpack_require__.n(tinycolor);\n\n// CONCATENATED MODULE: ./node_modules/@ant-design/colors/dist/index.esm.js\n\n\nvar hueStep = 2; // 色相阶梯\n\nvar saturationStep = 0.16; // 饱和度阶梯,浅色部分\n\nvar saturationStep2 = 0.05; // 饱和度阶梯,深色部分\n\nvar brightnessStep1 = 0.05; // 亮度阶梯,浅色部分\n\nvar brightnessStep2 = 0.15; // 亮度阶梯,深色部分\n\nvar lightColorCount = 5; // 浅色数量,主色上\n\nvar darkColorCount = 4; // 深色数量,主色下\n// 暗色主题颜色映射关系表\n\nvar darkColorMap = [{\n index: 7,\n opacity: 0.15\n}, {\n index: 6,\n opacity: 0.25\n}, {\n index: 5,\n opacity: 0.3\n}, {\n index: 5,\n opacity: 0.45\n}, {\n index: 5,\n opacity: 0.65\n}, {\n index: 5,\n opacity: 0.85\n}, {\n index: 4,\n opacity: 0.9\n}, {\n index: 3,\n opacity: 0.95\n}, {\n index: 2,\n opacity: 0.97\n}, {\n index: 1,\n opacity: 0.98\n}];\n\nfunction getHue(hsv, i, light) {\n var hue; // 根据色相不同,色相转向不同\n\n if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) {\n hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i;\n } else {\n hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i;\n }\n\n if (hue < 0) {\n hue += 360;\n } else if (hue >= 360) {\n hue -= 360;\n }\n\n return hue;\n}\n\nfunction getSaturation(hsv, i, light) {\n // grey color don't change saturation\n if (hsv.h === 0 && hsv.s === 0) {\n return hsv.s;\n }\n\n var saturation;\n\n if (light) {\n saturation = hsv.s - saturationStep * i;\n } else if (i === darkColorCount) {\n saturation = hsv.s + saturationStep;\n } else {\n saturation = hsv.s + saturationStep2 * i;\n } // 边界值修正\n\n\n if (saturation > 1) {\n saturation = 1;\n } // 第一格的 s 限制在 0.06-0.1 之间\n\n\n if (light && i === lightColorCount && saturation > 0.1) {\n saturation = 0.1;\n }\n\n if (saturation < 0.06) {\n saturation = 0.06;\n }\n\n return Number(saturation.toFixed(2));\n}\n\nfunction getValue(hsv, i, light) {\n var value;\n\n if (light) {\n value = hsv.v + brightnessStep1 * i;\n } else {\n value = hsv.v - brightnessStep2 * i;\n }\n\n if (value > 1) {\n value = 1;\n }\n\n return Number(value.toFixed(2));\n}\n\nfunction generate(color) {\n var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var patterns = [];\n var pColor = tinycolor_default()(color);\n\n for (var i = lightColorCount; i > 0; i -= 1) {\n var hsv = pColor.toHsv();\n var colorString = tinycolor_default()({\n h: getHue(hsv, i, true),\n s: getSaturation(hsv, i, true),\n v: getValue(hsv, i, true)\n }).toHexString();\n patterns.push(colorString);\n }\n\n patterns.push(pColor.toHexString());\n\n for (var _i = 1; _i <= darkColorCount; _i += 1) {\n var _hsv = pColor.toHsv();\n\n var _colorString = tinycolor_default()({\n h: getHue(_hsv, _i),\n s: getSaturation(_hsv, _i),\n v: getValue(_hsv, _i)\n }).toHexString();\n\n patterns.push(_colorString);\n } // dark theme patterns\n\n\n if (opts.theme === 'dark') {\n return darkColorMap.map(function (_ref) {\n var index = _ref.index,\n opacity = _ref.opacity;\n var darkColorString = tinycolor_default.a.mix(opts.backgroundColor || '#141414', patterns[index], opacity * 100).toHexString();\n return darkColorString;\n });\n }\n\n return patterns;\n}\n\nvar presetPrimaryColors = {\n red: '#F5222D',\n volcano: '#FA541C',\n orange: '#FA8C16',\n gold: '#FAAD14',\n yellow: '#FADB14',\n lime: '#A0D911',\n green: '#52C41A',\n cyan: '#13C2C2',\n blue: '#1890FF',\n geekblue: '#2F54EB',\n purple: '#722ED1',\n magenta: '#EB2F96',\n grey: '#666666'\n};\nvar presetPalettes = {};\nvar presetDarkPalettes = {};\nObject.keys(presetPrimaryColors).forEach(function (key) {\n presetPalettes[key] = generate(presetPrimaryColors[key]);\n presetPalettes[key].primary = presetPalettes[key][5]; // dark presetPalettes\n\n presetDarkPalettes[key] = generate(presetPrimaryColors[key], {\n theme: 'dark',\n backgroundColor: '#141414'\n });\n presetDarkPalettes[key].primary = presetDarkPalettes[key][5];\n});\nvar red = presetPalettes.red;\nvar volcano = presetPalettes.volcano;\nvar gold = presetPalettes.gold;\nvar orange = presetPalettes.orange;\nvar yellow = presetPalettes.yellow;\nvar lime = presetPalettes.lime;\nvar green = presetPalettes.green;\nvar cyan = presetPalettes.cyan;\nvar blue = presetPalettes.blue;\nvar geekblue = presetPalettes.geekblue;\nvar purple = presetPalettes.purple;\nvar magenta = presetPalettes.magenta;\nvar grey = presetPalettes.grey;\n\n\n\n// CONCATENATED MODULE: ./node_modules/@antv/g6-pc/es/util/color.js\n\n\n/**\n * get the mix color of backColor and frontColor with alpah\n * @param backColor background color\n * @param frontColor foreground color\n * @param frontAlpha the opacity of foreground color\n */\n\nvar color_mixColor = function mixColor(backColor, frontColor, frontAlpha) {\n var bc = color_default()(backColor);\n var fc = color_default()(frontColor);\n return color_default()([(1 - frontAlpha) * bc.red() + frontAlpha * fc.red(), (1 - frontAlpha) * bc.green() + frontAlpha * fc.green(), (1 - frontAlpha) * bc.blue() + frontAlpha * fc.blue()]).rgb();\n};\n\nvar color_getColorsWithDefaultTheme = function getColorsWithDefaultTheme(subjectColor, backColor, disableColor) {\n if (backColor === void 0) {\n backColor = '#fff';\n }\n\n if (disableColor === void 0) {\n disableColor = 'rgb(150, 150, 150)';\n }\n\n var subjectColor005 = color_mixColor(backColor, subjectColor, 0.05).rgb().toString();\n var subjectColor01 = color_mixColor(backColor, subjectColor, 0.1).rgb().toString();\n var subjectColor02 = color_mixColor(backColor, subjectColor, 0.2).rgb().toString();\n var subjectColor04 = color_mixColor(backColor, subjectColor, 0.4).rgb().toString();\n var disableColor002 = color_mixColor(backColor, disableColor, 0.02).rgb().toString();\n var disableColor005 = color_mixColor(backColor, disableColor, 0.05).rgb().toString();\n var disableColor01 = color_mixColor(backColor, disableColor, 0.1).rgb().toString();\n var disableColor02 = color_mixColor(backColor, disableColor, 0.2).rgb().toString();\n var disableColor03 = color_mixColor(backColor, disableColor, 0.3).rgb().toString();\n var paletteFromSubject = generate(subjectColor, {\n theme: 'default',\n backgroundColor: backColor\n });\n var subjectHex = color_default()(subjectColor).hex().toLowerCase();\n var subjectIdx = paletteFromSubject.indexOf(subjectHex);\n var deeperSubject = subjectColor;\n\n if (subjectIdx !== -1) {\n deeperSubject = paletteFromSubject[subjectIdx + 1];\n }\n\n return {\n // for nodes\n mainStroke: subjectColor,\n mainFill: subjectColor01,\n activeStroke: subjectColor,\n activeFill: subjectColor005,\n inactiveStroke: subjectColor04,\n inactiveFill: subjectColor005,\n selectedStroke: subjectColor,\n selectedFill: backColor,\n highlightStroke: deeperSubject,\n highlightFill: subjectColor02,\n disableStroke: disableColor03,\n disableFill: disableColor005,\n // for edges\n edgeMainStroke: disableColor03,\n edgeActiveStroke: subjectColor,\n edgeInactiveStroke: disableColor02,\n edgeSelectedStroke: subjectColor,\n edgeHighlightStroke: subjectColor,\n edgeDisableStroke: disableColor01,\n // for combos\n comboMainStroke: disableColor03,\n comboMainFill: disableColor002,\n comboActiveStroke: subjectColor,\n comboActiveFill: subjectColor005,\n comboInactiveStroke: disableColor03,\n comboInactiveFill: disableColor002,\n comboSelectedStroke: subjectColor,\n comboSelectedFill: disableColor002,\n comboHighlightStroke: deeperSubject,\n comboHighlightFill: disableColor002,\n comboDisableStroke: disableColor02,\n comboDisableFill: disableColor005\n };\n};\n\nvar color_getColorsWithDarkTheme = function getColorsWithDarkTheme(subjectColor, backColor, disableColor) {\n if (backColor === void 0) {\n backColor = '#fff';\n }\n\n if (disableColor === void 0) {\n disableColor = '#777';\n }\n\n var subjectColor02 = color_mixColor(backColor, subjectColor, 0.2).rgb().toString();\n var subjectColor03 = color_mixColor(backColor, subjectColor, 0.3).rgb().toString();\n var subjectColor06 = color_mixColor(backColor, subjectColor, 0.6).rgb().toString();\n var subjectColor08 = color_mixColor(backColor, subjectColor, 0.8).rgb().toString();\n var disableColor02 = color_mixColor(backColor, disableColor, 0.2).rgb().toString();\n var disableColor025 = color_mixColor(backColor, disableColor, 0.25).rgb().toString();\n var disableColor03 = color_mixColor(backColor, disableColor, 0.3).rgb().toString();\n var disableColor04 = color_mixColor(backColor, disableColor, 0.4).rgb().toString();\n var disableColor05 = color_mixColor(backColor, disableColor, 0.5).rgb().toString();\n var paletteFromSubject = generate(subjectColor, {\n theme: 'dark',\n backgroundColor: backColor\n });\n var subjectHex = color_default()(subjectColor).hex().toLowerCase();\n var subjectIdx = paletteFromSubject.indexOf(subjectHex);\n var deeperSubject = subjectColor;\n\n if (subjectIdx !== -1) {\n deeperSubject = paletteFromSubject[subjectIdx + 1];\n }\n\n return {\n // for nodes\n mainStroke: subjectColor08,\n mainFill: subjectColor02,\n activeStroke: subjectColor,\n activeFill: subjectColor03,\n inactiveStroke: subjectColor08,\n inactiveFill: subjectColor02,\n selectedStroke: subjectColor,\n selectedFill: subjectColor02,\n highlightStroke: subjectColor,\n highlightFill: subjectColor06,\n disableStroke: disableColor05,\n disableFill: disableColor025,\n // for edges\n edgeMainStroke: disableColor,\n edgeActiveStroke: subjectColor,\n edgeInactiveStroke: disableColor,\n edgeSelectedStroke: subjectColor,\n edgeHighlightStroke: subjectColor,\n edgeDisableStroke: disableColor03,\n // for combos\n comboMainStroke: disableColor04,\n comboMainFill: disableColor025,\n comboActiveStroke: subjectColor,\n comboActiveFill: disableColor02,\n comboInactiveStroke: disableColor04,\n comboInactiveFill: disableColor025,\n comboSelectedStroke: subjectColor,\n comboSelectedFill: disableColor02,\n comboHighlightStroke: deeperSubject,\n comboHighlightFill: disableColor025,\n comboDisableStroke: disableColor04,\n comboDisableFill: disableColor02\n };\n};\n/**\n * get the set of colors according to the subject color and background color\n * @param subjectColor the subject color\n * @param backColor background color\n * @param disableColor the color for disable state\n */\n\n\nvar getColorsWithSubjectColor = function getColorsWithSubjectColor(subjectColor, backColor, theme, disableColor) {\n if (backColor === void 0) {\n backColor = '#fff';\n }\n\n if (theme === void 0) {\n theme = 'default';\n }\n\n if (disableColor === void 0) {\n disableColor = 'rgb(150, 150, 150)';\n }\n\n if (theme === 'default') return color_getColorsWithDefaultTheme(subjectColor, backColor, 'rgb(150, 150, 150)');\n return color_getColorsWithDarkTheme(subjectColor, backColor, '#777');\n};\nvar getColorSetsBySubjectColors = function getColorSetsBySubjectColors(subjectColors, backColor, theme, disableColor) {\n if (backColor === void 0) {\n backColor = '#fff';\n }\n\n if (theme === void 0) {\n theme = 'default';\n }\n\n if (disableColor === void 0) {\n disableColor = 'rgb(150, 150, 150)';\n }\n\n var sets = [];\n subjectColors.forEach(function (sColor) {\n sets.push(getColorsWithSubjectColor(sColor, backColor, theme, disableColor));\n });\n return sets;\n};\n// CONCATENATED MODULE: ./node_modules/@antv/g6-pc/es/global.js\n\nvar es_global_subjectColor = 'rgb(95, 149, 255)';\nvar es_global_backColor = 'rgb(255, 255, 255)';\nvar es_global_textColor = 'rgb(0, 0, 0)';\nvar global_colorSet = getColorsWithSubjectColor(es_global_subjectColor, es_global_backColor);\n/* harmony default export */ var es_global = ({\n version: '0.4.1',\n rootContainerClassName: 'root-container',\n nodeContainerClassName: 'node-container',\n edgeContainerClassName: 'edge-container',\n comboContainerClassName: 'combo-container',\n delegateContainerClassName: 'delegate-container',\n defaultLoopPosition: 'top',\n nodeLabel: {\n style: {\n fill: '#000',\n fontSize: 12,\n textAlign: 'center',\n textBaseline: 'middle'\n },\n offset: 4 // 节点的默认文本不居中时的偏移量\n\n },\n defaultNode: {\n type: 'circle',\n style: {\n lineWidth: 1,\n stroke: global_colorSet.mainStroke,\n fill: global_colorSet.mainFill\n },\n size: 20,\n color: global_colorSet.mainStroke,\n linkPoints: {\n size: 8,\n lineWidth: 1,\n fill: global_colorSet.activeFill,\n stroke: global_colorSet.activeStroke\n }\n },\n // 节点应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展\n nodeStateStyles: {\n active: {\n fill: global_colorSet.activeFill,\n stroke: global_colorSet.activeStroke,\n lineWidth: 2,\n shadowColor: global_colorSet.mainStroke,\n shadowBlur: 10\n },\n selected: {\n fill: global_colorSet.selectedFill,\n stroke: global_colorSet.selectedStroke,\n lineWidth: 4,\n shadowColor: global_colorSet.selectedStroke,\n shadowBlur: 10,\n 'text-shape': {\n fontWeight: 500\n }\n },\n highlight: {\n fill: global_colorSet.highlightFill,\n stroke: global_colorSet.highlightStroke,\n lineWidth: 2,\n 'text-shape': {\n fontWeight: 500\n }\n },\n inactive: {\n fill: global_colorSet.inactiveFill,\n stroke: global_colorSet.inactiveStroke,\n lineWidth: 1\n },\n disable: {\n fill: global_colorSet.disableFill,\n stroke: global_colorSet.disableStroke,\n lineWidth: 1\n }\n },\n edgeLabel: {\n style: {\n fill: es_global_textColor,\n textAlign: 'center',\n textBaseline: 'middle',\n fontSize: 12\n }\n },\n defaultEdge: {\n type: 'line',\n size: 1,\n style: {\n stroke: global_colorSet.edgeMainStroke,\n lineAppendWidth: 2\n },\n color: global_colorSet.edgeMainStroke\n },\n // 边应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展\n edgeStateStyles: {\n active: {\n stroke: global_colorSet.edgeActiveStroke,\n lineWidth: 1\n },\n selected: {\n stroke: global_colorSet.edgeSelectedStroke,\n lineWidth: 2,\n shadowColor: global_colorSet.edgeSelectedStroke,\n shadowBlur: 10,\n 'text-shape': {\n fontWeight: 500\n }\n },\n highlight: {\n stroke: global_colorSet.edgeHighlightStroke,\n lineWidth: 2,\n 'text-shape': {\n fontWeight: 500\n }\n },\n inactive: {\n stroke: global_colorSet.edgeInactiveStroke,\n lineWidth: 1\n },\n disable: {\n stroke: global_colorSet.edgeDisableStroke,\n lineWidth: 1\n }\n },\n comboLabel: {\n style: {\n fill: es_global_textColor,\n // textAlign: 'center',\n textBaseline: 'middle',\n fontSize: 12\n },\n refY: 10,\n refX: 10 // Combo 的默认文本不居中时的偏移量\n\n },\n defaultCombo: {\n type: 'circle',\n style: {\n fill: global_colorSet.comboMainFill,\n lineWidth: 1,\n stroke: global_colorSet.comboMainStroke,\n r: 5,\n width: 20,\n height: 10\n },\n size: [20, 5],\n color: global_colorSet.comboMainStroke,\n padding: [25, 20, 15, 20]\n },\n // combo 应用状态后的样式,默认仅提供 active、selected、highlight、inactive、disable,用户可以自己扩展\n comboStateStyles: {\n active: {\n stroke: global_colorSet.comboActiveStroke,\n lineWidth: 1,\n fill: global_colorSet.comboActiveFill\n },\n selected: {\n stroke: global_colorSet.comboSelectedStroke,\n lineWidth: 2,\n fill: global_colorSet.comboSelectedFill,\n shadowColor: global_colorSet.comboSelectedStroke,\n shadowBlur: 10,\n 'text-shape': {\n fontWeight: 500\n }\n },\n highlight: {\n stroke: global_colorSet.comboHighlightStroke,\n lineWidth: 2,\n fill: global_colorSet.comboHighlightFill,\n 'text-shape': {\n fontWeight: 500\n }\n },\n inactive: {\n stroke: global_colorSet.comboInactiveStroke,\n fill: global_colorSet.comboInactiveFill,\n lineWidth: 1\n },\n disable: {\n stroke: global_colorSet.comboDisableStroke,\n fill: global_colorSet.comboDisableFill,\n lineWidth: 1\n }\n },\n delegateStyle: {\n fill: '#F3F9FF',\n fillOpacity: 0.5,\n stroke: '#1890FF',\n strokeOpacity: 0.9,\n lineDash: [5, 5]\n },\n // 文本水印默认配置\n textWaterMarkerConfig: {\n width: 150,\n height: 100,\n compatible: false,\n text: {\n x: 0,\n y: 60,\n lineHeight: 20,\n rotate: 20,\n fontSize: 14,\n fontFamily: 'Microsoft YaHei',\n fill: 'rgba(0, 0, 0, 0.1)',\n baseline: 'Middle'\n }\n },\n imageWaterMarkerConfig: {\n width: 150,\n height: 130,\n compatible: false,\n image: {\n x: 0,\n y: 0,\n width: 30,\n height: 20,\n rotate: 0\n }\n },\n waterMarkerImage: 'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'\n});\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/add-event-listener.js\nfunction addEventListener(target, eventType, callback) {\n if (target) {\n if (typeof target.addEventListener === 'function') {\n target.addEventListener(eventType, callback, false);\n return {\n remove: function () {\n target.removeEventListener(eventType, callback, false);\n },\n };\n // @ts-ignore\n }\n if (typeof target.attachEvent === 'function') {\n // @ts-ignore\n target.attachEvent('on' + eventType, callback);\n return {\n remove: function () {\n // @ts-ignore\n target.detachEvent('on' + eventType, callback);\n },\n };\n }\n }\n}\n//# sourceMappingURL=add-event-listener.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/create-dom.js\n/**\n * 创建DOM 节点\n * @param {String} str Dom 字符串\n * @return {HTMLElement} DOM 节点\n */\nvar TABLE;\nvar TABLE_TR;\nvar FRAGMENT_REG;\nvar CONTAINERS;\nfunction initConstants() {\n TABLE = document.createElement('table');\n TABLE_TR = document.createElement('tr');\n FRAGMENT_REG = /^\\s*<(\\w+|!)[^>]*>/;\n CONTAINERS = {\n tr: document.createElement('tbody'),\n tbody: TABLE,\n thead: TABLE,\n tfoot: TABLE,\n td: TABLE_TR,\n th: TABLE_TR,\n '*': document.createElement('div'),\n };\n}\nfunction createDom(str) {\n if (!TABLE) {\n initConstants();\n }\n var name = FRAGMENT_REG.test(str) && RegExp.$1;\n if (!name || !(name in CONTAINERS)) {\n name = '*';\n }\n var container = CONTAINERS[name];\n str = str.replace(/(^\\s*)|(\\s*$)/g, '');\n container.innerHTML = '' + str;\n var dom = container.childNodes[0];\n container.removeChild(dom);\n return dom;\n}\n//# sourceMappingURL=create-dom.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/get-style.js\n/**\n * 获取样式\n * @param {Object} dom DOM节点\n * @param {String} name 样式名\n * @param {Any} defaultValue 默认值\n * @return {String} 属性值\n */\nfunction getStyle(dom, name, defaultValue) {\n var v;\n try {\n v = window.getComputedStyle ?\n window.getComputedStyle(dom, null)[name] :\n dom.style[name]; // 一般不会走到这个逻辑,dom.style 获取的是标签 style 属性,也不准确\n }\n catch (e) {\n // do nothing\n }\n finally {\n v = v === undefined ? defaultValue : v;\n }\n return v;\n}\n//# sourceMappingURL=get-style.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/get-height.js\n\nfunction getHeight(el, defaultValue) {\n var height = getStyle(el, 'height', defaultValue);\n if (height === 'auto') {\n height = el.offsetHeight;\n }\n return parseFloat(height);\n}\n//# sourceMappingURL=get-height.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/get-outer-height.js\n\n\nfunction getOuterHeight(el, defaultValue) {\n var height = getHeight(el, defaultValue);\n var bTop = parseFloat(getStyle(el, 'borderTopWidth')) || 0;\n var pTop = parseFloat(getStyle(el, 'paddingTop')) || 0;\n var pBottom = parseFloat(getStyle(el, 'paddingBottom')) || 0;\n var bBottom = parseFloat(getStyle(el, 'borderBottomWidth')) || 0;\n var mTop = parseFloat(getStyle(el, 'marginTop')) || 0;\n var mBottom = parseFloat(getStyle(el, 'marginBottom')) || 0;\n return height + bTop + bBottom + pTop + pBottom + mTop + mBottom;\n}\n//# sourceMappingURL=get-outer-height.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/get-width.js\n\nfunction get_width_getHeight(el, defaultValue) {\n var width = getStyle(el, 'width', defaultValue);\n if (width === 'auto') {\n width = el.offsetWidth;\n }\n return parseFloat(width);\n}\n//# sourceMappingURL=get-width.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/get-outer-width.js\n\n\nfunction getOuterWidth(el, defaultValue) {\n var width = get_width_getHeight(el, defaultValue);\n var bLeft = parseFloat(getStyle(el, 'borderLeftWidth')) || 0;\n var pLeft = parseFloat(getStyle(el, 'paddingLeft')) || 0;\n var pRight = parseFloat(getStyle(el, 'paddingRight')) || 0;\n var bRight = parseFloat(getStyle(el, 'borderRightWidth')) || 0;\n var mRight = parseFloat(getStyle(el, 'marginRight')) || 0;\n var mLeft = parseFloat(getStyle(el, 'marginLeft')) || 0;\n return width + bLeft + bRight + pLeft + pRight + mLeft + mRight;\n}\n//# sourceMappingURL=get-outer-width.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/get-ratio.js\nfunction getRatio() {\n return window.devicePixelRatio ? window.devicePixelRatio : 2;\n}\n//# sourceMappingURL=get-ratio.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/modify-css.js\nfunction modifyCSS(dom, css) {\n if (dom) {\n for (var key in css) {\n if (css.hasOwnProperty(key)) {\n dom.style[key] = css[key];\n }\n }\n }\n return dom;\n}\n//# sourceMappingURL=modify-css.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/dom-util/esm/index.js\n// dom\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n// CONCATENATED MODULE: ./node_modules/@antv/g6-pc/es/graph/controller/event.js\n\n\n\n\nvar event_cloneEvent = util.cloneEvent,\n event_isViewportChanged = util.isViewportChanged;\n\nvar controller_event_EventController =\n/** @class */\nfunction (_super) {\n Object(tslib_es6[\"__extends\"])(EventController, _super);\n\n function EventController(graph) {\n var _this = _super.call(this, graph) || this;\n\n _this.extendEvents = [];\n _this.dragging = false;\n _this.preItem = null;\n _this.graph = graph;\n _this.destroyed = false;\n\n _this.initEvents();\n\n return _this;\n } // 初始化 G6 中的事件\n\n\n EventController.prototype.initEvents = function () {\n var _a = this,\n graph = _a.graph,\n _b = _a.extendEvents,\n extendEvents = _b === void 0 ? [] : _b;\n\n var canvas = graph.get('canvas'); // canvas.set('draggable', true);\n\n var el = canvas.get('el');\n var canvasHandler = Object(esm[\"wrapBehavior\"])(this, 'onCanvasEvents');\n var originHandler = Object(esm[\"wrapBehavior\"])(this, 'onExtendEvents');\n var wheelHandler = Object(esm[\"wrapBehavior\"])(this, 'onWheelEvent'); // each(EVENTS, event => {\n // canvas.off(event).on(event, canvasHandler);\n // });\n\n canvas.off('*').on('*', canvasHandler);\n this.canvasHandler = canvasHandler;\n extendEvents.push(addEventListener(el, 'DOMMouseScroll', wheelHandler));\n extendEvents.push(addEventListener(el, 'mousewheel', wheelHandler));\n\n if (typeof window !== 'undefined') {\n extendEvents.push(addEventListener(window, 'keydown', originHandler));\n extendEvents.push(addEventListener(window, 'keyup', originHandler));\n extendEvents.push(addEventListener(window, 'focus', originHandler));\n }\n }; // 获取 shape 的 item 对象\n\n\n EventController.getItemRoot = function (shape) {\n while (shape && !shape.get('item')) {\n shape = shape.get('parent');\n }\n\n return shape;\n };\n /**\n * 处理 canvas 事件\n * @param evt 事件句柄\n */\n\n\n EventController.prototype.onCanvasEvents = function (evt) {\n var graph = this.graph;\n var canvas = graph.get('canvas');\n var target = evt.target;\n var eventType = evt.type;\n /**\n * (clientX, clientY): 相对于页面的坐标;\n * (canvasX, canvasY): 相对于