/*
* @nebula.js/sn-histogram v1.0.6
* Copyright (c) 2025 QlikTech International AB
* Released under the MIT license.
*/

(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@nebula.js/stardust')) :
	typeof define === 'function' && define.amd ? define(['@nebula.js/stardust'], factory) :
	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global["sn-histogram"] = factory(global.stardust));
})(this, (function (stardust) { 'use strict';

	var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

	function getDefaultExportFromCjs (x) {
		return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
	}

	var jquery$1 = {exports: {}};

	/*!
	 * jQuery JavaScript Library v3.7.1
	 * https://jquery.com/
	 *
	 * Copyright OpenJS Foundation and other contributors
	 * Released under the MIT license
	 * https://jquery.org/license
	 *
	 * Date: 2023-08-28T13:37Z
	 */
	var jquery = jquery$1.exports;
	var hasRequiredJquery;
	function requireJquery() {
	  if (hasRequiredJquery) return jquery$1.exports;
	  hasRequiredJquery = 1;
	  (function (module) {
	    (function (global, factory) {

	      {
	        // For CommonJS and CommonJS-like environments where a proper `window`
	        // is present, execute the factory and get jQuery.
	        // For environments that do not have a `window` with a `document`
	        // (such as Node.js), expose a factory as module.exports.
	        // This accentuates the need for the creation of a real `window`.
	        // e.g. var jQuery = require("jquery")(window);
	        // See ticket trac-14549 for more info.
	        module.exports = global.document ? factory(global, true) : function (w) {
	          if (!w.document) {
	            throw new Error("jQuery requires a window with a document");
	          }
	          return factory(w);
	        };
	      }

	      // Pass this if window is not defined yet
	    })(typeof window !== "undefined" ? window : jquery, function (window, noGlobal) {

	      var arr = [];
	      var getProto = Object.getPrototypeOf;
	      var slice = arr.slice;
	      var flat = arr.flat ? function (array) {
	        return arr.flat.call(array);
	      } : function (array) {
	        return arr.concat.apply([], array);
	      };
	      var push = arr.push;
	      var indexOf = arr.indexOf;
	      var class2type = {};
	      var toString = class2type.toString;
	      var hasOwn = class2type.hasOwnProperty;
	      var fnToString = hasOwn.toString;
	      var ObjectFunctionString = fnToString.call(Object);
	      var support = {};
	      var isFunction = function isFunction(obj) {
	        // Support: Chrome <=57, Firefox <=52
	        // In some browsers, typeof returns "function" for HTML <object> elements
	        // (i.e., `typeof document.createElement( "object" ) === "function"`).
	        // We don't want to classify *any* DOM node as a function.
	        // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
	        // Plus for old WebKit, typeof returns "function" for HTML collections
	        // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
	        return typeof obj === "function" && typeof obj.nodeType !== "number" && typeof obj.item !== "function";
	      };
	      var isWindow = function isWindow(obj) {
	        return obj != null && obj === obj.window;
	      };
	      var document = window.document;
	      var preservedScriptAttributes = {
	        type: true,
	        src: true,
	        nonce: true,
	        noModule: true
	      };
	      function DOMEval(code, node, doc) {
	        doc = doc || document;
	        var i,
	          val,
	          script = doc.createElement("script");
	        script.text = code;
	        if (node) {
	          for (i in preservedScriptAttributes) {
	            // Support: Firefox 64+, Edge 18+
	            // Some browsers don't support the "nonce" property on scripts.
	            // On the other hand, just using `getAttribute` is not enough as
	            // the `nonce` attribute is reset to an empty string whenever it
	            // becomes browsing-context connected.
	            // See https://github.com/whatwg/html/issues/2369
	            // See https://html.spec.whatwg.org/#nonce-attributes
	            // The `node.getAttribute` check was added for the sake of
	            // `jQuery.globalEval` so that it can fake a nonce-containing node
	            // via an object.
	            val = node[i] || node.getAttribute && node.getAttribute(i);
	            if (val) {
	              script.setAttribute(i, val);
	            }
	          }
	        }
	        doc.head.appendChild(script).parentNode.removeChild(script);
	      }
	      function toType(obj) {
	        if (obj == null) {
	          return obj + "";
	        }

	        // Support: Android <=2.3 only (functionish RegExp)
	        return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj;
	      }
	      /* global Symbol */
	      // Defining this global in .eslintrc.json would create a danger of using the global
	      // unguarded in another place, it seems safer to define global only for this module

	      var version = "3.7.1",
	        rhtmlSuffix = /HTML$/i,
	        // Define a local copy of jQuery
	        jQuery = function (selector, context) {
	          // The jQuery object is actually just the init constructor 'enhanced'
	          // Need init if jQuery is called (just allow error to be thrown if not included)
	          return new jQuery.fn.init(selector, context);
	        };
	      jQuery.fn = jQuery.prototype = {
	        // The current version of jQuery being used
	        jquery: version,
	        constructor: jQuery,
	        // The default length of a jQuery object is 0
	        length: 0,
	        toArray: function () {
	          return slice.call(this);
	        },
	        // Get the Nth element in the matched element set OR
	        // Get the whole matched element set as a clean array
	        get: function (num) {
	          // Return all the elements in a clean array
	          if (num == null) {
	            return slice.call(this);
	          }

	          // Return just the one element from the set
	          return num < 0 ? this[num + this.length] : this[num];
	        },
	        // Take an array of elements and push it onto the stack
	        // (returning the new matched element set)
	        pushStack: function (elems) {
	          // Build a new jQuery matched element set
	          var ret = jQuery.merge(this.constructor(), elems);

	          // Add the old object onto the stack (as a reference)
	          ret.prevObject = this;

	          // Return the newly-formed element set
	          return ret;
	        },
	        // Execute a callback for every element in the matched set.
	        each: function (callback) {
	          return jQuery.each(this, callback);
	        },
	        map: function (callback) {
	          return this.pushStack(jQuery.map(this, function (elem, i) {
	            return callback.call(elem, i, elem);
	          }));
	        },
	        slice: function () {
	          return this.pushStack(slice.apply(this, arguments));
	        },
	        first: function () {
	          return this.eq(0);
	        },
	        last: function () {
	          return this.eq(-1);
	        },
	        even: function () {
	          return this.pushStack(jQuery.grep(this, function (_elem, i) {
	            return (i + 1) % 2;
	          }));
	        },
	        odd: function () {
	          return this.pushStack(jQuery.grep(this, function (_elem, i) {
	            return i % 2;
	          }));
	        },
	        eq: function (i) {
	          var len = this.length,
	            j = +i + (i < 0 ? len : 0);
	          return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
	        },
	        end: function () {
	          return this.prevObject || this.constructor();
	        },
	        // For internal use only.
	        // Behaves like an Array's method, not like a jQuery method.
	        push: push,
	        sort: arr.sort,
	        splice: arr.splice
	      };
	      jQuery.extend = jQuery.fn.extend = function () {
	        var options,
	          name,
	          src,
	          copy,
	          copyIsArray,
	          clone,
	          target = arguments[0] || {},
	          i = 1,
	          length = arguments.length,
	          deep = false;

	        // Handle a deep copy situation
	        if (typeof target === "boolean") {
	          deep = target;

	          // Skip the boolean and the target
	          target = arguments[i] || {};
	          i++;
	        }

	        // Handle case when target is a string or something (possible in deep copy)
	        if (typeof target !== "object" && !isFunction(target)) {
	          target = {};
	        }

	        // Extend jQuery itself if only one argument is passed
	        if (i === length) {
	          target = this;
	          i--;
	        }
	        for (; i < length; i++) {
	          // Only deal with non-null/undefined values
	          if ((options = arguments[i]) != null) {
	            // Extend the base object
	            for (name in options) {
	              copy = options[name];

	              // Prevent Object.prototype pollution
	              // Prevent never-ending loop
	              if (name === "__proto__" || target === copy) {
	                continue;
	              }

	              // Recurse if we're merging plain objects or arrays
	              if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
	                src = target[name];

	                // Ensure proper type for the source value
	                if (copyIsArray && !Array.isArray(src)) {
	                  clone = [];
	                } else if (!copyIsArray && !jQuery.isPlainObject(src)) {
	                  clone = {};
	                } else {
	                  clone = src;
	                }
	                copyIsArray = false;

	                // Never move original objects, clone them
	                target[name] = jQuery.extend(deep, clone, copy);

	                // Don't bring in undefined values
	              } else if (copy !== undefined) {
	                target[name] = copy;
	              }
	            }
	          }
	        }

	        // Return the modified object
	        return target;
	      };
	      jQuery.extend({
	        // Unique for each copy of jQuery on the page
	        expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
	        // Assume jQuery is ready without the ready module
	        isReady: true,
	        error: function (msg) {
	          throw new Error(msg);
	        },
	        noop: function () {},
	        isPlainObject: function (obj) {
	          var proto, Ctor;

	          // Detect obvious negatives
	          // Use toString instead of jQuery.type to catch host objects
	          if (!obj || toString.call(obj) !== "[object Object]") {
	            return false;
	          }
	          proto = getProto(obj);

	          // Objects with no prototype (e.g., `Object.create( null )`) are plain
	          if (!proto) {
	            return true;
	          }

	          // Objects with prototype are plain iff they were constructed by a global Object function
	          Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
	          return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
	        },
	        isEmptyObject: function (obj) {
	          var name;
	          for (name in obj) {
	            return false;
	          }
	          return true;
	        },
	        // Evaluates a script in a provided context; falls back to the global one
	        // if not specified.
	        globalEval: function (code, options, doc) {
	          DOMEval(code, {
	            nonce: options && options.nonce
	          }, doc);
	        },
	        each: function (obj, callback) {
	          var length,
	            i = 0;
	          if (isArrayLike(obj)) {
	            length = obj.length;
	            for (; i < length; i++) {
	              if (callback.call(obj[i], i, obj[i]) === false) {
	                break;
	              }
	            }
	          } else {
	            for (i in obj) {
	              if (callback.call(obj[i], i, obj[i]) === false) {
	                break;
	              }
	            }
	          }
	          return obj;
	        },
	        // Retrieve the text value of an array of DOM nodes
	        text: function (elem) {
	          var node,
	            ret = "",
	            i = 0,
	            nodeType = elem.nodeType;
	          if (!nodeType) {
	            // If no nodeType, this is expected to be an array
	            while (node = elem[i++]) {
	              // Do not traverse comment nodes
	              ret += jQuery.text(node);
	            }
	          }
	          if (nodeType === 1 || nodeType === 11) {
	            return elem.textContent;
	          }
	          if (nodeType === 9) {
	            return elem.documentElement.textContent;
	          }
	          if (nodeType === 3 || nodeType === 4) {
	            return elem.nodeValue;
	          }

	          // Do not include comment or processing instruction nodes

	          return ret;
	        },
	        // results is for internal usage only
	        makeArray: function (arr, results) {
	          var ret = results || [];
	          if (arr != null) {
	            if (isArrayLike(Object(arr))) {
	              jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
	            } else {
	              push.call(ret, arr);
	            }
	          }
	          return ret;
	        },
	        inArray: function (elem, arr, i) {
	          return arr == null ? -1 : indexOf.call(arr, elem, i);
	        },
	        isXMLDoc: function (elem) {
	          var namespace = elem && elem.namespaceURI,
	            docElem = elem && (elem.ownerDocument || elem).documentElement;

	          // Assume HTML when documentElement doesn't yet exist, such as inside
	          // document fragments.
	          return !rhtmlSuffix.test(namespace || docElem && docElem.nodeName || "HTML");
	        },
	        // Support: Android <=4.0 only, PhantomJS 1 only
	        // push.apply(_, arraylike) throws on ancient WebKit
	        merge: function (first, second) {
	          var len = +second.length,
	            j = 0,
	            i = first.length;
	          for (; j < len; j++) {
	            first[i++] = second[j];
	          }
	          first.length = i;
	          return first;
	        },
	        grep: function (elems, callback, invert) {
	          var callbackInverse,
	            matches = [],
	            i = 0,
	            length = elems.length,
	            callbackExpect = !invert;

	          // Go through the array, only saving the items
	          // that pass the validator function
	          for (; i < length; i++) {
	            callbackInverse = !callback(elems[i], i);
	            if (callbackInverse !== callbackExpect) {
	              matches.push(elems[i]);
	            }
	          }
	          return matches;
	        },
	        // arg is for internal usage only
	        map: function (elems, callback, arg) {
	          var length,
	            value,
	            i = 0,
	            ret = [];

	          // Go through the array, translating each of the items to their new values
	          if (isArrayLike(elems)) {
	            length = elems.length;
	            for (; i < length; i++) {
	              value = callback(elems[i], i, arg);
	              if (value != null) {
	                ret.push(value);
	              }
	            }

	            // Go through every key on the object,
	          } else {
	            for (i in elems) {
	              value = callback(elems[i], i, arg);
	              if (value != null) {
	                ret.push(value);
	              }
	            }
	          }

	          // Flatten any nested arrays
	          return flat(ret);
	        },
	        // A global GUID counter for objects
	        guid: 1,
	        // jQuery.support is not used in Core but other projects attach their
	        // properties to it so it needs to exist.
	        support: support
	      });
	      if (typeof Symbol === "function") {
	        jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
	      }

	      // Populate the class2type map
	      jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (_i, name) {
	        class2type["[object " + name + "]"] = name.toLowerCase();
	      });
	      function isArrayLike(obj) {
	        // Support: real iOS 8.2 only (not reproducible in simulator)
	        // `in` check used to prevent JIT error (gh-2145)
	        // hasOwn isn't used here due to false negatives
	        // regarding Nodelist length in IE
	        var length = !!obj && "length" in obj && obj.length,
	          type = toType(obj);
	        if (isFunction(obj) || isWindow(obj)) {
	          return false;
	        }
	        return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
	      }
	      function nodeName(elem, name) {
	        return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
	      }
	      var pop = arr.pop;
	      var sort = arr.sort;
	      var splice = arr.splice;
	      var whitespace = "[\\x20\\t\\r\\n\\f]";
	      var rtrimCSS = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g");

	      // Note: an element does not contain itself
	      jQuery.contains = function (a, b) {
	        var bup = b && b.parentNode;
	        return a === bup || !!(bup && bup.nodeType === 1 && (
	        // Support: IE 9 - 11+
	        // IE doesn't have `contains` on SVG.
	        a.contains ? a.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
	      };

	      // CSS string/identifier serialization
	      // https://drafts.csswg.org/cssom/#common-serializing-idioms
	      var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
	      function fcssescape(ch, asCodePoint) {
	        if (asCodePoint) {
	          // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
	          if (ch === "\0") {
	            return "\uFFFD";
	          }

	          // Control characters and (dependent upon position) numbers get escaped as code points
	          return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
	        }

	        // Other potentially-special ASCII characters get backslash-escaped
	        return "\\" + ch;
	      }
	      jQuery.escapeSelector = function (sel) {
	        return (sel + "").replace(rcssescape, fcssescape);
	      };
	      var preferredDoc = document,
	        pushNative = push;
	      (function () {
	        var i,
	          Expr,
	          outermostContext,
	          sortInput,
	          hasDuplicate,
	          push = pushNative,
	          // Local document vars
	          document,
	          documentElement,
	          documentIsHTML,
	          rbuggyQSA,
	          matches,
	          // Instance-specific data
	          expando = jQuery.expando,
	          dirruns = 0,
	          done = 0,
	          classCache = createCache(),
	          tokenCache = createCache(),
	          compilerCache = createCache(),
	          nonnativeSelectorCache = createCache(),
	          sortOrder = function (a, b) {
	            if (a === b) {
	              hasDuplicate = true;
	            }
	            return 0;
	          },
	          booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + "loop|multiple|open|readonly|required|scoped",
	          // Regular expressions

	          // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
	          identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
	          // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
	          attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
	          // Operator (capture 2)
	          "*([*^$|!~]?=)" + whitespace +
	          // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
	          "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]",
	          pseudos = ":(" + identifier + ")(?:\\((" +
	          // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
	          // 1. quoted (capture 3; capture 4 or capture 5)
	          "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
	          // 2. simple (capture 6)
	          "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
	          // 3. anything else (capture 2)
	          ".*" + ")\\)|)",
	          // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
	          rwhitespace = new RegExp(whitespace + "+", "g"),
	          rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
	          rleadingCombinator = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
	          rdescend = new RegExp(whitespace + "|>"),
	          rpseudo = new RegExp(pseudos),
	          ridentifier = new RegExp("^" + identifier + "$"),
	          matchExpr = {
	            ID: new RegExp("^#(" + identifier + ")"),
	            CLASS: new RegExp("^\\.(" + identifier + ")"),
	            TAG: new RegExp("^(" + identifier + "|[*])"),
	            ATTR: new RegExp("^" + attributes),
	            PSEUDO: new RegExp("^" + pseudos),
	            CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
	            bool: new RegExp("^(?:" + booleans + ")$", "i"),
	            // For use in libraries implementing .is()
	            // We use this for POS matching in `select`
	            needsContext: new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
	          },
	          rinputs = /^(?:input|select|textarea|button)$/i,
	          rheader = /^h\d$/i,
	          // Easily-parseable/retrievable ID or TAG or CLASS selectors
	          rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
	          rsibling = /[+~]/,
	          // CSS escapes
	          // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
	          runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g"),
	          funescape = function (escape, nonHex) {
	            var high = "0x" + escape.slice(1) - 0x10000;
	            if (nonHex) {
	              // Strip the backslash prefix from a non-hex escape sequence
	              return nonHex;
	            }

	            // Replace a hexadecimal escape sequence with the encoded Unicode code point
	            // Support: IE <=11+
	            // For values outside the Basic Multilingual Plane (BMP), manually construct a
	            // surrogate pair
	            return high < 0 ? String.fromCharCode(high + 0x10000) : String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
	          },
	          // Used for iframes; see `setDocument`.
	          // Support: IE 9 - 11+, Edge 12 - 18+
	          // Removing the function wrapper causes a "Permission Denied"
	          // error in IE/Edge.
	          unloadHandler = function () {
	            setDocument();
	          },
	          inDisabledFieldset = addCombinator(function (elem) {
	            return elem.disabled === true && nodeName(elem, "fieldset");
	          }, {
	            dir: "parentNode",
	            next: "legend"
	          });

	        // Support: IE <=9 only
	        // Accessing document.activeElement can throw unexpectedly
	        // https://bugs.jquery.com/ticket/13393
	        function safeActiveElement() {
	          try {
	            return document.activeElement;
	          } catch (err) {}
	        }

	        // Optimize for push.apply( _, NodeList )
	        try {
	          push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);

	          // Support: Android <=4.0
	          // Detect silently failing push.apply
	          // eslint-disable-next-line no-unused-expressions
	          arr[preferredDoc.childNodes.length].nodeType;
	        } catch (e) {
	          push = {
	            apply: function (target, els) {
	              pushNative.apply(target, slice.call(els));
	            },
	            call: function (target) {
	              pushNative.apply(target, slice.call(arguments, 1));
	            }
	          };
	        }
	        function find(selector, context, results, seed) {
	          var m,
	            i,
	            elem,
	            nid,
	            match,
	            groups,
	            newSelector,
	            newContext = context && context.ownerDocument,
	            // nodeType defaults to 9, since context defaults to document
	            nodeType = context ? context.nodeType : 9;
	          results = results || [];

	          // Return early from calls with invalid selector or context
	          if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
	            return results;
	          }

	          // Try to shortcut find operations (as opposed to filters) in HTML documents
	          if (!seed) {
	            setDocument(context);
	            context = context || document;
	            if (documentIsHTML) {
	              // If the selector is sufficiently simple, try using a "get*By*" DOM method
	              // (excepting DocumentFragment context, where the methods don't exist)
	              if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
	                // ID selector
	                if (m = match[1]) {
	                  // Document context
	                  if (nodeType === 9) {
	                    if (elem = context.getElementById(m)) {
	                      // Support: IE 9 only
	                      // getElementById can match elements by name instead of ID
	                      if (elem.id === m) {
	                        push.call(results, elem);
	                        return results;
	                      }
	                    } else {
	                      return results;
	                    }

	                    // Element context
	                  } else {
	                    // Support: IE 9 only
	                    // getElementById can match elements by name instead of ID
	                    if (newContext && (elem = newContext.getElementById(m)) && find.contains(context, elem) && elem.id === m) {
	                      push.call(results, elem);
	                      return results;
	                    }
	                  }

	                  // Type selector
	                } else if (match[2]) {
	                  push.apply(results, context.getElementsByTagName(selector));
	                  return results;

	                  // Class selector
	                } else if ((m = match[3]) && context.getElementsByClassName) {
	                  push.apply(results, context.getElementsByClassName(m));
	                  return results;
	                }
	              }

	              // Take advantage of querySelectorAll
	              if (!nonnativeSelectorCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
	                newSelector = selector;
	                newContext = context;

	                // qSA considers elements outside a scoping root when evaluating child or
	                // descendant combinators, which is not what we want.
	                // In such cases, we work around the behavior by prefixing every selector in the
	                // list with an ID selector referencing the scope context.
	                // The technique has to be used as well when a leading combinator is used
	                // as such selectors are not recognized by querySelectorAll.
	                // Thanks to Andrew Dupont for this technique.
	                if (nodeType === 1 && (rdescend.test(selector) || rleadingCombinator.test(selector))) {
	                  // Expand context for sibling selectors
	                  newContext = rsibling.test(selector) && testContext(context.parentNode) || context;

	                  // We can use :scope instead of the ID hack if the browser
	                  // supports it & if we're not changing the context.
	                  // Support: IE 11+, Edge 17 - 18+
	                  // IE/Edge sometimes throw a "Permission denied" error when
	                  // strict-comparing two documents; shallow comparisons work.
	                  // eslint-disable-next-line eqeqeq
	                  if (newContext != context || !support.scope) {
	                    // Capture the context ID, setting it first if necessary
	                    if (nid = context.getAttribute("id")) {
	                      nid = jQuery.escapeSelector(nid);
	                    } else {
	                      context.setAttribute("id", nid = expando);
	                    }
	                  }

	                  // Prefix every selector in the list
	                  groups = tokenize(selector);
	                  i = groups.length;
	                  while (i--) {
	                    groups[i] = (nid ? "#" + nid : ":scope") + " " + toSelector(groups[i]);
	                  }
	                  newSelector = groups.join(",");
	                }
	                try {
	                  push.apply(results, newContext.querySelectorAll(newSelector));
	                  return results;
	                } catch (qsaError) {
	                  nonnativeSelectorCache(selector, true);
	                } finally {
	                  if (nid === expando) {
	                    context.removeAttribute("id");
	                  }
	                }
	              }
	            }
	          }

	          // All others
	          return select(selector.replace(rtrimCSS, "$1"), context, results, seed);
	        }

	        /**
	         * Create key-value caches of limited size
	         * @returns {function(string, object)} Returns the Object data after storing it on itself with
	         *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
	         *	deleting the oldest entry
	         */
	        function createCache() {
	          var keys = [];
	          function cache(key, value) {
	            // Use (key + " ") to avoid collision with native prototype properties
	            // (see https://github.com/jquery/sizzle/issues/157)
	            if (keys.push(key + " ") > Expr.cacheLength) {
	              // Only keep the most recent entries
	              delete cache[keys.shift()];
	            }
	            return cache[key + " "] = value;
	          }
	          return cache;
	        }

	        /**
	         * Mark a function for special use by jQuery selector module
	         * @param {Function} fn The function to mark
	         */
	        function markFunction(fn) {
	          fn[expando] = true;
	          return fn;
	        }

	        /**
	         * Support testing using an element
	         * @param {Function} fn Passed the created element and returns a boolean result
	         */
	        function assert(fn) {
	          var el = document.createElement("fieldset");
	          try {
	            return !!fn(el);
	          } catch (e) {
	            return false;
	          } finally {
	            // Remove from its parent by default
	            if (el.parentNode) {
	              el.parentNode.removeChild(el);
	            }

	            // release memory in IE
	            el = null;
	          }
	        }

	        /**
	         * Returns a function to use in pseudos for input types
	         * @param {String} type
	         */
	        function createInputPseudo(type) {
	          return function (elem) {
	            return nodeName(elem, "input") && elem.type === type;
	          };
	        }

	        /**
	         * Returns a function to use in pseudos for buttons
	         * @param {String} type
	         */
	        function createButtonPseudo(type) {
	          return function (elem) {
	            return (nodeName(elem, "input") || nodeName(elem, "button")) && elem.type === type;
	          };
	        }

	        /**
	         * Returns a function to use in pseudos for :enabled/:disabled
	         * @param {Boolean} disabled true for :disabled; false for :enabled
	         */
	        function createDisabledPseudo(disabled) {
	          // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
	          return function (elem) {
	            // Only certain elements can match :enabled or :disabled
	            // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
	            // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
	            if ("form" in elem) {
	              // Check for inherited disabledness on relevant non-disabled elements:
	              // * listed form-associated elements in a disabled fieldset
	              //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
	              //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
	              // * option elements in a disabled optgroup
	              //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
	              // All such elements have a "form" property.
	              if (elem.parentNode && elem.disabled === false) {
	                // Option elements defer to a parent optgroup if present
	                if ("label" in elem) {
	                  if ("label" in elem.parentNode) {
	                    return elem.parentNode.disabled === disabled;
	                  } else {
	                    return elem.disabled === disabled;
	                  }
	                }

	                // Support: IE 6 - 11+
	                // Use the isDisabled shortcut property to check for disabled fieldset ancestors
	                return elem.isDisabled === disabled ||
	                // Where there is no isDisabled, check manually
	                elem.isDisabled !== !disabled && inDisabledFieldset(elem) === disabled;
	              }
	              return elem.disabled === disabled;

	              // Try to winnow out elements that can't be disabled before trusting the disabled property.
	              // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
	              // even exist on them, let alone have a boolean value.
	            } else if ("label" in elem) {
	              return elem.disabled === disabled;
	            }

	            // Remaining elements are neither :enabled nor :disabled
	            return false;
	          };
	        }

	        /**
	         * Returns a function to use in pseudos for positionals
	         * @param {Function} fn
	         */
	        function createPositionalPseudo(fn) {
	          return markFunction(function (argument) {
	            argument = +argument;
	            return markFunction(function (seed, matches) {
	              var j,
	                matchIndexes = fn([], seed.length, argument),
	                i = matchIndexes.length;

	              // Match elements found at the specified indexes
	              while (i--) {
	                if (seed[j = matchIndexes[i]]) {
	                  seed[j] = !(matches[j] = seed[j]);
	                }
	              }
	            });
	          });
	        }

	        /**
	         * Checks a node for validity as a jQuery selector context
	         * @param {Element|Object=} context
	         * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
	         */
	        function testContext(context) {
	          return context && typeof context.getElementsByTagName !== "undefined" && context;
	        }

	        /**
	         * Sets document-related variables once based on the current document
	         * @param {Element|Object} [node] An element or document object to use to set the document
	         * @returns {Object} Returns the current document
	         */
	        function setDocument(node) {
	          var subWindow,
	            doc = node ? node.ownerDocument || node : preferredDoc;

	          // Return early if doc is invalid or already selected
	          // Support: IE 11+, Edge 17 - 18+
	          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	          // two documents; shallow comparisons work.
	          // eslint-disable-next-line eqeqeq
	          if (doc == document || doc.nodeType !== 9 || !doc.documentElement) {
	            return document;
	          }

	          // Update global variables
	          document = doc;
	          documentElement = document.documentElement;
	          documentIsHTML = !jQuery.isXMLDoc(document);

	          // Support: iOS 7 only, IE 9 - 11+
	          // Older browsers didn't support unprefixed `matches`.
	          matches = documentElement.matches || documentElement.webkitMatchesSelector || documentElement.msMatchesSelector;

	          // Support: IE 9 - 11+, Edge 12 - 18+
	          // Accessing iframe documents after unload throws "permission denied" errors
	          // (see trac-13936).
	          // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
	          // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
	          if (documentElement.msMatchesSelector &&
	          // Support: IE 11+, Edge 17 - 18+
	          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	          // two documents; shallow comparisons work.
	          // eslint-disable-next-line eqeqeq
	          preferredDoc != document && (subWindow = document.defaultView) && subWindow.top !== subWindow) {
	            // Support: IE 9 - 11+, Edge 12 - 18+
	            subWindow.addEventListener("unload", unloadHandler);
	          }

	          // Support: IE <10
	          // Check if getElementById returns elements by name
	          // The broken getElementById methods don't pick up programmatically-set names,
	          // so use a roundabout getElementsByName test
	          support.getById = assert(function (el) {
	            documentElement.appendChild(el).id = jQuery.expando;
	            return !document.getElementsByName || !document.getElementsByName(jQuery.expando).length;
	          });

	          // Support: IE 9 only
	          // Check to see if it's possible to do matchesSelector
	          // on a disconnected node.
	          support.disconnectedMatch = assert(function (el) {
	            return matches.call(el, "*");
	          });

	          // Support: IE 9 - 11+, Edge 12 - 18+
	          // IE/Edge don't support the :scope pseudo-class.
	          support.scope = assert(function () {
	            return document.querySelectorAll(":scope");
	          });

	          // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
	          // Make sure the `:has()` argument is parsed unforgivingly.
	          // We include `*` in the test to detect buggy implementations that are
	          // _selectively_ forgiving (specifically when the list includes at least
	          // one valid selector).
	          // Note that we treat complete lack of support for `:has()` as if it were
	          // spec-compliant support, which is fine because use of `:has()` in such
	          // environments will fail in the qSA path and fall back to jQuery traversal
	          // anyway.
	          support.cssHas = assert(function () {
	            try {
	              document.querySelector(":has(*,:jqfake)");
	              return false;
	            } catch (e) {
	              return true;
	            }
	          });

	          // ID filter and find
	          if (support.getById) {
	            Expr.filter.ID = function (id) {
	              var attrId = id.replace(runescape, funescape);
	              return function (elem) {
	                return elem.getAttribute("id") === attrId;
	              };
	            };
	            Expr.find.ID = function (id, context) {
	              if (typeof context.getElementById !== "undefined" && documentIsHTML) {
	                var elem = context.getElementById(id);
	                return elem ? [elem] : [];
	              }
	            };
	          } else {
	            Expr.filter.ID = function (id) {
	              var attrId = id.replace(runescape, funescape);
	              return function (elem) {
	                var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
	                return node && node.value === attrId;
	              };
	            };

	            // Support: IE 6 - 7 only
	            // getElementById is not reliable as a find shortcut
	            Expr.find.ID = function (id, context) {
	              if (typeof context.getElementById !== "undefined" && documentIsHTML) {
	                var node,
	                  i,
	                  elems,
	                  elem = context.getElementById(id);
	                if (elem) {
	                  // Verify the id attribute
	                  node = elem.getAttributeNode("id");
	                  if (node && node.value === id) {
	                    return [elem];
	                  }

	                  // Fall back on getElementsByName
	                  elems = context.getElementsByName(id);
	                  i = 0;
	                  while (elem = elems[i++]) {
	                    node = elem.getAttributeNode("id");
	                    if (node && node.value === id) {
	                      return [elem];
	                    }
	                  }
	                }
	                return [];
	              }
	            };
	          }

	          // Tag
	          Expr.find.TAG = function (tag, context) {
	            if (typeof context.getElementsByTagName !== "undefined") {
	              return context.getElementsByTagName(tag);

	              // DocumentFragment nodes don't have gEBTN
	            } else {
	              return context.querySelectorAll(tag);
	            }
	          };

	          // Class
	          Expr.find.CLASS = function (className, context) {
	            if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
	              return context.getElementsByClassName(className);
	            }
	          };

	          /* QSA/matchesSelector
	          ---------------------------------------------------------------------- */

	          // QSA and matchesSelector support

	          rbuggyQSA = [];

	          // Build QSA regex
	          // Regex strategy adopted from Diego Perini
	          assert(function (el) {
	            var input;
	            documentElement.appendChild(el).innerHTML = "<a id='" + expando + "' href='' disabled='disabled'></a>" + "<select id='" + expando + "-\r\\' disabled='disabled'>" + "<option selected=''></option></select>";

	            // Support: iOS <=7 - 8 only
	            // Boolean attributes and "value" are not treated correctly in some XML documents
	            if (!el.querySelectorAll("[selected]").length) {
	              rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
	            }

	            // Support: iOS <=7 - 8 only
	            if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
	              rbuggyQSA.push("~=");
	            }

	            // Support: iOS 8 only
	            // https://bugs.webkit.org/show_bug.cgi?id=136851
	            // In-page `selector#id sibling-combinator selector` fails
	            if (!el.querySelectorAll("a#" + expando + "+*").length) {
	              rbuggyQSA.push(".#.+[+~]");
	            }

	            // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
	            // In some of the document kinds, these selectors wouldn't work natively.
	            // This is probably OK but for backwards compatibility we want to maintain
	            // handling them through jQuery traversal in jQuery 3.x.
	            if (!el.querySelectorAll(":checked").length) {
	              rbuggyQSA.push(":checked");
	            }

	            // Support: Windows 8 Native Apps
	            // The type and name attributes are restricted during .innerHTML assignment
	            input = document.createElement("input");
	            input.setAttribute("type", "hidden");
	            el.appendChild(input).setAttribute("name", "D");

	            // Support: IE 9 - 11+
	            // IE's :disabled selector does not pick up the children of disabled fieldsets
	            // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
	            // In some of the document kinds, these selectors wouldn't work natively.
	            // This is probably OK but for backwards compatibility we want to maintain
	            // handling them through jQuery traversal in jQuery 3.x.
	            documentElement.appendChild(el).disabled = true;
	            if (el.querySelectorAll(":disabled").length !== 2) {
	              rbuggyQSA.push(":enabled", ":disabled");
	            }

	            // Support: IE 11+, Edge 15 - 18+
	            // IE 11/Edge don't find elements on a `[name='']` query in some cases.
	            // Adding a temporary attribute to the document before the selection works
	            // around the issue.
	            // Interestingly, IE 10 & older don't seem to have the issue.
	            input = document.createElement("input");
	            input.setAttribute("name", "");
	            el.appendChild(input);
	            if (!el.querySelectorAll("[name='']").length) {
	              rbuggyQSA.push("\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:''|\"\")");
	            }
	          });
	          if (!support.cssHas) {
	            // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
	            // Our regular `try-catch` mechanism fails to detect natively-unsupported
	            // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
	            // in browsers that parse the `:has()` argument as a forgiving selector list.
	            // https://drafts.csswg.org/selectors/#relational now requires the argument
	            // to be parsed unforgivingly, but browsers have not yet fully adjusted.
	            rbuggyQSA.push(":has");
	          }
	          rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));

	          /* Sorting
	          ---------------------------------------------------------------------- */

	          // Document order sorting
	          sortOrder = function (a, b) {
	            // Flag for duplicate removal
	            if (a === b) {
	              hasDuplicate = true;
	              return 0;
	            }

	            // Sort on method existence if only one input has compareDocumentPosition
	            var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
	            if (compare) {
	              return compare;
	            }

	            // Calculate position if both inputs belong to the same document
	            // Support: IE 11+, Edge 17 - 18+
	            // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	            // two documents; shallow comparisons work.
	            // eslint-disable-next-line eqeqeq
	            compare = (a.ownerDocument || a) == (b.ownerDocument || b) ? a.compareDocumentPosition(b) :
	            // Otherwise we know they are disconnected
	            1;

	            // Disconnected nodes
	            if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
	              // Choose the first element that is related to our preferred document
	              // Support: IE 11+, Edge 17 - 18+
	              // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	              // two documents; shallow comparisons work.
	              // eslint-disable-next-line eqeqeq
	              if (a === document || a.ownerDocument == preferredDoc && find.contains(preferredDoc, a)) {
	                return -1;
	              }

	              // Support: IE 11+, Edge 17 - 18+
	              // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	              // two documents; shallow comparisons work.
	              // eslint-disable-next-line eqeqeq
	              if (b === document || b.ownerDocument == preferredDoc && find.contains(preferredDoc, b)) {
	                return 1;
	              }

	              // Maintain original order
	              return sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0;
	            }
	            return compare & 4 ? -1 : 1;
	          };
	          return document;
	        }
	        find.matches = function (expr, elements) {
	          return find(expr, null, null, elements);
	        };
	        find.matchesSelector = function (elem, expr) {
	          setDocument(elem);
	          if (documentIsHTML && !nonnativeSelectorCache[expr + " "] && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
	            try {
	              var ret = matches.call(elem, expr);

	              // IE 9's matchesSelector returns false on disconnected nodes
	              if (ret || support.disconnectedMatch ||
	              // As well, disconnected nodes are said to be in a document
	              // fragment in IE 9
	              elem.document && elem.document.nodeType !== 11) {
	                return ret;
	              }
	            } catch (e) {
	              nonnativeSelectorCache(expr, true);
	            }
	          }
	          return find(expr, document, null, [elem]).length > 0;
	        };
	        find.contains = function (context, elem) {
	          // Set document vars if needed
	          // Support: IE 11+, Edge 17 - 18+
	          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	          // two documents; shallow comparisons work.
	          // eslint-disable-next-line eqeqeq
	          if ((context.ownerDocument || context) != document) {
	            setDocument(context);
	          }
	          return jQuery.contains(context, elem);
	        };
	        find.attr = function (elem, name) {
	          // Set document vars if needed
	          // Support: IE 11+, Edge 17 - 18+
	          // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	          // two documents; shallow comparisons work.
	          // eslint-disable-next-line eqeqeq
	          if ((elem.ownerDocument || elem) != document) {
	            setDocument(elem);
	          }
	          var fn = Expr.attrHandle[name.toLowerCase()],
	            // Don't get fooled by Object.prototype properties (see trac-13807)
	            val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
	          if (val !== undefined) {
	            return val;
	          }
	          return elem.getAttribute(name);
	        };
	        find.error = function (msg) {
	          throw new Error("Syntax error, unrecognized expression: " + msg);
	        };

	        /**
	         * Document sorting and removing duplicates
	         * @param {ArrayLike} results
	         */
	        jQuery.uniqueSort = function (results) {
	          var elem,
	            duplicates = [],
	            j = 0,
	            i = 0;

	          // Unless we *know* we can detect duplicates, assume their presence
	          //
	          // Support: Android <=4.0+
	          // Testing for detecting duplicates is unpredictable so instead assume we can't
	          // depend on duplicate detection in all browsers without a stable sort.
	          hasDuplicate = !support.sortStable;
	          sortInput = !support.sortStable && slice.call(results, 0);
	          sort.call(results, sortOrder);
	          if (hasDuplicate) {
	            while (elem = results[i++]) {
	              if (elem === results[i]) {
	                j = duplicates.push(i);
	              }
	            }
	            while (j--) {
	              splice.call(results, duplicates[j], 1);
	            }
	          }

	          // Clear input after sorting to release objects
	          // See https://github.com/jquery/sizzle/pull/225
	          sortInput = null;
	          return results;
	        };
	        jQuery.fn.uniqueSort = function () {
	          return this.pushStack(jQuery.uniqueSort(slice.apply(this)));
	        };
	        Expr = jQuery.expr = {
	          // Can be adjusted by the user
	          cacheLength: 50,
	          createPseudo: markFunction,
	          match: matchExpr,
	          attrHandle: {},
	          find: {},
	          relative: {
	            ">": {
	              dir: "parentNode",
	              first: true
	            },
	            " ": {
	              dir: "parentNode"
	            },
	            "+": {
	              dir: "previousSibling",
	              first: true
	            },
	            "~": {
	              dir: "previousSibling"
	            }
	          },
	          preFilter: {
	            ATTR: function (match) {
	              match[1] = match[1].replace(runescape, funescape);

	              // Move the given value to match[3] whether quoted or unquoted
	              match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
	              if (match[2] === "~=") {
	                match[3] = " " + match[3] + " ";
	              }
	              return match.slice(0, 4);
	            },
	            CHILD: function (match) {
	              /* matches from matchExpr["CHILD"]
	              	1 type (only|nth|...)
	              	2 what (child|of-type)
	              	3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
	              	4 xn-component of xn+y argument ([+-]?\d*n|)
	              	5 sign of xn-component
	              	6 x of xn-component
	              	7 sign of y-component
	              	8 y of y-component
	              */
	              match[1] = match[1].toLowerCase();
	              if (match[1].slice(0, 3) === "nth") {
	                // nth-* requires argument
	                if (!match[3]) {
	                  find.error(match[0]);
	                }

	                // numeric x and y parameters for Expr.filter.CHILD
	                // remember that false/true cast respectively to 0/1
	                match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
	                match[5] = +(match[7] + match[8] || match[3] === "odd");

	                // other types prohibit arguments
	              } else if (match[3]) {
	                find.error(match[0]);
	              }
	              return match;
	            },
	            PSEUDO: function (match) {
	              var excess,
	                unquoted = !match[6] && match[2];
	              if (matchExpr.CHILD.test(match[0])) {
	                return null;
	              }

	              // Accept quoted arguments as-is
	              if (match[3]) {
	                match[2] = match[4] || match[5] || "";

	                // Strip excess characters from unquoted arguments
	              } else if (unquoted && rpseudo.test(unquoted) && (
	              // Get excess from tokenize (recursively)
	              excess = tokenize(unquoted, true)) && (
	              // advance to the next closing parenthesis
	              excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
	                // excess is a negative index
	                match[0] = match[0].slice(0, excess);
	                match[2] = unquoted.slice(0, excess);
	              }

	              // Return only captures needed by the pseudo filter method (type and argument)
	              return match.slice(0, 3);
	            }
	          },
	          filter: {
	            TAG: function (nodeNameSelector) {
	              var expectedNodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
	              return nodeNameSelector === "*" ? function () {
	                return true;
	              } : function (elem) {
	                return nodeName(elem, expectedNodeName);
	              };
	            },
	            CLASS: function (className) {
	              var pattern = classCache[className + " "];
	              return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
	                return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
	              });
	            },
	            ATTR: function (name, operator, check) {
	              return function (elem) {
	                var result = find.attr(elem, name);
	                if (result == null) {
	                  return operator === "!=";
	                }
	                if (!operator) {
	                  return true;
	                }
	                result += "";
	                if (operator === "=") {
	                  return result === check;
	                }
	                if (operator === "!=") {
	                  return result !== check;
	                }
	                if (operator === "^=") {
	                  return check && result.indexOf(check) === 0;
	                }
	                if (operator === "*=") {
	                  return check && result.indexOf(check) > -1;
	                }
	                if (operator === "$=") {
	                  return check && result.slice(-check.length) === check;
	                }
	                if (operator === "~=") {
	                  return (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1;
	                }
	                if (operator === "|=") {
	                  return result === check || result.slice(0, check.length + 1) === check + "-";
	                }
	                return false;
	              };
	            },
	            CHILD: function (type, what, _argument, first, last) {
	              var simple = type.slice(0, 3) !== "nth",
	                forward = type.slice(-4) !== "last",
	                ofType = what === "of-type";
	              return first === 1 && last === 0 ?
	              // Shortcut for :nth-*(n)
	              function (elem) {
	                return !!elem.parentNode;
	              } : function (elem, _context, xml) {
	                var cache,
	                  outerCache,
	                  node,
	                  nodeIndex,
	                  start,
	                  dir = simple !== forward ? "nextSibling" : "previousSibling",
	                  parent = elem.parentNode,
	                  name = ofType && elem.nodeName.toLowerCase(),
	                  useCache = !xml && !ofType,
	                  diff = false;
	                if (parent) {
	                  // :(first|last|only)-(child|of-type)
	                  if (simple) {
	                    while (dir) {
	                      node = elem;
	                      while (node = node[dir]) {
	                        if (ofType ? nodeName(node, name) : node.nodeType === 1) {
	                          return false;
	                        }
	                      }

	                      // Reverse direction for :only-* (if we haven't yet done so)
	                      start = dir = type === "only" && !start && "nextSibling";
	                    }
	                    return true;
	                  }
	                  start = [forward ? parent.firstChild : parent.lastChild];

	                  // non-xml :nth-child(...) stores cache data on `parent`
	                  if (forward && useCache) {
	                    // Seek `elem` from a previously-cached index
	                    outerCache = parent[expando] || (parent[expando] = {});
	                    cache = outerCache[type] || [];
	                    nodeIndex = cache[0] === dirruns && cache[1];
	                    diff = nodeIndex && cache[2];
	                    node = nodeIndex && parent.childNodes[nodeIndex];
	                    while (node = ++nodeIndex && node && node[dir] || (
	                    // Fallback to seeking `elem` from the start
	                    diff = nodeIndex = 0) || start.pop()) {
	                      // When found, cache indexes on `parent` and break
	                      if (node.nodeType === 1 && ++diff && node === elem) {
	                        outerCache[type] = [dirruns, nodeIndex, diff];
	                        break;
	                      }
	                    }
	                  } else {
	                    // Use previously-cached element index if available
	                    if (useCache) {
	                      outerCache = elem[expando] || (elem[expando] = {});
	                      cache = outerCache[type] || [];
	                      nodeIndex = cache[0] === dirruns && cache[1];
	                      diff = nodeIndex;
	                    }

	                    // xml :nth-child(...)
	                    // or :nth-last-child(...) or :nth(-last)?-of-type(...)
	                    if (diff === false) {
	                      // Use the same loop as above to seek `elem` from the start
	                      while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
	                        if ((ofType ? nodeName(node, name) : node.nodeType === 1) && ++diff) {
	                          // Cache the index of each encountered element
	                          if (useCache) {
	                            outerCache = node[expando] || (node[expando] = {});
	                            outerCache[type] = [dirruns, diff];
	                          }
	                          if (node === elem) {
	                            break;
	                          }
	                        }
	                      }
	                    }
	                  }

	                  // Incorporate the offset, then check against cycle size
	                  diff -= last;
	                  return diff === first || diff % first === 0 && diff / first >= 0;
	                }
	              };
	            },
	            PSEUDO: function (pseudo, argument) {
	              // pseudo-class names are case-insensitive
	              // https://www.w3.org/TR/selectors/#pseudo-classes
	              // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
	              // Remember that setFilters inherits from pseudos
	              var args,
	                fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || find.error("unsupported pseudo: " + pseudo);

	              // The user may use createPseudo to indicate that
	              // arguments are needed to create the filter function
	              // just as jQuery does
	              if (fn[expando]) {
	                return fn(argument);
	              }

	              // But maintain support for old signatures
	              if (fn.length > 1) {
	                args = [pseudo, pseudo, "", argument];
	                return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
	                  var idx,
	                    matched = fn(seed, argument),
	                    i = matched.length;
	                  while (i--) {
	                    idx = indexOf.call(seed, matched[i]);
	                    seed[idx] = !(matches[idx] = matched[i]);
	                  }
	                }) : function (elem) {
	                  return fn(elem, 0, args);
	                };
	              }
	              return fn;
	            }
	          },
	          pseudos: {
	            // Potentially complex pseudos
	            not: markFunction(function (selector) {
	              // Trim the selector passed to compile
	              // to avoid treating leading and trailing
	              // spaces as combinators
	              var input = [],
	                results = [],
	                matcher = compile(selector.replace(rtrimCSS, "$1"));
	              return matcher[expando] ? markFunction(function (seed, matches, _context, xml) {
	                var elem,
	                  unmatched = matcher(seed, null, xml, []),
	                  i = seed.length;

	                // Match elements unmatched by `matcher`
	                while (i--) {
	                  if (elem = unmatched[i]) {
	                    seed[i] = !(matches[i] = elem);
	                  }
	                }
	              }) : function (elem, _context, xml) {
	                input[0] = elem;
	                matcher(input, null, xml, results);

	                // Don't keep the element
	                // (see https://github.com/jquery/sizzle/issues/299)
	                input[0] = null;
	                return !results.pop();
	              };
	            }),
	            has: markFunction(function (selector) {
	              return function (elem) {
	                return find(selector, elem).length > 0;
	              };
	            }),
	            contains: markFunction(function (text) {
	              text = text.replace(runescape, funescape);
	              return function (elem) {
	                return (elem.textContent || jQuery.text(elem)).indexOf(text) > -1;
	              };
	            }),
	            // "Whether an element is represented by a :lang() selector
	            // is based solely on the element's language value
	            // being equal to the identifier C,
	            // or beginning with the identifier C immediately followed by "-".
	            // The matching of C against the element's language value is performed case-insensitively.
	            // The identifier C does not have to be a valid language name."
	            // https://www.w3.org/TR/selectors/#lang-pseudo
	            lang: markFunction(function (lang) {
	              // lang value must be a valid identifier
	              if (!ridentifier.test(lang || "")) {
	                find.error("unsupported lang: " + lang);
	              }
	              lang = lang.replace(runescape, funescape).toLowerCase();
	              return function (elem) {
	                var elemLang;
	                do {
	                  if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
	                    elemLang = elemLang.toLowerCase();
	                    return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
	                  }
	                } while ((elem = elem.parentNode) && elem.nodeType === 1);
	                return false;
	              };
	            }),
	            // Miscellaneous
	            target: function (elem) {
	              var hash = window.location && window.location.hash;
	              return hash && hash.slice(1) === elem.id;
	            },
	            root: function (elem) {
	              return elem === documentElement;
	            },
	            focus: function (elem) {
	              return elem === safeActiveElement() && document.hasFocus() && !!(elem.type || elem.href || ~elem.tabIndex);
	            },
	            // Boolean properties
	            enabled: createDisabledPseudo(false),
	            disabled: createDisabledPseudo(true),
	            checked: function (elem) {
	              // In CSS3, :checked should return both checked and selected elements
	              // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
	              return nodeName(elem, "input") && !!elem.checked || nodeName(elem, "option") && !!elem.selected;
	            },
	            selected: function (elem) {
	              // Support: IE <=11+
	              // Accessing the selectedIndex property
	              // forces the browser to treat the default option as
	              // selected when in an optgroup.
	              if (elem.parentNode) {
	                // eslint-disable-next-line no-unused-expressions
	                elem.parentNode.selectedIndex;
	              }
	              return elem.selected === true;
	            },
	            // Contents
	            empty: function (elem) {
	              // https://www.w3.org/TR/selectors/#empty-pseudo
	              // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
	              //   but not by others (comment: 8; processing instruction: 7; etc.)
	              // nodeType < 6 works because attributes (2) do not appear as children
	              for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
	                if (elem.nodeType < 6) {
	                  return false;
	                }
	              }
	              return true;
	            },
	            parent: function (elem) {
	              return !Expr.pseudos.empty(elem);
	            },
	            // Element/input types
	            header: function (elem) {
	              return rheader.test(elem.nodeName);
	            },
	            input: function (elem) {
	              return rinputs.test(elem.nodeName);
	            },
	            button: function (elem) {
	              return nodeName(elem, "input") && elem.type === "button" || nodeName(elem, "button");
	            },
	            text: function (elem) {
	              var attr;
	              return nodeName(elem, "input") && elem.type === "text" && (
	              // Support: IE <10 only
	              // New HTML5 attribute values (e.g., "search") appear
	              // with elem.type === "text"
	              (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
	            },
	            // Position-in-collection
	            first: createPositionalPseudo(function () {
	              return [0];
	            }),
	            last: createPositionalPseudo(function (_matchIndexes, length) {
	              return [length - 1];
	            }),
	            eq: createPositionalPseudo(function (_matchIndexes, length, argument) {
	              return [argument < 0 ? argument + length : argument];
	            }),
	            even: createPositionalPseudo(function (matchIndexes, length) {
	              var i = 0;
	              for (; i < length; i += 2) {
	                matchIndexes.push(i);
	              }
	              return matchIndexes;
	            }),
	            odd: createPositionalPseudo(function (matchIndexes, length) {
	              var i = 1;
	              for (; i < length; i += 2) {
	                matchIndexes.push(i);
	              }
	              return matchIndexes;
	            }),
	            lt: createPositionalPseudo(function (matchIndexes, length, argument) {
	              var i;
	              if (argument < 0) {
	                i = argument + length;
	              } else if (argument > length) {
	                i = length;
	              } else {
	                i = argument;
	              }
	              for (; --i >= 0;) {
	                matchIndexes.push(i);
	              }
	              return matchIndexes;
	            }),
	            gt: createPositionalPseudo(function (matchIndexes, length, argument) {
	              var i = argument < 0 ? argument + length : argument;
	              for (; ++i < length;) {
	                matchIndexes.push(i);
	              }
	              return matchIndexes;
	            })
	          }
	        };
	        Expr.pseudos.nth = Expr.pseudos.eq;

	        // Add button/input type pseudos
	        for (i in {
	          radio: true,
	          checkbox: true,
	          file: true,
	          password: true,
	          image: true
	        }) {
	          Expr.pseudos[i] = createInputPseudo(i);
	        }
	        for (i in {
	          submit: true,
	          reset: true
	        }) {
	          Expr.pseudos[i] = createButtonPseudo(i);
	        }

	        // Easy API for creating new setFilters
	        function setFilters() {}
	        setFilters.prototype = Expr.filters = Expr.pseudos;
	        Expr.setFilters = new setFilters();
	        function tokenize(selector, parseOnly) {
	          var matched,
	            match,
	            tokens,
	            type,
	            soFar,
	            groups,
	            preFilters,
	            cached = tokenCache[selector + " "];
	          if (cached) {
	            return parseOnly ? 0 : cached.slice(0);
	          }
	          soFar = selector;
	          groups = [];
	          preFilters = Expr.preFilter;
	          while (soFar) {
	            // Comma and first run
	            if (!matched || (match = rcomma.exec(soFar))) {
	              if (match) {
	                // Don't consume trailing commas as valid
	                soFar = soFar.slice(match[0].length) || soFar;
	              }
	              groups.push(tokens = []);
	            }
	            matched = false;

	            // Combinators
	            if (match = rleadingCombinator.exec(soFar)) {
	              matched = match.shift();
	              tokens.push({
	                value: matched,
	                // Cast descendant combinators to space
	                type: match[0].replace(rtrimCSS, " ")
	              });
	              soFar = soFar.slice(matched.length);
	            }

	            // Filters
	            for (type in Expr.filter) {
	              if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
	                matched = match.shift();
	                tokens.push({
	                  value: matched,
	                  type: type,
	                  matches: match
	                });
	                soFar = soFar.slice(matched.length);
	              }
	            }
	            if (!matched) {
	              break;
	            }
	          }

	          // Return the length of the invalid excess
	          // if we're just parsing
	          // Otherwise, throw an error or return tokens
	          if (parseOnly) {
	            return soFar.length;
	          }
	          return soFar ? find.error(selector) :
	          // Cache the tokens
	          tokenCache(selector, groups).slice(0);
	        }
	        function toSelector(tokens) {
	          var i = 0,
	            len = tokens.length,
	            selector = "";
	          for (; i < len; i++) {
	            selector += tokens[i].value;
	          }
	          return selector;
	        }
	        function addCombinator(matcher, combinator, base) {
	          var dir = combinator.dir,
	            skip = combinator.next,
	            key = skip || dir,
	            checkNonElements = base && key === "parentNode",
	            doneName = done++;
	          return combinator.first ?
	          // Check against closest ancestor/preceding element
	          function (elem, context, xml) {
	            while (elem = elem[dir]) {
	              if (elem.nodeType === 1 || checkNonElements) {
	                return matcher(elem, context, xml);
	              }
	            }
	            return false;
	          } :
	          // Check against all ancestor/preceding elements
	          function (elem, context, xml) {
	            var oldCache,
	              outerCache,
	              newCache = [dirruns, doneName];

	            // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
	            if (xml) {
	              while (elem = elem[dir]) {
	                if (elem.nodeType === 1 || checkNonElements) {
	                  if (matcher(elem, context, xml)) {
	                    return true;
	                  }
	                }
	              }
	            } else {
	              while (elem = elem[dir]) {
	                if (elem.nodeType === 1 || checkNonElements) {
	                  outerCache = elem[expando] || (elem[expando] = {});
	                  if (skip && nodeName(elem, skip)) {
	                    elem = elem[dir] || elem;
	                  } else if ((oldCache = outerCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
	                    // Assign to newCache so results back-propagate to previous elements
	                    return newCache[2] = oldCache[2];
	                  } else {
	                    // Reuse newcache so results back-propagate to previous elements
	                    outerCache[key] = newCache;

	                    // A match means we're done; a fail means we have to keep checking
	                    if (newCache[2] = matcher(elem, context, xml)) {
	                      return true;
	                    }
	                  }
	                }
	              }
	            }
	            return false;
	          };
	        }
	        function elementMatcher(matchers) {
	          return matchers.length > 1 ? function (elem, context, xml) {
	            var i = matchers.length;
	            while (i--) {
	              if (!matchers[i](elem, context, xml)) {
	                return false;
	              }
	            }
	            return true;
	          } : matchers[0];
	        }
	        function multipleContexts(selector, contexts, results) {
	          var i = 0,
	            len = contexts.length;
	          for (; i < len; i++) {
	            find(selector, contexts[i], results);
	          }
	          return results;
	        }
	        function condense(unmatched, map, filter, context, xml) {
	          var elem,
	            newUnmatched = [],
	            i = 0,
	            len = unmatched.length,
	            mapped = map != null;
	          for (; i < len; i++) {
	            if (elem = unmatched[i]) {
	              if (!filter || filter(elem, context, xml)) {
	                newUnmatched.push(elem);
	                if (mapped) {
	                  map.push(i);
	                }
	              }
	            }
	          }
	          return newUnmatched;
	        }
	        function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
	          if (postFilter && !postFilter[expando]) {
	            postFilter = setMatcher(postFilter);
	          }
	          if (postFinder && !postFinder[expando]) {
	            postFinder = setMatcher(postFinder, postSelector);
	          }
	          return markFunction(function (seed, results, context, xml) {
	            var temp,
	              i,
	              elem,
	              matcherOut,
	              preMap = [],
	              postMap = [],
	              preexisting = results.length,
	              // Get initial elements from seed or context
	              elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
	              // Prefilter to get matcher input, preserving a map for seed-results synchronization
	              matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems;
	            if (matcher) {
	              // If we have a postFinder, or filtered seed, or non-seed postFilter
	              // or preexisting results,
	              matcherOut = postFinder || (seed ? preFilter : preexisting || postFilter) ?
	              // ...intermediate processing is necessary
	              [] :
	              // ...otherwise use results directly
	              results;

	              // Find primary matches
	              matcher(matcherIn, matcherOut, context, xml);
	            } else {
	              matcherOut = matcherIn;
	            }

	            // Apply postFilter
	            if (postFilter) {
	              temp = condense(matcherOut, postMap);
	              postFilter(temp, [], context, xml);

	              // Un-match failing elements by moving them back to matcherIn
	              i = temp.length;
	              while (i--) {
	                if (elem = temp[i]) {
	                  matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
	                }
	              }
	            }
	            if (seed) {
	              if (postFinder || preFilter) {
	                if (postFinder) {
	                  // Get the final matcherOut by condensing this intermediate into postFinder contexts
	                  temp = [];
	                  i = matcherOut.length;
	                  while (i--) {
	                    if (elem = matcherOut[i]) {
	                      // Restore matcherIn since elem is not yet a final match
	                      temp.push(matcherIn[i] = elem);
	                    }
	                  }
	                  postFinder(null, matcherOut = [], temp, xml);
	                }

	                // Move matched elements from seed to results to keep them synchronized
	                i = matcherOut.length;
	                while (i--) {
	                  if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) {
	                    seed[temp] = !(results[temp] = elem);
	                  }
	                }
	              }

	              // Add elements to results, through postFinder if defined
	            } else {
	              matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
	              if (postFinder) {
	                postFinder(null, results, matcherOut, xml);
	              } else {
	                push.apply(results, matcherOut);
	              }
	            }
	          });
	        }
	        function matcherFromTokens(tokens) {
	          var checkContext,
	            matcher,
	            j,
	            len = tokens.length,
	            leadingRelative = Expr.relative[tokens[0].type],
	            implicitRelative = leadingRelative || Expr.relative[" "],
	            i = leadingRelative ? 1 : 0,
	            // The foundational matcher ensures that elements are reachable from top-level context(s)
	            matchContext = addCombinator(function (elem) {
	              return elem === checkContext;
	            }, implicitRelative, true),
	            matchAnyContext = addCombinator(function (elem) {
	              return indexOf.call(checkContext, elem) > -1;
	            }, implicitRelative, true),
	            matchers = [function (elem, context, xml) {
	              // Support: IE 11+, Edge 17 - 18+
	              // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	              // two documents; shallow comparisons work.
	              // eslint-disable-next-line eqeqeq
	              var ret = !leadingRelative && (xml || context != outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));

	              // Avoid hanging onto element
	              // (see https://github.com/jquery/sizzle/issues/299)
	              checkContext = null;
	              return ret;
	            }];
	          for (; i < len; i++) {
	            if (matcher = Expr.relative[tokens[i].type]) {
	              matchers = [addCombinator(elementMatcher(matchers), matcher)];
	            } else {
	              matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);

	              // Return special upon seeing a positional matcher
	              if (matcher[expando]) {
	                // Find the next relative operator (if any) for proper handling
	                j = ++i;
	                for (; j < len; j++) {
	                  if (Expr.relative[tokens[j].type]) {
	                    break;
	                  }
	                }
	                return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(
	                // If the preceding token was a descendant combinator, insert an implicit any-element `*`
	                tokens.slice(0, i - 1).concat({
	                  value: tokens[i - 2].type === " " ? "*" : ""
	                })).replace(rtrimCSS, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
	              }
	              matchers.push(matcher);
	            }
	          }
	          return elementMatcher(matchers);
	        }
	        function matcherFromGroupMatchers(elementMatchers, setMatchers) {
	          var bySet = setMatchers.length > 0,
	            byElement = elementMatchers.length > 0,
	            superMatcher = function (seed, context, xml, results, outermost) {
	              var elem,
	                j,
	                matcher,
	                matchedCount = 0,
	                i = "0",
	                unmatched = seed && [],
	                setMatched = [],
	                contextBackup = outermostContext,
	                // We must always have either seed elements or outermost context
	                elems = seed || byElement && Expr.find.TAG("*", outermost),
	                // Use integer dirruns iff this is the outermost matcher
	                dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
	                len = elems.length;
	              if (outermost) {
	                // Support: IE 11+, Edge 17 - 18+
	                // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	                // two documents; shallow comparisons work.
	                // eslint-disable-next-line eqeqeq
	                outermostContext = context == document || context || outermost;
	              }

	              // Add elements passing elementMatchers directly to results
	              // Support: iOS <=7 - 9 only
	              // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching
	              // elements by id. (see trac-14142)
	              for (; i !== len && (elem = elems[i]) != null; i++) {
	                if (byElement && elem) {
	                  j = 0;

	                  // Support: IE 11+, Edge 17 - 18+
	                  // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
	                  // two documents; shallow comparisons work.
	                  // eslint-disable-next-line eqeqeq
	                  if (!context && elem.ownerDocument != document) {
	                    setDocument(elem);
	                    xml = !documentIsHTML;
	                  }
	                  while (matcher = elementMatchers[j++]) {
	                    if (matcher(elem, context || document, xml)) {
	                      push.call(results, elem);
	                      break;
	                    }
	                  }
	                  if (outermost) {
	                    dirruns = dirrunsUnique;
	                  }
	                }

	                // Track unmatched elements for set filters
	                if (bySet) {
	                  // They will have gone through all possible matchers
	                  if (elem = !matcher && elem) {
	                    matchedCount--;
	                  }

	                  // Lengthen the array for every element, matched or not
	                  if (seed) {
	                    unmatched.push(elem);
	                  }
	                }
	              }

	              // `i` is now the count of elements visited above, and adding it to `matchedCount`
	              // makes the latter nonnegative.
	              matchedCount += i;

	              // Apply set filters to unmatched elements
	              // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
	              // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
	              // no element matchers and no seed.
	              // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
	              // case, which will result in a "00" `matchedCount` that differs from `i` but is also
	              // numerically zero.
	              if (bySet && i !== matchedCount) {
	                j = 0;
	                while (matcher = setMatchers[j++]) {
	                  matcher(unmatched, setMatched, context, xml);
	                }
	                if (seed) {
	                  // Reintegrate element matches to eliminate the need for sorting
	                  if (matchedCount > 0) {
	                    while (i--) {
	                      if (!(unmatched[i] || setMatched[i])) {
	                        setMatched[i] = pop.call(results);
	                      }
	                    }
	                  }

	                  // Discard index placeholder values to get only actual matches
	                  setMatched = condense(setMatched);
	                }

	                // Add matches to results
	                push.apply(results, setMatched);

	                // Seedless set matches succeeding multiple successful matchers stipulate sorting
	                if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
	                  jQuery.uniqueSort(results);
	                }
	              }

	              // Override manipulation of globals by nested matchers
	              if (outermost) {
	                dirruns = dirrunsUnique;
	                outermostContext = contextBackup;
	              }
	              return unmatched;
	            };
	          return bySet ? markFunction(superMatcher) : superMatcher;
	        }
	        function compile(selector, match /* Internal Use Only */) {
	          var i,
	            setMatchers = [],
	            elementMatchers = [],
	            cached = compilerCache[selector + " "];
	          if (!cached) {
	            // Generate a function of recursive functions that can be used to check each element
	            if (!match) {
	              match = tokenize(selector);
	            }
	            i = match.length;
	            while (i--) {
	              cached = matcherFromTokens(match[i]);
	              if (cached[expando]) {
	                setMatchers.push(cached);
	              } else {
	                elementMatchers.push(cached);
	              }
	            }

	            // Cache the compiled function
	            cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));

	            // Save selector and tokenization
	            cached.selector = selector;
	          }
	          return cached;
	        }

	        /**
	         * A low-level selection function that works with jQuery's compiled
	         *  selector functions
	         * @param {String|Function} selector A selector or a pre-compiled
	         *  selector function built with jQuery selector compile
	         * @param {Element} context
	         * @param {Array} [results]
	         * @param {Array} [seed] A set of elements to match against
	         */
	        function select(selector, context, results, seed) {
	          var i,
	            tokens,
	            token,
	            type,
	            find,
	            compiled = typeof selector === "function" && selector,
	            match = !seed && tokenize(selector = compiled.selector || selector);
	          results = results || [];

	          // Try to minimize operations if there is only one selector in the list and no seed
	          // (the latter of which guarantees us context)
	          if (match.length === 1) {
	            // Reduce context if the leading compound selector is an ID
	            tokens = match[0] = match[0].slice(0);
	            if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
	              context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0];
	              if (!context) {
	                return results;

	                // Precompiled matchers will still verify ancestry, so step up a level
	              } else if (compiled) {
	                context = context.parentNode;
	              }
	              selector = selector.slice(tokens.shift().value.length);
	            }

	            // Fetch a seed set for right-to-left matching
	            i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
	            while (i--) {
	              token = tokens[i];

	              // Abort if we hit a combinator
	              if (Expr.relative[type = token.type]) {
	                break;
	              }
	              if (find = Expr.find[type]) {
	                // Search, expanding context for leading sibling combinators
	                if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {
	                  // If seed is empty or no tokens remain, we can return early
	                  tokens.splice(i, 1);
	                  selector = seed.length && toSelector(tokens);
	                  if (!selector) {
	                    push.apply(results, seed);
	                    return results;
	                  }
	                  break;
	                }
	              }
	            }
	          }

	          // Compile and execute a filtering function if one is not provided
	          // Provide `match` to avoid retokenization if we modified the selector above
	          (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);
	          return results;
	        }

	        // One-time assignments

	        // Support: Android <=4.0 - 4.1+
	        // Sort stability
	        support.sortStable = expando.split("").sort(sortOrder).join("") === expando;

	        // Initialize against the default document
	        setDocument();

	        // Support: Android <=4.0 - 4.1+
	        // Detached nodes confoundingly follow *each other*
	        support.sortDetached = assert(function (el) {
	          // Should return 1, but returns 4 (following)
	          return el.compareDocumentPosition(document.createElement("fieldset")) & 1;
	        });
	        jQuery.find = find;

	        // Deprecated
	        jQuery.expr[":"] = jQuery.expr.pseudos;
	        jQuery.unique = jQuery.uniqueSort;

	        // These have always been private, but they used to be documented as part of
	        // Sizzle so let's maintain them for now for backwards compatibility purposes.
	        find.compile = compile;
	        find.select = select;
	        find.setDocument = setDocument;
	        find.tokenize = tokenize;
	        find.escape = jQuery.escapeSelector;
	        find.getText = jQuery.text;
	        find.isXML = jQuery.isXMLDoc;
	        find.selectors = jQuery.expr;
	        find.support = jQuery.support;
	        find.uniqueSort = jQuery.uniqueSort;

	        /* eslint-enable */
	      })();
	      var dir = function (elem, dir, until) {
	        var matched = [],
	          truncate = until !== undefined;
	        while ((elem = elem[dir]) && elem.nodeType !== 9) {
	          if (elem.nodeType === 1) {
	            if (truncate && jQuery(elem).is(until)) {
	              break;
	            }
	            matched.push(elem);
	          }
	        }
	        return matched;
	      };
	      var siblings = function (n, elem) {
	        var matched = [];
	        for (; n; n = n.nextSibling) {
	          if (n.nodeType === 1 && n !== elem) {
	            matched.push(n);
	          }
	        }
	        return matched;
	      };
	      var rneedsContext = jQuery.expr.match.needsContext;
	      var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;

	      // Implement the identical functionality for filter and not
	      function winnow(elements, qualifier, not) {
	        if (isFunction(qualifier)) {
	          return jQuery.grep(elements, function (elem, i) {
	            return !!qualifier.call(elem, i, elem) !== not;
	          });
	        }

	        // Single element
	        if (qualifier.nodeType) {
	          return jQuery.grep(elements, function (elem) {
	            return elem === qualifier !== not;
	          });
	        }

	        // Arraylike of elements (jQuery, arguments, Array)
	        if (typeof qualifier !== "string") {
	          return jQuery.grep(elements, function (elem) {
	            return indexOf.call(qualifier, elem) > -1 !== not;
	          });
	        }

	        // Filtered directly for both simple and complex selectors
	        return jQuery.filter(qualifier, elements, not);
	      }
	      jQuery.filter = function (expr, elems, not) {
	        var elem = elems[0];
	        if (not) {
	          expr = ":not(" + expr + ")";
	        }
	        if (elems.length === 1 && elem.nodeType === 1) {
	          return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
	        }
	        return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
	          return elem.nodeType === 1;
	        }));
	      };
	      jQuery.fn.extend({
	        find: function (selector) {
	          var i,
	            ret,
	            len = this.length,
	            self = this;
	          if (typeof selector !== "string") {
	            return this.pushStack(jQuery(selector).filter(function () {
	              for (i = 0; i < len; i++) {
	                if (jQuery.contains(self[i], this)) {
	                  return true;
	                }
	              }
	            }));
	          }
	          ret = this.pushStack([]);
	          for (i = 0; i < len; i++) {
	            jQuery.find(selector, self[i], ret);
	          }
	          return len > 1 ? jQuery.uniqueSort(ret) : ret;
	        },
	        filter: function (selector) {
	          return this.pushStack(winnow(this, selector || [], false));
	        },
	        not: function (selector) {
	          return this.pushStack(winnow(this, selector || [], true));
	        },
	        is: function (selector) {
	          return !!winnow(this,
	          // If this is a positional/relative selector, check membership in the returned set
	          // so $("p:first").is("p:last") won't return true for a doc with two "p".
	          typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
	        }
	      });

	      // Initialize a jQuery object

	      // A central reference to the root jQuery(document)
	      var rootjQuery,
	        // A simple way to check for HTML strings
	        // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
	        // Strict HTML recognition (trac-11290: must start with <)
	        // Shortcut simple #id case for speed
	        rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
	        init = jQuery.fn.init = function (selector, context, root) {
	          var match, elem;

	          // HANDLE: $(""), $(null), $(undefined), $(false)
	          if (!selector) {
	            return this;
	          }

	          // Method init() accepts an alternate rootjQuery
	          // so migrate can support jQuery.sub (gh-2101)
	          root = root || rootjQuery;

	          // Handle HTML strings
	          if (typeof selector === "string") {
	            if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
	              // Assume that strings that start and end with <> are HTML and skip the regex check
	              match = [null, selector, null];
	            } else {
	              match = rquickExpr.exec(selector);
	            }

	            // Match html or make sure no context is specified for #id
	            if (match && (match[1] || !context)) {
	              // HANDLE: $(html) -> $(array)
	              if (match[1]) {
	                context = context instanceof jQuery ? context[0] : context;

	                // Option to run scripts is true for back-compat
	                // Intentionally let the error be thrown if parseHTML is not present
	                jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));

	                // HANDLE: $(html, props)
	                if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
	                  for (match in context) {
	                    // Properties of context are called as methods if possible
	                    if (isFunction(this[match])) {
	                      this[match](context[match]);

	                      // ...and otherwise set as attributes
	                    } else {
	                      this.attr(match, context[match]);
	                    }
	                  }
	                }
	                return this;

	                // HANDLE: $(#id)
	              } else {
	                elem = document.getElementById(match[2]);
	                if (elem) {
	                  // Inject the element directly into the jQuery object
	                  this[0] = elem;
	                  this.length = 1;
	                }
	                return this;
	              }

	              // HANDLE: $(expr, $(...))
	            } else if (!context || context.jquery) {
	              return (context || root).find(selector);

	              // HANDLE: $(expr, context)
	              // (which is just equivalent to: $(context).find(expr)
	            } else {
	              return this.constructor(context).find(selector);
	            }

	            // HANDLE: $(DOMElement)
	          } else if (selector.nodeType) {
	            this[0] = selector;
	            this.length = 1;
	            return this;

	            // HANDLE: $(function)
	            // Shortcut for document ready
	          } else if (isFunction(selector)) {
	            return root.ready !== undefined ? root.ready(selector) :
	            // Execute immediately if ready is not present
	            selector(jQuery);
	          }
	          return jQuery.makeArray(selector, this);
	        };

	      // Give the init function the jQuery prototype for later instantiation
	      init.prototype = jQuery.fn;

	      // Initialize central reference
	      rootjQuery = jQuery(document);
	      var rparentsprev = /^(?:parents|prev(?:Until|All))/,
	        // Methods guaranteed to produce a unique set when starting from a unique set
	        guaranteedUnique = {
	          children: true,
	          contents: true,
	          next: true,
	          prev: true
	        };
	      jQuery.fn.extend({
	        has: function (target) {
	          var targets = jQuery(target, this),
	            l = targets.length;
	          return this.filter(function () {
	            var i = 0;
	            for (; i < l; i++) {
	              if (jQuery.contains(this, targets[i])) {
	                return true;
	              }
	            }
	          });
	        },
	        closest: function (selectors, context) {
	          var cur,
	            i = 0,
	            l = this.length,
	            matched = [],
	            targets = typeof selectors !== "string" && jQuery(selectors);

	          // Positional selectors never match, since there's no _selection_ context
	          if (!rneedsContext.test(selectors)) {
	            for (; i < l; i++) {
	              for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
	                // Always skip document fragments
	                if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 :
	                // Don't pass non-elements to jQuery#find
	                cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
	                  matched.push(cur);
	                  break;
	                }
	              }
	            }
	          }
	          return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
	        },
	        // Determine the position of an element within the set
	        index: function (elem) {
	          // No argument, return index in parent
	          if (!elem) {
	            return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
	          }

	          // Index in selector
	          if (typeof elem === "string") {
	            return indexOf.call(jQuery(elem), this[0]);
	          }

	          // Locate the position of the desired element
	          return indexOf.call(this,
	          // If it receives a jQuery object, the first element is used
	          elem.jquery ? elem[0] : elem);
	        },
	        add: function (selector, context) {
	          return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context))));
	        },
	        addBack: function (selector) {
	          return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
	        }
	      });
	      function sibling(cur, dir) {
	        while ((cur = cur[dir]) && cur.nodeType !== 1) {}
	        return cur;
	      }
	      jQuery.each({
	        parent: function (elem) {
	          var parent = elem.parentNode;
	          return parent && parent.nodeType !== 11 ? parent : null;
	        },
	        parents: function (elem) {
	          return dir(elem, "parentNode");
	        },
	        parentsUntil: function (elem, _i, until) {
	          return dir(elem, "parentNode", until);
	        },
	        next: function (elem) {
	          return sibling(elem, "nextSibling");
	        },
	        prev: function (elem) {
	          return sibling(elem, "previousSibling");
	        },
	        nextAll: function (elem) {
	          return dir(elem, "nextSibling");
	        },
	        prevAll: function (elem) {
	          return dir(elem, "previousSibling");
	        },
	        nextUntil: function (elem, _i, until) {
	          return dir(elem, "nextSibling", until);
	        },
	        prevUntil: function (elem, _i, until) {
	          return dir(elem, "previousSibling", until);
	        },
	        siblings: function (elem) {
	          return siblings((elem.parentNode || {}).firstChild, elem);
	        },
	        children: function (elem) {
	          return siblings(elem.firstChild);
	        },
	        contents: function (elem) {
	          if (elem.contentDocument != null &&
	          // Support: IE 11+
	          // <object> elements with no `data` attribute has an object
	          // `contentDocument` with a `null` prototype.
	          getProto(elem.contentDocument)) {
	            return elem.contentDocument;
	          }

	          // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
	          // Treat the template element as a regular one in browsers that
	          // don't support it.
	          if (nodeName(elem, "template")) {
	            elem = elem.content || elem;
	          }
	          return jQuery.merge([], elem.childNodes);
	        }
	      }, function (name, fn) {
	        jQuery.fn[name] = function (until, selector) {
	          var matched = jQuery.map(this, fn, until);
	          if (name.slice(-5) !== "Until") {
	            selector = until;
	          }
	          if (selector && typeof selector === "string") {
	            matched = jQuery.filter(selector, matched);
	          }
	          if (this.length > 1) {
	            // Remove duplicates
	            if (!guaranteedUnique[name]) {
	              jQuery.uniqueSort(matched);
	            }

	            // Reverse order for parents* and prev-derivatives
	            if (rparentsprev.test(name)) {
	              matched.reverse();
	            }
	          }
	          return this.pushStack(matched);
	        };
	      });
	      var rnothtmlwhite = /[^\x20\t\r\n\f]+/g;

	      // Convert String-formatted options into Object-formatted ones
	      function createOptions(options) {
	        var object = {};
	        jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
	          object[flag] = true;
	        });
	        return object;
	      }

	      /*
	       * Create a callback list using the following parameters:
	       *
	       *	options: an optional list of space-separated options that will change how
	       *			the callback list behaves or a more traditional option object
	       *
	       * By default a callback list will act like an event callback list and can be
	       * "fired" multiple times.
	       *
	       * Possible options:
	       *
	       *	once:			will ensure the callback list can only be fired once (like a Deferred)
	       *
	       *	memory:			will keep track of previous values and will call any callback added
	       *					after the list has been fired right away with the latest "memorized"
	       *					values (like a Deferred)
	       *
	       *	unique:			will ensure a callback can only be added once (no duplicate in the list)
	       *
	       *	stopOnFalse:	interrupt callings when a callback returns false
	       *
	       */
	      jQuery.Callbacks = function (options) {
	        // Convert options from String-formatted to Object-formatted if needed
	        // (we check in cache first)
	        options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options);
	        var
	          // Flag to know if list is currently firing
	          firing,
	          // Last fire value for non-forgettable lists
	          memory,
	          // Flag to know if list was already fired
	          fired,
	          // Flag to prevent firing
	          locked,
	          // Actual callback list
	          list = [],
	          // Queue of execution data for repeatable lists
	          queue = [],
	          // Index of currently firing callback (modified by add/remove as needed)
	          firingIndex = -1,
	          // Fire callbacks
	          fire = function () {
	            // Enforce single-firing
	            locked = locked || options.once;

	            // Execute callbacks for all pending executions,
	            // respecting firingIndex overrides and runtime changes
	            fired = firing = true;
	            for (; queue.length; firingIndex = -1) {
	              memory = queue.shift();
	              while (++firingIndex < list.length) {
	                // Run callback and check for early termination
	                if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {
	                  // Jump to end and forget the data so .add doesn't re-fire
	                  firingIndex = list.length;
	                  memory = false;
	                }
	              }
	            }

	            // Forget the data if we're done with it
	            if (!options.memory) {
	              memory = false;
	            }
	            firing = false;

	            // Clean up if we're done firing for good
	            if (locked) {
	              // Keep an empty list if we have data for future add calls
	              if (memory) {
	                list = [];

	                // Otherwise, this object is spent
	              } else {
	                list = "";
	              }
	            }
	          },
	          // Actual Callbacks object
	          self = {
	            // Add a callback or a collection of callbacks to the list
	            add: function () {
	              if (list) {
	                // If we have memory from a past run, we should fire after adding
	                if (memory && !firing) {
	                  firingIndex = list.length - 1;
	                  queue.push(memory);
	                }
	                (function add(args) {
	                  jQuery.each(args, function (_, arg) {
	                    if (isFunction(arg)) {
	                      if (!options.unique || !self.has(arg)) {
	                        list.push(arg);
	                      }
	                    } else if (arg && arg.length && toType(arg) !== "string") {
	                      // Inspect recursively
	                      add(arg);
	                    }
	                  });
	                })(arguments);
	                if (memory && !firing) {
	                  fire();
	                }
	              }
	              return this;
	            },
	            // Remove a callback from the list
	            remove: function () {
	              jQuery.each(arguments, function (_, arg) {
	                var index;
	                while ((index = jQuery.inArray(arg, list, index)) > -1) {
	                  list.splice(index, 1);

	                  // Handle firing indexes
	                  if (index <= firingIndex) {
	                    firingIndex--;
	                  }
	                }
	              });
	              return this;
	            },
	            // Check if a given callback is in the list.
	            // If no argument is given, return whether or not list has callbacks attached.
	            has: function (fn) {
	              return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0;
	            },
	            // Remove all callbacks from the list
	            empty: function () {
	              if (list) {
	                list = [];
	              }
	              return this;
	            },
	            // Disable .fire and .add
	            // Abort any current/pending executions
	            // Clear all callbacks and values
	            disable: function () {
	              locked = queue = [];
	              list = memory = "";
	              return this;
	            },
	            disabled: function () {
	              return !list;
	            },
	            // Disable .fire
	            // Also disable .add unless we have memory (since it would have no effect)
	            // Abort any pending executions
	            lock: function () {
	              locked = queue = [];
	              if (!memory && !firing) {
	                list = memory = "";
	              }
	              return this;
	            },
	            locked: function () {
	              return !!locked;
	            },
	            // Call all callbacks with the given context and arguments
	            fireWith: function (context, args) {
	              if (!locked) {
	                args = args || [];
	                args = [context, args.slice ? args.slice() : args];
	                queue.push(args);
	                if (!firing) {
	                  fire();
	                }
	              }
	              return this;
	            },
	            // Call all the callbacks with the given arguments
	            fire: function () {
	              self.fireWith(this, arguments);
	              return this;
	            },
	            // To know if the callbacks have already been called at least once
	            fired: function () {
	              return !!fired;
	            }
	          };
	        return self;
	      };
	      function Identity(v) {
	        return v;
	      }
	      function Thrower(ex) {
	        throw ex;
	      }
	      function adoptValue(value, resolve, reject, noValue) {
	        var method;
	        try {
	          // Check for promise aspect first to privilege synchronous behavior
	          if (value && isFunction(method = value.promise)) {
	            method.call(value).done(resolve).fail(reject);

	            // Other thenables
	          } else if (value && isFunction(method = value.then)) {
	            method.call(value, resolve, reject);

	            // Other non-thenables
	          } else {
	            // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
	            // * false: [ value ].slice( 0 ) => resolve( value )
	            // * true: [ value ].slice( 1 ) => resolve()
	            resolve.apply(undefined, [value].slice(noValue));
	          }

	          // For Promises/A+, convert exceptions into rejections
	          // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
	          // Deferred#then to conditionally suppress rejection.
	        } catch (value) {
	          // Support: Android 4.0 only
	          // Strict mode functions invoked without .call/.apply get global-object context
	          reject.apply(undefined, [value]);
	        }
	      }
	      jQuery.extend({
	        Deferred: function (func) {
	          var tuples = [
	            // action, add listener, callbacks,
	            // ... .then handlers, argument index, [final state]
	            ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]],
	            state = "pending",
	            promise = {
	              state: function () {
	                return state;
	              },
	              always: function () {
	                deferred.done(arguments).fail(arguments);
	                return this;
	              },
	              "catch": function (fn) {
	                return promise.then(null, fn);
	              },
	              // Keep pipe for back-compat
	              pipe: function /* fnDone, fnFail, fnProgress */
	              () {
	                var fns = arguments;
	                return jQuery.Deferred(function (newDefer) {
	                  jQuery.each(tuples, function (_i, tuple) {
	                    // Map tuples (progress, done, fail) to arguments (done, fail, progress)
	                    var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]];

	                    // deferred.progress(function() { bind to newDefer or newDefer.notify })
	                    // deferred.done(function() { bind to newDefer or newDefer.resolve })
	                    // deferred.fail(function() { bind to newDefer or newDefer.reject })
	                    deferred[tuple[1]](function () {
	                      var returned = fn && fn.apply(this, arguments);
	                      if (returned && isFunction(returned.promise)) {
	                        returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);
	                      } else {
	                        newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments);
	                      }
	                    });
	                  });
	                  fns = null;
	                }).promise();
	              },
	              then: function (onFulfilled, onRejected, onProgress) {
	                var maxDepth = 0;
	                function resolve(depth, deferred, handler, special) {
	                  return function () {
	                    var that = this,
	                      args = arguments,
	                      mightThrow = function () {
	                        var returned, then;

	                        // Support: Promises/A+ section 2.3.3.3.3
	                        // https://promisesaplus.com/#point-59
	                        // Ignore double-resolution attempts
	                        if (depth < maxDepth) {
	                          return;
	                        }
	                        returned = handler.apply(that, args);

	                        // Support: Promises/A+ section 2.3.1
	                        // https://promisesaplus.com/#point-48
	                        if (returned === deferred.promise()) {
	                          throw new TypeError("Thenable self-resolution");
	                        }

	                        // Support: Promises/A+ sections 2.3.3.1, 3.5
	                        // https://promisesaplus.com/#point-54
	                        // https://promisesaplus.com/#point-75
	                        // Retrieve `then` only once
	                        then = returned && (
	                        // Support: Promises/A+ section 2.3.4
	                        // https://promisesaplus.com/#point-64
	                        // Only check objects and functions for thenability
	                        typeof returned === "object" || typeof returned === "function") && returned.then;

	                        // Handle a returned thenable
	                        if (isFunction(then)) {
	                          // Special processors (notify) just wait for resolution
	                          if (special) {
	                            then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special));

	                            // Normal processors (resolve) also hook into progress
	                          } else {
	                            // ...and disregard older resolution values
	                            maxDepth++;
	                            then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith));
	                          }

	                          // Handle all other returned values
	                        } else {
	                          // Only substitute handlers pass on context
	                          // and multiple values (non-spec behavior)
	                          if (handler !== Identity) {
	                            that = undefined;
	                            args = [returned];
	                          }

	                          // Process the value(s)
	                          // Default process is resolve
	                          (special || deferred.resolveWith)(that, args);
	                        }
	                      },
	                      // Only normal processors (resolve) catch and reject exceptions
	                      process = special ? mightThrow : function () {
	                        try {
	                          mightThrow();
	                        } catch (e) {
	                          if (jQuery.Deferred.exceptionHook) {
	                            jQuery.Deferred.exceptionHook(e, process.error);
	                          }

	                          // Support: Promises/A+ section 2.3.3.3.4.1
	                          // https://promisesaplus.com/#point-61
	                          // Ignore post-resolution exceptions
	                          if (depth + 1 >= maxDepth) {
	                            // Only substitute handlers pass on context
	                            // and multiple values (non-spec behavior)
	                            if (handler !== Thrower) {
	                              that = undefined;
	                              args = [e];
	                            }
	                            deferred.rejectWith(that, args);
	                          }
	                        }
	                      };

	                    // Support: Promises/A+ section 2.3.3.3.1
	                    // https://promisesaplus.com/#point-57
	                    // Re-resolve promises immediately to dodge false rejection from
	                    // subsequent errors
	                    if (depth) {
	                      process();
	                    } else {
	                      // Call an optional hook to record the error, in case of exception
	                      // since it's otherwise lost when execution goes async
	                      if (jQuery.Deferred.getErrorHook) {
	                        process.error = jQuery.Deferred.getErrorHook();

	                        // The deprecated alias of the above. While the name suggests
	                        // returning the stack, not an error instance, jQuery just passes
	                        // it directly to `console.warn` so both will work; an instance
	                        // just better cooperates with source maps.
	                      } else if (jQuery.Deferred.getStackHook) {
	                        process.error = jQuery.Deferred.getStackHook();
	                      }
	                      window.setTimeout(process);
	                    }
	                  };
	                }
	                return jQuery.Deferred(function (newDefer) {
	                  // progress_handlers.add( ... )
	                  tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith));

	                  // fulfilled_handlers.add( ... )
	                  tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity));

	                  // rejected_handlers.add( ... )
	                  tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower));
	                }).promise();
	              },
	              // Get a promise for this deferred
	              // If obj is provided, the promise aspect is added to the object
	              promise: function (obj) {
	                return obj != null ? jQuery.extend(obj, promise) : promise;
	              }
	            },
	            deferred = {};

	          // Add list-specific methods
	          jQuery.each(tuples, function (i, tuple) {
	            var list = tuple[2],
	              stateString = tuple[5];

	            // promise.progress = list.add
	            // promise.done = list.add
	            // promise.fail = list.add
	            promise[tuple[1]] = list.add;

	            // Handle state
	            if (stateString) {
	              list.add(function () {
	                // state = "resolved" (i.e., fulfilled)
	                // state = "rejected"
	                state = stateString;
	              },
	              // rejected_callbacks.disable
	              // fulfilled_callbacks.disable
	              tuples[3 - i][2].disable,
	              // rejected_handlers.disable
	              // fulfilled_handlers.disable
	              tuples[3 - i][3].disable,
	              // progress_callbacks.lock
	              tuples[0][2].lock,
	              // progress_handlers.lock
	              tuples[0][3].lock);
	            }

	            // progress_handlers.fire
	            // fulfilled_handlers.fire
	            // rejected_handlers.fire
	            list.add(tuple[3].fire);

	            // deferred.notify = function() { deferred.notifyWith(...) }
	            // deferred.resolve = function() { deferred.resolveWith(...) }
	            // deferred.reject = function() { deferred.rejectWith(...) }
	            deferred[tuple[0]] = function () {
	              deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
	              return this;
	            };

	            // deferred.notifyWith = list.fireWith
	            // deferred.resolveWith = list.fireWith
	            // deferred.rejectWith = list.fireWith
	            deferred[tuple[0] + "With"] = list.fireWith;
	          });

	          // Make the deferred a promise
	          promise.promise(deferred);

	          // Call given func if any
	          if (func) {
	            func.call(deferred, deferred);
	          }

	          // All done!
	          return deferred;
	        },
	        // Deferred helper
	        when: function (singleValue) {
	          var
	            // count of uncompleted subordinates
	            remaining = arguments.length,
	            // count of unprocessed arguments
	            i = remaining,
	            // subordinate fulfillment data
	            resolveContexts = Array(i),
	            resolveValues = slice.call(arguments),
	            // the primary Deferred
	            primary = jQuery.Deferred(),
	            // subordinate callback factory
	            updateFunc = function (i) {
	              return function (value) {
	                resolveContexts[i] = this;
	                resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;
	                if (! --remaining) {
	                  primary.resolveWith(resolveContexts, resolveValues);
	                }
	              };
	            };

	          // Single- and empty arguments are adopted like Promise.resolve
	          if (remaining <= 1) {
	            adoptValue(singleValue, primary.done(updateFunc(i)).resolve, primary.reject, !remaining);

	            // Use .then() to unwrap secondary thenables (cf. gh-3000)
	            if (primary.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) {
	              return primary.then();
	            }
	          }

	          // Multiple arguments are aggregated like Promise.all array elements
	          while (i--) {
	            adoptValue(resolveValues[i], updateFunc(i), primary.reject);
	          }
	          return primary.promise();
	        }
	      });

	      // These usually indicate a programmer mistake during development,
	      // warn about them ASAP rather than swallowing them by default.
	      var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;

	      // If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error
	      // captured before the async barrier to get the original error cause
	      // which may otherwise be hidden.
	      jQuery.Deferred.exceptionHook = function (error, asyncError) {
	        // Support: IE 8 - 9 only
	        // Console exists when dev tools are open, which can happen at any time
	        if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
	          window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, asyncError);
	        }
	      };
	      jQuery.readyException = function (error) {
	        window.setTimeout(function () {
	          throw error;
	        });
	      };

	      // The deferred used on DOM ready
	      var readyList = jQuery.Deferred();
	      jQuery.fn.ready = function (fn) {
	        readyList.then(fn)

	        // Wrap jQuery.readyException in a function so that the lookup
	        // happens at the time of error handling instead of callback
	        // registration.
	        .catch(function (error) {
	          jQuery.readyException(error);
	        });
	        return this;
	      };
	      jQuery.extend({
	        // Is the DOM ready to be used? Set to true once it occurs.
	        isReady: false,
	        // A counter to track how many items to wait for before
	        // the ready event fires. See trac-6781
	        readyWait: 1,
	        // Handle when the DOM is ready
	        ready: function (wait) {
	          // Abort if there are pending holds or we're already ready
	          if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
	            return;
	          }

	          // Remember that the DOM is ready
	          jQuery.isReady = true;

	          // If a normal DOM Ready event fired, decrement, and wait if need be
	          if (wait !== true && --jQuery.readyWait > 0) {
	            return;
	          }

	          // If there are functions bound, to execute
	          readyList.resolveWith(document, [jQuery]);
	        }
	      });
	      jQuery.ready.then = readyList.then;

	      // The ready event handler and self cleanup method
	      function completed() {
	        document.removeEventListener("DOMContentLoaded", completed);
	        window.removeEventListener("load", completed);
	        jQuery.ready();
	      }

	      // Catch cases where $(document).ready() is called
	      // after the browser event has already occurred.
	      // Support: IE <=9 - 10 only
	      // Older IE sometimes signals "interactive" too soon
	      if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) {
	        // Handle it asynchronously to allow scripts the opportunity to delay ready
	        window.setTimeout(jQuery.ready);
	      } else {
	        // Use the handy event callback
	        document.addEventListener("DOMContentLoaded", completed);

	        // A fallback to window.onload, that will always work
	        window.addEventListener("load", completed);
	      }

	      // Multifunctional method to get and set values of a collection
	      // The value/s can optionally be executed if it's a function
	      var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
	        var i = 0,
	          len = elems.length,
	          bulk = key == null;

	        // Sets many values
	        if (toType(key) === "object") {
	          chainable = true;
	          for (i in key) {
	            access(elems, fn, i, key[i], true, emptyGet, raw);
	          }

	          // Sets one value
	        } else if (value !== undefined) {
	          chainable = true;
	          if (!isFunction(value)) {
	            raw = true;
	          }
	          if (bulk) {
	            // Bulk operations run against the entire set
	            if (raw) {
	              fn.call(elems, value);
	              fn = null;

	              // ...except when executing function values
	            } else {
	              bulk = fn;
	              fn = function (elem, _key, value) {
	                return bulk.call(jQuery(elem), value);
	              };
	            }
	          }
	          if (fn) {
	            for (; i < len; i++) {
	              fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
	            }
	          }
	        }
	        if (chainable) {
	          return elems;
	        }

	        // Gets
	        if (bulk) {
	          return fn.call(elems);
	        }
	        return len ? fn(elems[0], key) : emptyGet;
	      };

	      // Matches dashed string for camelizing
	      var rmsPrefix = /^-ms-/,
	        rdashAlpha = /-([a-z])/g;

	      // Used by camelCase as callback to replace()
	      function fcamelCase(_all, letter) {
	        return letter.toUpperCase();
	      }

	      // Convert dashed to camelCase; used by the css and data modules
	      // Support: IE <=9 - 11, Edge 12 - 15
	      // Microsoft forgot to hump their vendor prefix (trac-9572)
	      function camelCase(string) {
	        return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
	      }
	      var acceptData = function (owner) {
	        // Accepts only:
	        //  - Node
	        //    - Node.ELEMENT_NODE
	        //    - Node.DOCUMENT_NODE
	        //  - Object
	        //    - Any
	        return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;
	      };
	      function Data() {
	        this.expando = jQuery.expando + Data.uid++;
	      }
	      Data.uid = 1;
	      Data.prototype = {
	        cache: function (owner) {
	          // Check if the owner object already has a cache
	          var value = owner[this.expando];

	          // If not, create one
	          if (!value) {
	            value = {};

	            // We can accept data for non-element nodes in modern browsers,
	            // but we should not, see trac-8335.
	            // Always return an empty object.
	            if (acceptData(owner)) {
	              // If it is a node unlikely to be stringify-ed or looped over
	              // use plain assignment
	              if (owner.nodeType) {
	                owner[this.expando] = value;

	                // Otherwise secure it in a non-enumerable property
	                // configurable must be true to allow the property to be
	                // deleted when data is removed
	              } else {
	                Object.defineProperty(owner, this.expando, {
	                  value: value,
	                  configurable: true
	                });
	              }
	            }
	          }
	          return value;
	        },
	        set: function (owner, data, value) {
	          var prop,
	            cache = this.cache(owner);

	          // Handle: [ owner, key, value ] args
	          // Always use camelCase key (gh-2257)
	          if (typeof data === "string") {
	            cache[camelCase(data)] = value;

	            // Handle: [ owner, { properties } ] args
	          } else {
	            // Copy the properties one-by-one to the cache object
	            for (prop in data) {
	              cache[camelCase(prop)] = data[prop];
	            }
	          }
	          return cache;
	        },
	        get: function (owner, key) {
	          return key === undefined ? this.cache(owner) :
	          // Always use camelCase key (gh-2257)
	          owner[this.expando] && owner[this.expando][camelCase(key)];
	        },
	        access: function (owner, key, value) {
	          // In cases where either:
	          //
	          //   1. No key was specified
	          //   2. A string key was specified, but no value provided
	          //
	          // Take the "read" path and allow the get method to determine
	          // which value to return, respectively either:
	          //
	          //   1. The entire cache object
	          //   2. The data stored at the key
	          //
	          if (key === undefined || key && typeof key === "string" && value === undefined) {
	            return this.get(owner, key);
	          }

	          // When the key is not a string, or both a key and value
	          // are specified, set or extend (existing objects) with either:
	          //
	          //   1. An object of properties
	          //   2. A key and value
	          //
	          this.set(owner, key, value);

	          // Since the "set" path can have two possible entry points
	          // return the expected data based on which path was taken[*]
	          return value !== undefined ? value : key;
	        },
	        remove: function (owner, key) {
	          var i,
	            cache = owner[this.expando];
	          if (cache === undefined) {
	            return;
	          }
	          if (key !== undefined) {
	            // Support array or space separated string of keys
	            if (Array.isArray(key)) {
	              // If key is an array of keys...
	              // We always set camelCase keys, so remove that.
	              key = key.map(camelCase);
	            } else {
	              key = camelCase(key);

	              // If a key with the spaces exists, use it.
	              // Otherwise, create an array by matching non-whitespace
	              key = key in cache ? [key] : key.match(rnothtmlwhite) || [];
	            }
	            i = key.length;
	            while (i--) {
	              delete cache[key[i]];
	            }
	          }

	          // Remove the expando if there's no more data
	          if (key === undefined || jQuery.isEmptyObject(cache)) {
	            // Support: Chrome <=35 - 45
	            // Webkit & Blink performance suffers when deleting properties
	            // from DOM nodes, so set to undefined instead
	            // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
	            if (owner.nodeType) {
	              owner[this.expando] = undefined;
	            } else {
	              delete owner[this.expando];
	            }
	          }
	        },
	        hasData: function (owner) {
	          var cache = owner[this.expando];
	          return cache !== undefined && !jQuery.isEmptyObject(cache);
	        }
	      };
	      var dataPriv = new Data();
	      var dataUser = new Data();

	      //	Implementation Summary
	      //
	      //	1. Enforce API surface and semantic compatibility with 1.9.x branch
	      //	2. Improve the module's maintainability by reducing the storage
	      //		paths to a single mechanism.
	      //	3. Use the same single mechanism to support "private" and "user" data.
	      //	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
	      //	5. Avoid exposing implementation details on user objects (eg. expando properties)
	      //	6. Provide a clear path for implementation upgrade to WeakMap in 2014

	      var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
	        rmultiDash = /[A-Z]/g;
	      function getData(data) {
	        if (data === "true") {
	          return true;
	        }
	        if (data === "false") {
	          return false;
	        }
	        if (data === "null") {
	          return null;
	        }

	        // Only convert to a number if it doesn't change the string
	        if (data === +data + "") {
	          return +data;
	        }
	        if (rbrace.test(data)) {
	          return JSON.parse(data);
	        }
	        return data;
	      }
	      function dataAttr(elem, key, data) {
	        var name;

	        // If nothing was found internally, try to fetch any
	        // data from the HTML5 data-* attribute
	        if (data === undefined && elem.nodeType === 1) {
	          name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
	          data = elem.getAttribute(name);
	          if (typeof data === "string") {
	            try {
	              data = getData(data);
	            } catch (e) {}

	            // Make sure we set the data so it isn't changed later
	            dataUser.set(elem, key, data);
	          } else {
	            data = undefined;
	          }
	        }
	        return data;
	      }
	      jQuery.extend({
	        hasData: function (elem) {
	          return dataUser.hasData(elem) || dataPriv.hasData(elem);
	        },
	        data: function (elem, name, data) {
	          return dataUser.access(elem, name, data);
	        },
	        removeData: function (elem, name) {
	          dataUser.remove(elem, name);
	        },
	        // TODO: Now that all calls to _data and _removeData have been replaced
	        // with direct calls to dataPriv methods, these can be deprecated.
	        _data: function (elem, name, data) {
	          return dataPriv.access(elem, name, data);
	        },
	        _removeData: function (elem, name) {
	          dataPriv.remove(elem, name);
	        }
	      });
	      jQuery.fn.extend({
	        data: function (key, value) {
	          var i,
	            name,
	            data,
	            elem = this[0],
	            attrs = elem && elem.attributes;

	          // Gets all values
	          if (key === undefined) {
	            if (this.length) {
	              data = dataUser.get(elem);
	              if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
	                i = attrs.length;
	                while (i--) {
	                  // Support: IE 11 only
	                  // The attrs elements can be null (trac-14894)
	                  if (attrs[i]) {
	                    name = attrs[i].name;
	                    if (name.indexOf("data-") === 0) {
	                      name = camelCase(name.slice(5));
	                      dataAttr(elem, name, data[name]);
	                    }
	                  }
	                }
	                dataPriv.set(elem, "hasDataAttrs", true);
	              }
	            }
	            return data;
	          }

	          // Sets multiple values
	          if (typeof key === "object") {
	            return this.each(function () {
	              dataUser.set(this, key);
	            });
	          }
	          return access(this, function (value) {
	            var data;

	            // The calling jQuery object (element matches) is not empty
	            // (and therefore has an element appears at this[ 0 ]) and the
	            // `value` parameter was not undefined. An empty jQuery object
	            // will result in `undefined` for elem = this[ 0 ] which will
	            // throw an exception if an attempt to read a data cache is made.
	            if (elem && value === undefined) {
	              // Attempt to get data from the cache
	              // The key will always be camelCased in Data
	              data = dataUser.get(elem, key);
	              if (data !== undefined) {
	                return data;
	              }

	              // Attempt to "discover" the data in
	              // HTML5 custom data-* attrs
	              data = dataAttr(elem, key);
	              if (data !== undefined) {
	                return data;
	              }

	              // We tried really hard, but the data doesn't exist.
	              return;
	            }

	            // Set the data...
	            this.each(function () {
	              // We always store the camelCased key
	              dataUser.set(this, key, value);
	            });
	          }, null, value, arguments.length > 1, null, true);
	        },
	        removeData: function (key) {
	          return this.each(function () {
	            dataUser.remove(this, key);
	          });
	        }
	      });
	      jQuery.extend({
	        queue: function (elem, type, data) {
	          var queue;
	          if (elem) {
	            type = (type || "fx") + "queue";
	            queue = dataPriv.get(elem, type);

	            // Speed up dequeue by getting out quickly if this is just a lookup
	            if (data) {
	              if (!queue || Array.isArray(data)) {
	                queue = dataPriv.access(elem, type, jQuery.makeArray(data));
	              } else {
	                queue.push(data);
	              }
	            }
	            return queue || [];
	          }
	        },
	        dequeue: function (elem, type) {
	          type = type || "fx";
	          var queue = jQuery.queue(elem, type),
	            startLength = queue.length,
	            fn = queue.shift(),
	            hooks = jQuery._queueHooks(elem, type),
	            next = function () {
	              jQuery.dequeue(elem, type);
	            };

	          // If the fx queue is dequeued, always remove the progress sentinel
	          if (fn === "inprogress") {
	            fn = queue.shift();
	            startLength--;
	          }
	          if (fn) {
	            // Add a progress sentinel to prevent the fx queue from being
	            // automatically dequeued
	            if (type === "fx") {
	              queue.unshift("inprogress");
	            }

	            // Clear up the last queue stop function
	            delete hooks.stop;
	            fn.call(elem, next, hooks);
	          }
	          if (!startLength && hooks) {
	            hooks.empty.fire();
	          }
	        },
	        // Not public - generate a queueHooks object, or return the current one
	        _queueHooks: function (elem, type) {
	          var key = type + "queueHooks";
	          return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
	            empty: jQuery.Callbacks("once memory").add(function () {
	              dataPriv.remove(elem, [type + "queue", key]);
	            })
	          });
	        }
	      });
	      jQuery.fn.extend({
	        queue: function (type, data) {
	          var setter = 2;
	          if (typeof type !== "string") {
	            data = type;
	            type = "fx";
	            setter--;
	          }
	          if (arguments.length < setter) {
	            return jQuery.queue(this[0], type);
	          }
	          return data === undefined ? this : this.each(function () {
	            var queue = jQuery.queue(this, type, data);

	            // Ensure a hooks for this queue
	            jQuery._queueHooks(this, type);
	            if (type === "fx" && queue[0] !== "inprogress") {
	              jQuery.dequeue(this, type);
	            }
	          });
	        },
	        dequeue: function (type) {
	          return this.each(function () {
	            jQuery.dequeue(this, type);
	          });
	        },
	        clearQueue: function (type) {
	          return this.queue(type || "fx", []);
	        },
	        // Get a promise resolved when queues of a certain type
	        // are emptied (fx is the type by default)
	        promise: function (type, obj) {
	          var tmp,
	            count = 1,
	            defer = jQuery.Deferred(),
	            elements = this,
	            i = this.length,
	            resolve = function () {
	              if (! --count) {
	                defer.resolveWith(elements, [elements]);
	              }
	            };
	          if (typeof type !== "string") {
	            obj = type;
	            type = undefined;
	          }
	          type = type || "fx";
	          while (i--) {
	            tmp = dataPriv.get(elements[i], type + "queueHooks");
	            if (tmp && tmp.empty) {
	              count++;
	              tmp.empty.add(resolve);
	            }
	          }
	          resolve();
	          return defer.promise(obj);
	        }
	      });
	      var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
	      var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
	      var cssExpand = ["Top", "Right", "Bottom", "Left"];
	      var documentElement = document.documentElement;
	      var isAttached = function (elem) {
	          return jQuery.contains(elem.ownerDocument, elem);
	        },
	        composed = {
	          composed: true
	        };

	      // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
	      // Check attachment across shadow DOM boundaries when possible (gh-3504)
	      // Support: iOS 10.0-10.2 only
	      // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
	      // leading to errors. We need to check for `getRootNode`.
	      if (documentElement.getRootNode) {
	        isAttached = function (elem) {
	          return jQuery.contains(elem.ownerDocument, elem) || elem.getRootNode(composed) === elem.ownerDocument;
	        };
	      }
	      var isHiddenWithinTree = function (elem, el) {
	        // isHiddenWithinTree might be called from jQuery#filter function;
	        // in that case, element will be second argument
	        elem = el || elem;

	        // Inline style trumps all
	        return elem.style.display === "none" || elem.style.display === "" &&
	        // Otherwise, check computed style
	        // Support: Firefox <=43 - 45
	        // Disconnected elements can have computed display: none, so first confirm that elem is
	        // in the document.
	        isAttached(elem) && jQuery.css(elem, "display") === "none";
	      };
	      function adjustCSS(elem, prop, valueParts, tween) {
	        var adjusted,
	          scale,
	          maxIterations = 20,
	          currentValue = tween ? function () {
	            return tween.cur();
	          } : function () {
	            return jQuery.css(elem, prop, "");
	          },
	          initial = currentValue(),
	          unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
	          // Starting value computation is required for potential unit mismatches
	          initialInUnit = elem.nodeType && (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop));
	        if (initialInUnit && initialInUnit[3] !== unit) {
	          // Support: Firefox <=54
	          // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
	          initial = initial / 2;

	          // Trust units reported by jQuery.css
	          unit = unit || initialInUnit[3];

	          // Iteratively approximate from a nonzero starting point
	          initialInUnit = +initial || 1;
	          while (maxIterations--) {
	            // Evaluate and update our best guess (doubling guesses that zero out).
	            // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
	            jQuery.style(elem, prop, initialInUnit + unit);
	            if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {
	              maxIterations = 0;
	            }
	            initialInUnit = initialInUnit / scale;
	          }
	          initialInUnit = initialInUnit * 2;
	          jQuery.style(elem, prop, initialInUnit + unit);

	          // Make sure we update the tween properties later on
	          valueParts = valueParts || [];
	        }
	        if (valueParts) {
	          initialInUnit = +initialInUnit || +initial || 0;

	          // Apply relative offset (+=/-=) if specified
	          adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];
	          if (tween) {
	            tween.unit = unit;
	            tween.start = initialInUnit;
	            tween.end = adjusted;
	          }
	        }
	        return adjusted;
	      }
	      var defaultDisplayMap = {};
	      function getDefaultDisplay(elem) {
	        var temp,
	          doc = elem.ownerDocument,
	          nodeName = elem.nodeName,
	          display = defaultDisplayMap[nodeName];
	        if (display) {
	          return display;
	        }
	        temp = doc.body.appendChild(doc.createElement(nodeName));
	        display = jQuery.css(temp, "display");
	        temp.parentNode.removeChild(temp);
	        if (display === "none") {
	          display = "block";
	        }
	        defaultDisplayMap[nodeName] = display;
	        return display;
	      }
	      function showHide(elements, show) {
	        var display,
	          elem,
	          values = [],
	          index = 0,
	          length = elements.length;

	        // Determine new display value for elements that need to change
	        for (; index < length; index++) {
	          elem = elements[index];
	          if (!elem.style) {
	            continue;
	          }
	          display = elem.style.display;
	          if (show) {
	            // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
	            // check is required in this first loop unless we have a nonempty display value (either
	            // inline or about-to-be-restored)
	            if (display === "none") {
	              values[index] = dataPriv.get(elem, "display") || null;
	              if (!values[index]) {
	                elem.style.display = "";
	              }
	            }
	            if (elem.style.display === "" && isHiddenWithinTree(elem)) {
	              values[index] = getDefaultDisplay(elem);
	            }
	          } else {
	            if (display !== "none") {
	              values[index] = "none";

	              // Remember what we're overwriting
	              dataPriv.set(elem, "display", display);
	            }
	          }
	        }

	        // Set the display of the elements in a second loop to avoid constant reflow
	        for (index = 0; index < length; index++) {
	          if (values[index] != null) {
	            elements[index].style.display = values[index];
	          }
	        }
	        return elements;
	      }
	      jQuery.fn.extend({
	        show: function () {
	          return showHide(this, true);
	        },
	        hide: function () {
	          return showHide(this);
	        },
	        toggle: function (state) {
	          if (typeof state === "boolean") {
	            return state ? this.show() : this.hide();
	          }
	          return this.each(function () {
	            if (isHiddenWithinTree(this)) {
	              jQuery(this).show();
	            } else {
	              jQuery(this).hide();
	            }
	          });
	        }
	      });
	      var rcheckableType = /^(?:checkbox|radio)$/i;
	      var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i;
	      var rscriptType = /^$|^module$|\/(?:java|ecma)script/i;
	      (function () {
	        var fragment = document.createDocumentFragment(),
	          div = fragment.appendChild(document.createElement("div")),
	          input = document.createElement("input");

	        // Support: Android 4.0 - 4.3 only
	        // Check state lost if the name is set (trac-11217)
	        // Support: Windows Web Apps (WWA)
	        // `name` and `type` must use .setAttribute for WWA (trac-14901)
	        input.setAttribute("type", "radio");
	        input.setAttribute("checked", "checked");
	        input.setAttribute("name", "t");
	        div.appendChild(input);

	        // Support: Android <=4.1 only
	        // Older WebKit doesn't clone checked state correctly in fragments
	        support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;

	        // Support: IE <=11 only
	        // Make sure textarea (and checkbox) defaultValue is properly cloned
	        div.innerHTML = "<textarea>x</textarea>";
	        support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;

	        // Support: IE <=9 only
	        // IE <=9 replaces <option> tags with their contents when inserted outside of
	        // the select element.
	        div.innerHTML = "<option></option>";
	        support.option = !!div.lastChild;
	      })();

	      // We have to close these tags to support XHTML (trac-13200)
	      var wrapMap = {
	        // XHTML parsers do not magically insert elements in the
	        // same way that tag soup parsers do. So we cannot shorten
	        // this by omitting <tbody> or other required elements.
	        thead: [1, "<table>", "</table>"],
	        col: [2, "<table><colgroup>", "</colgroup></table>"],
	        tr: [2, "<table><tbody>", "</tbody></table>"],
	        td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
	        _default: [0, "", ""]
	      };
	      wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	      wrapMap.th = wrapMap.td;

	      // Support: IE <=9 only
	      if (!support.option) {
	        wrapMap.optgroup = wrapMap.option = [1, "<select multiple='multiple'>", "</select>"];
	      }
	      function getAll(context, tag) {
	        // Support: IE <=9 - 11 only
	        // Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
	        var ret;
	        if (typeof context.getElementsByTagName !== "undefined") {
	          ret = context.getElementsByTagName(tag || "*");
	        } else if (typeof context.querySelectorAll !== "undefined") {
	          ret = context.querySelectorAll(tag || "*");
	        } else {
	          ret = [];
	        }
	        if (tag === undefined || tag && nodeName(context, tag)) {
	          return jQuery.merge([context], ret);
	        }
	        return ret;
	      }

	      // Mark scripts as having already been evaluated
	      function setGlobalEval(elems, refElements) {
	        var i = 0,
	          l = elems.length;
	        for (; i < l; i++) {
	          dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval"));
	        }
	      }
	      var rhtml = /<|&#?\w+;/;
	      function buildFragment(elems, context, scripts, selection, ignored) {
	        var elem,
	          tmp,
	          tag,
	          wrap,
	          attached,
	          j,
	          fragment = context.createDocumentFragment(),
	          nodes = [],
	          i = 0,
	          l = elems.length;
	        for (; i < l; i++) {
	          elem = elems[i];
	          if (elem || elem === 0) {
	            // Add nodes directly
	            if (toType(elem) === "object") {
	              // Support: Android <=4.0 only, PhantomJS 1 only
	              // push.apply(_, arraylike) throws on ancient WebKit
	              jQuery.merge(nodes, elem.nodeType ? [elem] : elem);

	              // Convert non-html into a text node
	            } else if (!rhtml.test(elem)) {
	              nodes.push(context.createTextNode(elem));

	              // Convert html into DOM nodes
	            } else {
	              tmp = tmp || fragment.appendChild(context.createElement("div"));

	              // Deserialize a standard representation
	              tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
	              wrap = wrapMap[tag] || wrapMap._default;
	              tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];

	              // Descend through wrappers to the right content
	              j = wrap[0];
	              while (j--) {
	                tmp = tmp.lastChild;
	              }

	              // Support: Android <=4.0 only, PhantomJS 1 only
	              // push.apply(_, arraylike) throws on ancient WebKit
	              jQuery.merge(nodes, tmp.childNodes);

	              // Remember the top-level container
	              tmp = fragment.firstChild;

	              // Ensure the created nodes are orphaned (trac-12392)
	              tmp.textContent = "";
	            }
	          }
	        }

	        // Remove wrapper from fragment
	        fragment.textContent = "";
	        i = 0;
	        while (elem = nodes[i++]) {
	          // Skip elements already in the context collection (trac-4087)
	          if (selection && jQuery.inArray(elem, selection) > -1) {
	            if (ignored) {
	              ignored.push(elem);
	            }
	            continue;
	          }
	          attached = isAttached(elem);

	          // Append to fragment
	          tmp = getAll(fragment.appendChild(elem), "script");

	          // Preserve script evaluation history
	          if (attached) {
	            setGlobalEval(tmp);
	          }

	          // Capture executables
	          if (scripts) {
	            j = 0;
	            while (elem = tmp[j++]) {
	              if (rscriptType.test(elem.type || "")) {
	                scripts.push(elem);
	              }
	            }
	          }
	        }
	        return fragment;
	      }
	      var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
	      function returnTrue() {
	        return true;
	      }
	      function returnFalse() {
	        return false;
	      }
	      function on(elem, types, selector, data, fn, one) {
	        var origFn, type;

	        // Types can be a map of types/handlers
	        if (typeof types === "object") {
	          // ( types-Object, selector, data )
	          if (typeof selector !== "string") {
	            // ( types-Object, data )
	            data = data || selector;
	            selector = undefined;
	          }
	          for (type in types) {
	            on(elem, type, selector, data, types[type], one);
	          }
	          return elem;
	        }
	        if (data == null && fn == null) {
	          // ( types, fn )
	          fn = selector;
	          data = selector = undefined;
	        } else if (fn == null) {
	          if (typeof selector === "string") {
	            // ( types, selector, fn )
	            fn = data;
	            data = undefined;
	          } else {
	            // ( types, data, fn )
	            fn = data;
	            data = selector;
	            selector = undefined;
	          }
	        }
	        if (fn === false) {
	          fn = returnFalse;
	        } else if (!fn) {
	          return elem;
	        }
	        if (one === 1) {
	          origFn = fn;
	          fn = function (event) {
	            // Can use an empty set, since event contains the info
	            jQuery().off(event);
	            return origFn.apply(this, arguments);
	          };

	          // Use same guid so caller can remove using origFn
	          fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
	        }
	        return elem.each(function () {
	          jQuery.event.add(this, types, fn, data, selector);
	        });
	      }

	      /*
	       * Helper functions for managing events -- not part of the public interface.
	       * Props to Dean Edwards' addEvent library for many of the ideas.
	       */
	      jQuery.event = {
	        global: {},
	        add: function (elem, types, handler, data, selector) {
	          var handleObjIn,
	            eventHandle,
	            tmp,
	            events,
	            t,
	            handleObj,
	            special,
	            handlers,
	            type,
	            namespaces,
	            origType,
	            elemData = dataPriv.get(elem);

	          // Only attach events to objects that accept data
	          if (!acceptData(elem)) {
	            return;
	          }

	          // Caller can pass in an object of custom data in lieu of the handler
	          if (handler.handler) {
	            handleObjIn = handler;
	            handler = handleObjIn.handler;
	            selector = handleObjIn.selector;
	          }

	          // Ensure that invalid selectors throw exceptions at attach time
	          // Evaluate against documentElement in case elem is a non-element node (e.g., document)
	          if (selector) {
	            jQuery.find.matchesSelector(documentElement, selector);
	          }

	          // Make sure that the handler has a unique ID, used to find/remove it later
	          if (!handler.guid) {
	            handler.guid = jQuery.guid++;
	          }

	          // Init the element's event structure and main handler, if this is the first
	          if (!(events = elemData.events)) {
	            events = elemData.events = Object.create(null);
	          }
	          if (!(eventHandle = elemData.handle)) {
	            eventHandle = elemData.handle = function (e) {
	              // Discard the second event of a jQuery.event.trigger() and
	              // when an event is called after a page has unloaded
	              return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined;
	            };
	          }

	          // Handle multiple events separated by a space
	          types = (types || "").match(rnothtmlwhite) || [""];
	          t = types.length;
	          while (t--) {
	            tmp = rtypenamespace.exec(types[t]) || [];
	            type = origType = tmp[1];
	            namespaces = (tmp[2] || "").split(".").sort();

	            // There *must* be a type, no attaching namespace-only handlers
	            if (!type) {
	              continue;
	            }

	            // If event changes its type, use the special event handlers for the changed type
	            special = jQuery.event.special[type] || {};

	            // If selector defined, determine special event api type, otherwise given type
	            type = (selector ? special.delegateType : special.bindType) || type;

	            // Update special based on newly reset type
	            special = jQuery.event.special[type] || {};

	            // handleObj is passed to all event handlers
	            handleObj = jQuery.extend({
	              type: type,
	              origType: origType,
	              data: data,
	              handler: handler,
	              guid: handler.guid,
	              selector: selector,
	              needsContext: selector && jQuery.expr.match.needsContext.test(selector),
	              namespace: namespaces.join(".")
	            }, handleObjIn);

	            // Init the event handler queue if we're the first
	            if (!(handlers = events[type])) {
	              handlers = events[type] = [];
	              handlers.delegateCount = 0;

	              // Only use addEventListener if the special events handler returns false
	              if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
	                if (elem.addEventListener) {
	                  elem.addEventListener(type, eventHandle);
	                }
	              }
	            }
	            if (special.add) {
	              special.add.call(elem, handleObj);
	              if (!handleObj.handler.guid) {
	                handleObj.handler.guid = handler.guid;
	              }
	            }

	            // Add to the element's handler list, delegates in front
	            if (selector) {
	              handlers.splice(handlers.delegateCount++, 0, handleObj);
	            } else {
	              handlers.push(handleObj);
	            }

	            // Keep track of which events have ever been used, for event optimization
	            jQuery.event.global[type] = true;
	          }
	        },
	        // Detach an event or set of events from an element
	        remove: function (elem, types, handler, selector, mappedTypes) {
	          var j,
	            origCount,
	            tmp,
	            events,
	            t,
	            handleObj,
	            special,
	            handlers,
	            type,
	            namespaces,
	            origType,
	            elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
	          if (!elemData || !(events = elemData.events)) {
	            return;
	          }

	          // Once for each type.namespace in types; type may be omitted
	          types = (types || "").match(rnothtmlwhite) || [""];
	          t = types.length;
	          while (t--) {
	            tmp = rtypenamespace.exec(types[t]) || [];
	            type = origType = tmp[1];
	            namespaces = (tmp[2] || "").split(".").sort();

	            // Unbind all events (on this namespace, if provided) for the element
	            if (!type) {
	              for (type in events) {
	                jQuery.event.remove(elem, type + types[t], handler, selector, true);
	              }
	              continue;
	            }
	            special = jQuery.event.special[type] || {};
	            type = (selector ? special.delegateType : special.bindType) || type;
	            handlers = events[type] || [];
	            tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");

	            // Remove matching events
	            origCount = j = handlers.length;
	            while (j--) {
	              handleObj = handlers[j];
	              if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
	                handlers.splice(j, 1);
	                if (handleObj.selector) {
	                  handlers.delegateCount--;
	                }
	                if (special.remove) {
	                  special.remove.call(elem, handleObj);
	                }
	              }
	            }

	            // Remove generic event handler if we removed something and no more handlers exist
	            // (avoids potential for endless recursion during removal of special event handlers)
	            if (origCount && !handlers.length) {
	              if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
	                jQuery.removeEvent(elem, type, elemData.handle);
	              }
	              delete events[type];
	            }
	          }

	          // Remove data and the expando if it's no longer used
	          if (jQuery.isEmptyObject(events)) {
	            dataPriv.remove(elem, "handle events");
	          }
	        },
	        dispatch: function (nativeEvent) {
	          var i,
	            j,
	            ret,
	            matched,
	            handleObj,
	            handlerQueue,
	            args = new Array(arguments.length),
	            // Make a writable jQuery.Event from the native event object
	            event = jQuery.event.fix(nativeEvent),
	            handlers = (dataPriv.get(this, "events") || Object.create(null))[event.type] || [],
	            special = jQuery.event.special[event.type] || {};

	          // Use the fix-ed jQuery.Event rather than the (read-only) native event
	          args[0] = event;
	          for (i = 1; i < arguments.length; i++) {
	            args[i] = arguments[i];
	          }
	          event.delegateTarget = this;

	          // Call the preDispatch hook for the mapped type, and let it bail if desired
	          if (special.preDispatch && special.preDispatch.call(this, event) === false) {
	            return;
	          }

	          // Determine handlers
	          handlerQueue = jQuery.event.handlers.call(this, event, handlers);

	          // Run delegates first; they may want to stop propagation beneath us
	          i = 0;
	          while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
	            event.currentTarget = matched.elem;
	            j = 0;
	            while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
	              // If the event is namespaced, then each handler is only invoked if it is
	              // specially universal or its namespaces are a superset of the event's.
	              if (!event.rnamespace || handleObj.namespace === false || event.rnamespace.test(handleObj.namespace)) {
	                event.handleObj = handleObj;
	                event.data = handleObj.data;
	                ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
	                if (ret !== undefined) {
	                  if ((event.result = ret) === false) {
	                    event.preventDefault();
	                    event.stopPropagation();
	                  }
	                }
	              }
	            }
	          }

	          // Call the postDispatch hook for the mapped type
	          if (special.postDispatch) {
	            special.postDispatch.call(this, event);
	          }
	          return event.result;
	        },
	        handlers: function (event, handlers) {
	          var i,
	            handleObj,
	            sel,
	            matchedHandlers,
	            matchedSelectors,
	            handlerQueue = [],
	            delegateCount = handlers.delegateCount,
	            cur = event.target;

	          // Find delegate handlers
	          if (delegateCount &&
	          // Support: IE <=9
	          // Black-hole SVG <use> instance trees (trac-13180)
	          cur.nodeType &&
	          // Support: Firefox <=42
	          // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
	          // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
	          // Support: IE 11 only
	          // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
	          !(event.type === "click" && event.button >= 1)) {
	            for (; cur !== this; cur = cur.parentNode || this) {
	              // Don't check non-elements (trac-13208)
	              // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
	              if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
	                matchedHandlers = [];
	                matchedSelectors = {};
	                for (i = 0; i < delegateCount; i++) {
	                  handleObj = handlers[i];

	                  // Don't conflict with Object.prototype properties (trac-13203)
	                  sel = handleObj.selector + " ";
	                  if (matchedSelectors[sel] === undefined) {
	                    matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length;
	                  }
	                  if (matchedSelectors[sel]) {
	                    matchedHandlers.push(handleObj);
	                  }
	                }
	                if (matchedHandlers.length) {
	                  handlerQueue.push({
	                    elem: cur,
	                    handlers: matchedHandlers
	                  });
	                }
	              }
	            }
	          }

	          // Add the remaining (directly-bound) handlers
	          cur = this;
	          if (delegateCount < handlers.length) {
	            handlerQueue.push({
	              elem: cur,
	              handlers: handlers.slice(delegateCount)
	            });
	          }
	          return handlerQueue;
	        },
	        addProp: function (name, hook) {
	          Object.defineProperty(jQuery.Event.prototype, name, {
	            enumerable: true,
	            configurable: true,
	            get: isFunction(hook) ? function () {
	              if (this.originalEvent) {
	                return hook(this.originalEvent);
	              }
	            } : function () {
	              if (this.originalEvent) {
	                return this.originalEvent[name];
	              }
	            },
	            set: function (value) {
	              Object.defineProperty(this, name, {
	                enumerable: true,
	                configurable: true,
	                writable: true,
	                value: value
	              });
	            }
	          });
	        },
	        fix: function (originalEvent) {
	          return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent);
	        },
	        special: {
	          load: {
	            // Prevent triggered image.load events from bubbling to window.load
	            noBubble: true
	          },
	          click: {
	            // Utilize native event to ensure correct state for checkable inputs
	            setup: function (data) {
	              // For mutual compressibility with _default, replace `this` access with a local var.
	              // `|| data` is dead code meant only to preserve the variable through minification.
	              var el = this || data;

	              // Claim the first handler
	              if (rcheckableType.test(el.type) && el.click && nodeName(el, "input")) {
	                // dataPriv.set( el, "click", ... )
	                leverageNative(el, "click", true);
	              }

	              // Return false to allow normal processing in the caller
	              return false;
	            },
	            trigger: function (data) {
	              // For mutual compressibility with _default, replace `this` access with a local var.
	              // `|| data` is dead code meant only to preserve the variable through minification.
	              var el = this || data;

	              // Force setup before triggering a click
	              if (rcheckableType.test(el.type) && el.click && nodeName(el, "input")) {
	                leverageNative(el, "click");
	              }

	              // Return non-false to allow normal event-path propagation
	              return true;
	            },
	            // For cross-browser consistency, suppress native .click() on links
	            // Also prevent it if we're currently inside a leveraged native-event stack
	            _default: function (event) {
	              var target = event.target;
	              return rcheckableType.test(target.type) && target.click && nodeName(target, "input") && dataPriv.get(target, "click") || nodeName(target, "a");
	            }
	          },
	          beforeunload: {
	            postDispatch: function (event) {
	              // Support: Firefox 20+
	              // Firefox doesn't alert if the returnValue field is not set.
	              if (event.result !== undefined && event.originalEvent) {
	                event.originalEvent.returnValue = event.result;
	              }
	            }
	          }
	        }
	      };

	      // Ensure the presence of an event listener that handles manually-triggered
	      // synthetic events by interrupting progress until reinvoked in response to
	      // *native* events that it fires directly, ensuring that state changes have
	      // already occurred before other listeners are invoked.
	      function leverageNative(el, type, isSetup) {
	        // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add
	        if (!isSetup) {
	          if (dataPriv.get(el, type) === undefined) {
	            jQuery.event.add(el, type, returnTrue);
	          }
	          return;
	        }

	        // Register the controller as a special universal handler for all event namespaces
	        dataPriv.set(el, type, false);
	        jQuery.event.add(el, type, {
	          namespace: false,
	          handler: function (event) {
	            var result,
	              saved = dataPriv.get(this, type);
	            if (event.isTrigger & 1 && this[type]) {
	              // Interrupt processing of the outer synthetic .trigger()ed event
	              if (!saved) {
	                // Store arguments for use when handling the inner native event
	                // There will always be at least one argument (an event object), so this array
	                // will not be confused with a leftover capture object.
	                saved = slice.call(arguments);
	                dataPriv.set(this, type, saved);

	                // Trigger the native event and capture its result
	                this[type]();
	                result = dataPriv.get(this, type);
	                dataPriv.set(this, type, false);
	                if (saved !== result) {
	                  // Cancel the outer synthetic event
	                  event.stopImmediatePropagation();
	                  event.preventDefault();
	                  return result;
	                }

	                // If this is an inner synthetic event for an event with a bubbling surrogate
	                // (focus or blur), assume that the surrogate already propagated from triggering
	                // the native event and prevent that from happening again here.
	                // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
	                // bubbling surrogate propagates *after* the non-bubbling base), but that seems
	                // less bad than duplication.
	              } else if ((jQuery.event.special[type] || {}).delegateType) {
	                event.stopPropagation();
	              }

	              // If this is a native event triggered above, everything is now in order
	              // Fire an inner synthetic event with the original arguments
	            } else if (saved) {
	              // ...and capture the result
	              dataPriv.set(this, type, jQuery.event.trigger(saved[0], saved.slice(1), this));

	              // Abort handling of the native event by all jQuery handlers while allowing
	              // native handlers on the same element to run. On target, this is achieved
	              // by stopping immediate propagation just on the jQuery event. However,
	              // the native event is re-wrapped by a jQuery one on each level of the
	              // propagation so the only way to stop it for jQuery is to stop it for
	              // everyone via native `stopPropagation()`. This is not a problem for
	              // focus/blur which don't bubble, but it does also stop click on checkboxes
	              // and radios. We accept this limitation.
	              event.stopPropagation();
	              event.isImmediatePropagationStopped = returnTrue;
	            }
	          }
	        });
	      }
	      jQuery.removeEvent = function (elem, type, handle) {
	        // This "if" is needed for plain objects
	        if (elem.removeEventListener) {
	          elem.removeEventListener(type, handle);
	        }
	      };
	      jQuery.Event = function (src, props) {
	        // Allow instantiation without the 'new' keyword
	        if (!(this instanceof jQuery.Event)) {
	          return new jQuery.Event(src, props);
	        }

	        // Event object
	        if (src && src.type) {
	          this.originalEvent = src;
	          this.type = src.type;

	          // Events bubbling up the document may have been marked as prevented
	          // by a handler lower down the tree; reflect the correct value.
	          this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined &&
	          // Support: Android <=2.3 only
	          src.returnValue === false ? returnTrue : returnFalse;

	          // Create target properties
	          // Support: Safari <=6 - 7 only
	          // Target should not be a text node (trac-504, trac-13143)
	          this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target;
	          this.currentTarget = src.currentTarget;
	          this.relatedTarget = src.relatedTarget;

	          // Event type
	        } else {
	          this.type = src;
	        }

	        // Put explicitly provided properties onto the event object
	        if (props) {
	          jQuery.extend(this, props);
	        }

	        // Create a timestamp if incoming event doesn't have one
	        this.timeStamp = src && src.timeStamp || Date.now();

	        // Mark it as fixed
	        this[jQuery.expando] = true;
	      };

	      // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
	      // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	      jQuery.Event.prototype = {
	        constructor: jQuery.Event,
	        isDefaultPrevented: returnFalse,
	        isPropagationStopped: returnFalse,
	        isImmediatePropagationStopped: returnFalse,
	        isSimulated: false,
	        preventDefault: function () {
	          var e = this.originalEvent;
	          this.isDefaultPrevented = returnTrue;
	          if (e && !this.isSimulated) {
	            e.preventDefault();
	          }
	        },
	        stopPropagation: function () {
	          var e = this.originalEvent;
	          this.isPropagationStopped = returnTrue;
	          if (e && !this.isSimulated) {
	            e.stopPropagation();
	          }
	        },
	        stopImmediatePropagation: function () {
	          var e = this.originalEvent;
	          this.isImmediatePropagationStopped = returnTrue;
	          if (e && !this.isSimulated) {
	            e.stopImmediatePropagation();
	          }
	          this.stopPropagation();
	        }
	      };

	      // Includes all common event props including KeyEvent and MouseEvent specific props
	      jQuery.each({
	        altKey: true,
	        bubbles: true,
	        cancelable: true,
	        changedTouches: true,
	        ctrlKey: true,
	        detail: true,
	        eventPhase: true,
	        metaKey: true,
	        pageX: true,
	        pageY: true,
	        shiftKey: true,
	        view: true,
	        "char": true,
	        code: true,
	        charCode: true,
	        key: true,
	        keyCode: true,
	        button: true,
	        buttons: true,
	        clientX: true,
	        clientY: true,
	        offsetX: true,
	        offsetY: true,
	        pointerId: true,
	        pointerType: true,
	        screenX: true,
	        screenY: true,
	        targetTouches: true,
	        toElement: true,
	        touches: true,
	        which: true
	      }, jQuery.event.addProp);
	      jQuery.each({
	        focus: "focusin",
	        blur: "focusout"
	      }, function (type, delegateType) {
	        function focusMappedHandler(nativeEvent) {
	          if (document.documentMode) {
	            // Support: IE 11+
	            // Attach a single focusin/focusout handler on the document while someone wants
	            // focus/blur. This is because the former are synchronous in IE while the latter
	            // are async. In other browsers, all those handlers are invoked synchronously.

	            // `handle` from private data would already wrap the event, but we need
	            // to change the `type` here.
	            var handle = dataPriv.get(this, "handle"),
	              event = jQuery.event.fix(nativeEvent);
	            event.type = nativeEvent.type === "focusin" ? "focus" : "blur";
	            event.isSimulated = true;

	            // First, handle focusin/focusout
	            handle(nativeEvent);

	            // ...then, handle focus/blur
	            //
	            // focus/blur don't bubble while focusin/focusout do; simulate the former by only
	            // invoking the handler at the lower level.
	            if (event.target === event.currentTarget) {
	              // The setup part calls `leverageNative`, which, in turn, calls
	              // `jQuery.event.add`, so event handle will already have been set
	              // by this point.
	              handle(event);
	            }
	          } else {
	            // For non-IE browsers, attach a single capturing handler on the document
	            // while someone wants focusin/focusout.
	            jQuery.event.simulate(delegateType, nativeEvent.target, jQuery.event.fix(nativeEvent));
	          }
	        }
	        jQuery.event.special[type] = {
	          // Utilize native event if possible so blur/focus sequence is correct
	          setup: function () {
	            var attaches;

	            // Claim the first handler
	            // dataPriv.set( this, "focus", ... )
	            // dataPriv.set( this, "blur", ... )
	            leverageNative(this, type, true);
	            if (document.documentMode) {
	              // Support: IE 9 - 11+
	              // We use the same native handler for focusin & focus (and focusout & blur)
	              // so we need to coordinate setup & teardown parts between those events.
	              // Use `delegateType` as the key as `type` is already used by `leverageNative`.
	              attaches = dataPriv.get(this, delegateType);
	              if (!attaches) {
	                this.addEventListener(delegateType, focusMappedHandler);
	              }
	              dataPriv.set(this, delegateType, (attaches || 0) + 1);
	            } else {
	              // Return false to allow normal processing in the caller
	              return false;
	            }
	          },
	          trigger: function () {
	            // Force setup before trigger
	            leverageNative(this, type);

	            // Return non-false to allow normal event-path propagation
	            return true;
	          },
	          teardown: function () {
	            var attaches;
	            if (document.documentMode) {
	              attaches = dataPriv.get(this, delegateType) - 1;
	              if (!attaches) {
	                this.removeEventListener(delegateType, focusMappedHandler);
	                dataPriv.remove(this, delegateType);
	              } else {
	                dataPriv.set(this, delegateType, attaches);
	              }
	            } else {
	              // Return false to indicate standard teardown should be applied
	              return false;
	            }
	          },
	          // Suppress native focus or blur if we're currently inside
	          // a leveraged native-event stack
	          _default: function (event) {
	            return dataPriv.get(event.target, type);
	          },
	          delegateType: delegateType
	        };

	        // Support: Firefox <=44
	        // Firefox doesn't have focus(in | out) events
	        // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	        //
	        // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
	        // focus(in | out) events fire after focus & blur events,
	        // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	        // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
	        //
	        // Support: IE 9 - 11+
	        // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,
	        // attach a single handler for both events in IE.
	        jQuery.event.special[delegateType] = {
	          setup: function () {
	            // Handle: regular nodes (via `this.ownerDocument`), window
	            // (via `this.document`) & document (via `this`).
	            var doc = this.ownerDocument || this.document || this,
	              dataHolder = document.documentMode ? this : doc,
	              attaches = dataPriv.get(dataHolder, delegateType);

	            // Support: IE 9 - 11+
	            // We use the same native handler for focusin & focus (and focusout & blur)
	            // so we need to coordinate setup & teardown parts between those events.
	            // Use `delegateType` as the key as `type` is already used by `leverageNative`.
	            if (!attaches) {
	              if (document.documentMode) {
	                this.addEventListener(delegateType, focusMappedHandler);
	              } else {
	                doc.addEventListener(type, focusMappedHandler, true);
	              }
	            }
	            dataPriv.set(dataHolder, delegateType, (attaches || 0) + 1);
	          },
	          teardown: function () {
	            var doc = this.ownerDocument || this.document || this,
	              dataHolder = document.documentMode ? this : doc,
	              attaches = dataPriv.get(dataHolder, delegateType) - 1;
	            if (!attaches) {
	              if (document.documentMode) {
	                this.removeEventListener(delegateType, focusMappedHandler);
	              } else {
	                doc.removeEventListener(type, focusMappedHandler, true);
	              }
	              dataPriv.remove(dataHolder, delegateType);
	            } else {
	              dataPriv.set(dataHolder, delegateType, attaches);
	            }
	          }
	        };
	      });

	      // Create mouseenter/leave events using mouseover/out and event-time checks
	      // so that event delegation works in jQuery.
	      // Do the same for pointerenter/pointerleave and pointerover/pointerout
	      //
	      // Support: Safari 7 only
	      // Safari sends mouseenter too often; see:
	      // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
	      // for the description of the bug (it existed in older Chrome versions as well).
	      jQuery.each({
	        mouseenter: "mouseover",
	        mouseleave: "mouseout",
	        pointerenter: "pointerover",
	        pointerleave: "pointerout"
	      }, function (orig, fix) {
	        jQuery.event.special[orig] = {
	          delegateType: fix,
	          bindType: fix,
	          handle: function (event) {
	            var ret,
	              target = this,
	              related = event.relatedTarget,
	              handleObj = event.handleObj;

	            // For mouseenter/leave call the handler if related is outside the target.
	            // NB: No relatedTarget if the mouse left/entered the browser window
	            if (!related || related !== target && !jQuery.contains(target, related)) {
	              event.type = handleObj.origType;
	              ret = handleObj.handler.apply(this, arguments);
	              event.type = fix;
	            }
	            return ret;
	          }
	        };
	      });
	      jQuery.fn.extend({
	        on: function (types, selector, data, fn) {
	          return on(this, types, selector, data, fn);
	        },
	        one: function (types, selector, data, fn) {
	          return on(this, types, selector, data, fn, 1);
	        },
	        off: function (types, selector, fn) {
	          var handleObj, type;
	          if (types && types.preventDefault && types.handleObj) {
	            // ( event )  dispatched jQuery.Event
	            handleObj = types.handleObj;
	            jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
	            return this;
	          }
	          if (typeof types === "object") {
	            // ( types-object [, selector] )
	            for (type in types) {
	              this.off(type, selector, types[type]);
	            }
	            return this;
	          }
	          if (selector === false || typeof selector === "function") {
	            // ( types [, fn] )
	            fn = selector;
	            selector = undefined;
	          }
	          if (fn === false) {
	            fn = returnFalse;
	          }
	          return this.each(function () {
	            jQuery.event.remove(this, types, fn, selector);
	          });
	        }
	      });
	      var
	        // Support: IE <=10 - 11, Edge 12 - 13 only
	        // In IE/Edge using regex groups here causes severe slowdowns.
	        // See https://connect.microsoft.com/IE/feedback/details/1736512/
	        rnoInnerhtml = /<script|<style|<link/i,
	        // checked="checked" or checked
	        rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
	        rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;

	      // Prefer a tbody over its parent table for containing new rows
	      function manipulationTarget(elem, content) {
	        if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {
	          return jQuery(elem).children("tbody")[0] || elem;
	        }
	        return elem;
	      }

	      // Replace/restore the type attribute of script elements for safe DOM manipulation
	      function disableScript(elem) {
	        elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
	        return elem;
	      }
	      function restoreScript(elem) {
	        if ((elem.type || "").slice(0, 5) === "true/") {
	          elem.type = elem.type.slice(5);
	        } else {
	          elem.removeAttribute("type");
	        }
	        return elem;
	      }
	      function cloneCopyEvent(src, dest) {
	        var i, l, type, pdataOld, udataOld, udataCur, events;
	        if (dest.nodeType !== 1) {
	          return;
	        }

	        // 1. Copy private data: events, handlers, etc.
	        if (dataPriv.hasData(src)) {
	          pdataOld = dataPriv.get(src);
	          events = pdataOld.events;
	          if (events) {
	            dataPriv.remove(dest, "handle events");
	            for (type in events) {
	              for (i = 0, l = events[type].length; i < l; i++) {
	                jQuery.event.add(dest, type, events[type][i]);
	              }
	            }
	          }
	        }

	        // 2. Copy user data
	        if (dataUser.hasData(src)) {
	          udataOld = dataUser.access(src);
	          udataCur = jQuery.extend({}, udataOld);
	          dataUser.set(dest, udataCur);
	        }
	      }

	      // Fix IE bugs, see support tests
	      function fixInput(src, dest) {
	        var nodeName = dest.nodeName.toLowerCase();

	        // Fails to persist the checked state of a cloned checkbox or radio button.
	        if (nodeName === "input" && rcheckableType.test(src.type)) {
	          dest.checked = src.checked;

	          // Fails to return the selected option to the default selected state when cloning options
	        } else if (nodeName === "input" || nodeName === "textarea") {
	          dest.defaultValue = src.defaultValue;
	        }
	      }
	      function domManip(collection, args, callback, ignored) {
	        // Flatten any nested arrays
	        args = flat(args);
	        var fragment,
	          first,
	          scripts,
	          hasScripts,
	          node,
	          doc,
	          i = 0,
	          l = collection.length,
	          iNoClone = l - 1,
	          value = args[0],
	          valueIsFunction = isFunction(value);

	        // We can't cloneNode fragments that contain checked, in WebKit
	        if (valueIsFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) {
	          return collection.each(function (index) {
	            var self = collection.eq(index);
	            if (valueIsFunction) {
	              args[0] = value.call(this, index, self.html());
	            }
	            domManip(self, args, callback, ignored);
	          });
	        }
	        if (l) {
	          fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
	          first = fragment.firstChild;
	          if (fragment.childNodes.length === 1) {
	            fragment = first;
	          }

	          // Require either new content or an interest in ignored elements to invoke the callback
	          if (first || ignored) {
	            scripts = jQuery.map(getAll(fragment, "script"), disableScript);
	            hasScripts = scripts.length;

	            // Use the original fragment for the last item
	            // instead of the first because it can end up
	            // being emptied incorrectly in certain situations (trac-8070).
	            for (; i < l; i++) {
	              node = fragment;
	              if (i !== iNoClone) {
	                node = jQuery.clone(node, true, true);

	                // Keep references to cloned scripts for later restoration
	                if (hasScripts) {
	                  // Support: Android <=4.0 only, PhantomJS 1 only
	                  // push.apply(_, arraylike) throws on ancient WebKit
	                  jQuery.merge(scripts, getAll(node, "script"));
	                }
	              }
	              callback.call(collection[i], node, i);
	            }
	            if (hasScripts) {
	              doc = scripts[scripts.length - 1].ownerDocument;

	              // Re-enable scripts
	              jQuery.map(scripts, restoreScript);

	              // Evaluate executable scripts on first document insertion
	              for (i = 0; i < hasScripts; i++) {
	                node = scripts[i];
	                if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) {
	                  if (node.src && (node.type || "").toLowerCase() !== "module") {
	                    // Optional AJAX dependency, but won't run scripts if not present
	                    if (jQuery._evalUrl && !node.noModule) {
	                      jQuery._evalUrl(node.src, {
	                        nonce: node.nonce || node.getAttribute("nonce")
	                      }, doc);
	                    }
	                  } else {
	                    // Unwrap a CDATA section containing script contents. This shouldn't be
	                    // needed as in XML documents they're already not visible when
	                    // inspecting element contents and in HTML documents they have no
	                    // meaning but we're preserving that logic for backwards compatibility.
	                    // This will be removed completely in 4.0. See gh-4904.
	                    DOMEval(node.textContent.replace(rcleanScript, ""), node, doc);
	                  }
	                }
	              }
	            }
	          }
	        }
	        return collection;
	      }
	      function remove(elem, selector, keepData) {
	        var node,
	          nodes = selector ? jQuery.filter(selector, elem) : elem,
	          i = 0;
	        for (; (node = nodes[i]) != null; i++) {
	          if (!keepData && node.nodeType === 1) {
	            jQuery.cleanData(getAll(node));
	          }
	          if (node.parentNode) {
	            if (keepData && isAttached(node)) {
	              setGlobalEval(getAll(node, "script"));
	            }
	            node.parentNode.removeChild(node);
	          }
	        }
	        return elem;
	      }
	      jQuery.extend({
	        htmlPrefilter: function (html) {
	          return html;
	        },
	        clone: function (elem, dataAndEvents, deepDataAndEvents) {
	          var i,
	            l,
	            srcElements,
	            destElements,
	            clone = elem.cloneNode(true),
	            inPage = isAttached(elem);

	          // Fix IE cloning issues
	          if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {
	            // We eschew jQuery#find here for performance reasons:
	            // https://jsperf.com/getall-vs-sizzle/2
	            destElements = getAll(clone);
	            srcElements = getAll(elem);
	            for (i = 0, l = srcElements.length; i < l; i++) {
	              fixInput(srcElements[i], destElements[i]);
	            }
	          }

	          // Copy the events from the original to the clone
	          if (dataAndEvents) {
	            if (deepDataAndEvents) {
	              srcElements = srcElements || getAll(elem);
	              destElements = destElements || getAll(clone);
	              for (i = 0, l = srcElements.length; i < l; i++) {
	                cloneCopyEvent(srcElements[i], destElements[i]);
	              }
	            } else {
	              cloneCopyEvent(elem, clone);
	            }
	          }

	          // Preserve script evaluation history
	          destElements = getAll(clone, "script");
	          if (destElements.length > 0) {
	            setGlobalEval(destElements, !inPage && getAll(elem, "script"));
	          }

	          // Return the cloned set
	          return clone;
	        },
	        cleanData: function (elems) {
	          var data,
	            elem,
	            type,
	            special = jQuery.event.special,
	            i = 0;
	          for (; (elem = elems[i]) !== undefined; i++) {
	            if (acceptData(elem)) {
	              if (data = elem[dataPriv.expando]) {
	                if (data.events) {
	                  for (type in data.events) {
	                    if (special[type]) {
	                      jQuery.event.remove(elem, type);

	                      // This is a shortcut to avoid jQuery.event.remove's overhead
	                    } else {
	                      jQuery.removeEvent(elem, type, data.handle);
	                    }
	                  }
	                }

	                // Support: Chrome <=35 - 45+
	                // Assign undefined instead of using delete, see Data#remove
	                elem[dataPriv.expando] = undefined;
	              }
	              if (elem[dataUser.expando]) {
	                // Support: Chrome <=35 - 45+
	                // Assign undefined instead of using delete, see Data#remove
	                elem[dataUser.expando] = undefined;
	              }
	            }
	          }
	        }
	      });
	      jQuery.fn.extend({
	        detach: function (selector) {
	          return remove(this, selector, true);
	        },
	        remove: function (selector) {
	          return remove(this, selector);
	        },
	        text: function (value) {
	          return access(this, function (value) {
	            return value === undefined ? jQuery.text(this) : this.empty().each(function () {
	              if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
	                this.textContent = value;
	              }
	            });
	          }, null, value, arguments.length);
	        },
	        append: function () {
	          return domManip(this, arguments, function (elem) {
	            if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
	              var target = manipulationTarget(this, elem);
	              target.appendChild(elem);
	            }
	          });
	        },
	        prepend: function () {
	          return domManip(this, arguments, function (elem) {
	            if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
	              var target = manipulationTarget(this, elem);
	              target.insertBefore(elem, target.firstChild);
	            }
	          });
	        },
	        before: function () {
	          return domManip(this, arguments, function (elem) {
	            if (this.parentNode) {
	              this.parentNode.insertBefore(elem, this);
	            }
	          });
	        },
	        after: function () {
	          return domManip(this, arguments, function (elem) {
	            if (this.parentNode) {
	              this.parentNode.insertBefore(elem, this.nextSibling);
	            }
	          });
	        },
	        empty: function () {
	          var elem,
	            i = 0;
	          for (; (elem = this[i]) != null; i++) {
	            if (elem.nodeType === 1) {
	              // Prevent memory leaks
	              jQuery.cleanData(getAll(elem, false));

	              // Remove any remaining nodes
	              elem.textContent = "";
	            }
	          }
	          return this;
	        },
	        clone: function (dataAndEvents, deepDataAndEvents) {
	          dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
	          deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
	          return this.map(function () {
	            return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
	          });
	        },
	        html: function (value) {
	          return access(this, function (value) {
	            var elem = this[0] || {},
	              i = 0,
	              l = this.length;
	            if (value === undefined && elem.nodeType === 1) {
	              return elem.innerHTML;
	            }

	            // See if we can take a shortcut and just use innerHTML
	            if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
	              value = jQuery.htmlPrefilter(value);
	              try {
	                for (; i < l; i++) {
	                  elem = this[i] || {};

	                  // Remove element nodes and prevent memory leaks
	                  if (elem.nodeType === 1) {
	                    jQuery.cleanData(getAll(elem, false));
	                    elem.innerHTML = value;
	                  }
	                }
	                elem = 0;

	                // If using innerHTML throws an exception, use the fallback method
	              } catch (e) {}
	            }
	            if (elem) {
	              this.empty().append(value);
	            }
	          }, null, value, arguments.length);
	        },
	        replaceWith: function () {
	          var ignored = [];

	          // Make the changes, replacing each non-ignored context element with the new content
	          return domManip(this, arguments, function (elem) {
	            var parent = this.parentNode;
	            if (jQuery.inArray(this, ignored) < 0) {
	              jQuery.cleanData(getAll(this));
	              if (parent) {
	                parent.replaceChild(elem, this);
	              }
	            }

	            // Force callback invocation
	          }, ignored);
	        }
	      });
	      jQuery.each({
	        appendTo: "append",
	        prependTo: "prepend",
	        insertBefore: "before",
	        insertAfter: "after",
	        replaceAll: "replaceWith"
	      }, function (name, original) {
	        jQuery.fn[name] = function (selector) {
	          var elems,
	            ret = [],
	            insert = jQuery(selector),
	            last = insert.length - 1,
	            i = 0;
	          for (; i <= last; i++) {
	            elems = i === last ? this : this.clone(true);
	            jQuery(insert[i])[original](elems);

	            // Support: Android <=4.0 only, PhantomJS 1 only
	            // .get() because push.apply(_, arraylike) throws on ancient WebKit
	            push.apply(ret, elems.get());
	          }
	          return this.pushStack(ret);
	        };
	      });
	      var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
	      var rcustomProp = /^--/;
	      var getStyles = function (elem) {
	        // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
	        // IE throws on elements created in popups
	        // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
	        var view = elem.ownerDocument.defaultView;
	        if (!view || !view.opener) {
	          view = window;
	        }
	        return view.getComputedStyle(elem);
	      };
	      var swap = function (elem, options, callback) {
	        var ret,
	          name,
	          old = {};

	        // Remember the old values, and insert the new ones
	        for (name in options) {
	          old[name] = elem.style[name];
	          elem.style[name] = options[name];
	        }
	        ret = callback.call(elem);

	        // Revert the old values
	        for (name in options) {
	          elem.style[name] = old[name];
	        }
	        return ret;
	      };
	      var rboxStyle = new RegExp(cssExpand.join("|"), "i");
	      (function () {
	        // Executing both pixelPosition & boxSizingReliable tests require only one layout
	        // so they're executed at the same time to save the second computation.
	        function computeStyleTests() {
	          // This is a singleton, we need to execute it only once
	          if (!div) {
	            return;
	          }
	          container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0";
	          div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%";
	          documentElement.appendChild(container).appendChild(div);
	          var divStyle = window.getComputedStyle(div);
	          pixelPositionVal = divStyle.top !== "1%";

	          // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
	          reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12;

	          // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
	          // Some styles come back with percentage values, even though they shouldn't
	          div.style.right = "60%";
	          pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36;

	          // Support: IE 9 - 11 only
	          // Detect misreporting of content dimensions for box-sizing:border-box elements
	          boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36;

	          // Support: IE 9 only
	          // Detect overflow:scroll screwiness (gh-3699)
	          // Support: Chrome <=64
	          // Don't get tricked when zoom affects offsetWidth (gh-4029)
	          div.style.position = "absolute";
	          scrollboxSizeVal = roundPixelMeasures(div.offsetWidth / 3) === 12;
	          documentElement.removeChild(container);

	          // Nullify the div so it wouldn't be stored in the memory and
	          // it will also be a sign that checks already performed
	          div = null;
	        }
	        function roundPixelMeasures(measure) {
	          return Math.round(parseFloat(measure));
	        }
	        var pixelPositionVal,
	          boxSizingReliableVal,
	          scrollboxSizeVal,
	          pixelBoxStylesVal,
	          reliableTrDimensionsVal,
	          reliableMarginLeftVal,
	          container = document.createElement("div"),
	          div = document.createElement("div");

	        // Finish early in limited (non-browser) environments
	        if (!div.style) {
	          return;
	        }

	        // Support: IE <=9 - 11 only
	        // Style of cloned element affects source element cloned (trac-8908)
	        div.style.backgroundClip = "content-box";
	        div.cloneNode(true).style.backgroundClip = "";
	        support.clearCloneStyle = div.style.backgroundClip === "content-box";
	        jQuery.extend(support, {
	          boxSizingReliable: function () {
	            computeStyleTests();
	            return boxSizingReliableVal;
	          },
	          pixelBoxStyles: function () {
	            computeStyleTests();
	            return pixelBoxStylesVal;
	          },
	          pixelPosition: function () {
	            computeStyleTests();
	            return pixelPositionVal;
	          },
	          reliableMarginLeft: function () {
	            computeStyleTests();
	            return reliableMarginLeftVal;
	          },
	          scrollboxSize: function () {
	            computeStyleTests();
	            return scrollboxSizeVal;
	          },
	          // Support: IE 9 - 11+, Edge 15 - 18+
	          // IE/Edge misreport `getComputedStyle` of table rows with width/height
	          // set in CSS while `offset*` properties report correct values.
	          // Behavior in IE 9 is more subtle than in newer versions & it passes
	          // some versions of this test; make sure not to make it pass there!
	          //
	          // Support: Firefox 70+
	          // Only Firefox includes border widths
	          // in computed dimensions. (gh-4529)
	          reliableTrDimensions: function () {
	            var table, tr, trChild, trStyle;
	            if (reliableTrDimensionsVal == null) {
	              table = document.createElement("table");
	              tr = document.createElement("tr");
	              trChild = document.createElement("div");
	              table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
	              tr.style.cssText = "box-sizing:content-box;border:1px solid";

	              // Support: Chrome 86+
	              // Height set through cssText does not get applied.
	              // Computed height then comes back as 0.
	              tr.style.height = "1px";
	              trChild.style.height = "9px";

	              // Support: Android 8 Chrome 86+
	              // In our bodyBackground.html iframe,
	              // display for all div elements is set to "inline",
	              // which causes a problem only in Android 8 Chrome 86.
	              // Ensuring the div is `display: block`
	              // gets around this issue.
	              trChild.style.display = "block";
	              documentElement.appendChild(table).appendChild(tr).appendChild(trChild);
	              trStyle = window.getComputedStyle(tr);
	              reliableTrDimensionsVal = parseInt(trStyle.height, 10) + parseInt(trStyle.borderTopWidth, 10) + parseInt(trStyle.borderBottomWidth, 10) === tr.offsetHeight;
	              documentElement.removeChild(table);
	            }
	            return reliableTrDimensionsVal;
	          }
	        });
	      })();
	      function curCSS(elem, name, computed) {
	        var width,
	          minWidth,
	          maxWidth,
	          ret,
	          isCustomProp = rcustomProp.test(name),
	          // Support: Firefox 51+
	          // Retrieving style before computed somehow
	          // fixes an issue with getting wrong values
	          // on detached elements
	          style = elem.style;
	        computed = computed || getStyles(elem);

	        // getPropertyValue is needed for:
	        //   .css('filter') (IE 9 only, trac-12537)
	        //   .css('--customProperty) (gh-3144)
	        if (computed) {
	          // Support: IE <=9 - 11+
	          // IE only supports `"float"` in `getPropertyValue`; in computed styles
	          // it's only available as `"cssFloat"`. We no longer modify properties
	          // sent to `.css()` apart from camelCasing, so we need to check both.
	          // Normally, this would create difference in behavior: if
	          // `getPropertyValue` returns an empty string, the value returned
	          // by `.css()` would be `undefined`. This is usually the case for
	          // disconnected elements. However, in IE even disconnected elements
	          // with no styles return `"none"` for `getPropertyValue( "float" )`
	          ret = computed.getPropertyValue(name) || computed[name];
	          if (isCustomProp && ret) {
	            // Support: Firefox 105+, Chrome <=105+
	            // Spec requires trimming whitespace for custom properties (gh-4926).
	            // Firefox only trims leading whitespace. Chrome just collapses
	            // both leading & trailing whitespace to a single space.
	            //
	            // Fall back to `undefined` if empty string returned.
	            // This collapses a missing definition with property defined
	            // and set to an empty string but there's no standard API
	            // allowing us to differentiate them without a performance penalty
	            // and returning `undefined` aligns with older jQuery.
	            //
	            // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED
	            // as whitespace while CSS does not, but this is not a problem
	            // because CSS preprocessing replaces them with U+000A LINE FEED
	            // (which *is* CSS whitespace)
	            // https://www.w3.org/TR/css-syntax-3/#input-preprocessing
	            ret = ret.replace(rtrimCSS, "$1") || undefined;
	          }
	          if (ret === "" && !isAttached(elem)) {
	            ret = jQuery.style(elem, name);
	          }

	          // A tribute to the "awesome hack by Dean Edwards"
	          // Android Browser returns percentage for some values,
	          // but width seems to be reliably pixels.
	          // This is against the CSSOM draft spec:
	          // https://drafts.csswg.org/cssom/#resolved-values
	          if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) {
	            // Remember the original values
	            width = style.width;
	            minWidth = style.minWidth;
	            maxWidth = style.maxWidth;

	            // Put in the new values to get a computed value out
	            style.minWidth = style.maxWidth = style.width = ret;
	            ret = computed.width;

	            // Revert the changed values
	            style.width = width;
	            style.minWidth = minWidth;
	            style.maxWidth = maxWidth;
	          }
	        }
	        return ret !== undefined ?
	        // Support: IE <=9 - 11 only
	        // IE returns zIndex value as an integer.
	        ret + "" : ret;
	      }
	      function addGetHookIf(conditionFn, hookFn) {
	        // Define the hook, we'll check on the first run if it's really needed.
	        return {
	          get: function () {
	            if (conditionFn()) {
	              // Hook not needed (or it's not possible to use it due
	              // to missing dependency), remove it.
	              delete this.get;
	              return;
	            }

	            // Hook needed; redefine it so that the support test is not executed again.
	            return (this.get = hookFn).apply(this, arguments);
	          }
	        };
	      }
	      var cssPrefixes = ["Webkit", "Moz", "ms"],
	        emptyStyle = document.createElement("div").style,
	        vendorProps = {};

	      // Return a vendor-prefixed property or undefined
	      function vendorPropName(name) {
	        // Check for vendor prefixed names
	        var capName = name[0].toUpperCase() + name.slice(1),
	          i = cssPrefixes.length;
	        while (i--) {
	          name = cssPrefixes[i] + capName;
	          if (name in emptyStyle) {
	            return name;
	          }
	        }
	      }

	      // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
	      function finalPropName(name) {
	        var final = jQuery.cssProps[name] || vendorProps[name];
	        if (final) {
	          return final;
	        }
	        if (name in emptyStyle) {
	          return name;
	        }
	        return vendorProps[name] = vendorPropName(name) || name;
	      }
	      var
	        // Swappable if display is none or starts with table
	        // except "table", "table-cell", or "table-caption"
	        // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
	        rdisplayswap = /^(none|table(?!-c[ea]).+)/,
	        cssShow = {
	          position: "absolute",
	          visibility: "hidden",
	          display: "block"
	        },
	        cssNormalTransform = {
	          letterSpacing: "0",
	          fontWeight: "400"
	        };
	      function setPositiveNumber(_elem, value, subtract) {
	        // Any relative (+/-) values have already been
	        // normalized at this point
	        var matches = rcssNum.exec(value);
	        return matches ?
	        // Guard against undefined "subtract", e.g., when used as in cssHooks
	        Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value;
	      }
	      function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {
	        var i = dimension === "width" ? 1 : 0,
	          extra = 0,
	          delta = 0,
	          marginDelta = 0;

	        // Adjustment may not be necessary
	        if (box === (isBorderBox ? "border" : "content")) {
	          return 0;
	        }
	        for (; i < 4; i += 2) {
	          // Both box models exclude margin
	          // Count margin delta separately to only add it after scroll gutter adjustment.
	          // This is needed to make negative margins work with `outerHeight( true )` (gh-3982).
	          if (box === "margin") {
	            marginDelta += jQuery.css(elem, box + cssExpand[i], true, styles);
	          }

	          // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
	          if (!isBorderBox) {
	            // Add padding
	            delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles);

	            // For "border" or "margin", add border
	            if (box !== "padding") {
	              delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);

	              // But still keep track of it otherwise
	            } else {
	              extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
	            }

	            // If we get here with a border-box (content + padding + border), we're seeking "content" or
	            // "padding" or "margin"
	          } else {
	            // For "content", subtract padding
	            if (box === "content") {
	              delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
	            }

	            // For "content" or "padding", subtract border
	            if (box !== "margin") {
	              delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
	            }
	          }
	        }

	        // Account for positive content-box scroll gutter when requested by providing computedVal
	        if (!isBorderBox && computedVal >= 0) {
	          // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
	          // Assuming integer scroll gutter, subtract the rest and round down
	          delta += Math.max(0, Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5

	          // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
	          // Use an explicit zero to avoid NaN (gh-3964)
	          )) || 0;
	        }
	        return delta + marginDelta;
	      }
	      function getWidthOrHeight(elem, dimension, extra) {
	        // Start with computed style
	        var styles = getStyles(elem),
	          // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
	          // Fake content-box until we know it's needed to know the true value.
	          boxSizingNeeded = !support.boxSizingReliable() || extra,
	          isBorderBox = boxSizingNeeded && jQuery.css(elem, "boxSizing", false, styles) === "border-box",
	          valueIsBorderBox = isBorderBox,
	          val = curCSS(elem, dimension, styles),
	          offsetProp = "offset" + dimension[0].toUpperCase() + dimension.slice(1);

	        // Support: Firefox <=54
	        // Return a confounding non-pixel value or feign ignorance, as appropriate.
	        if (rnumnonpx.test(val)) {
	          if (!extra) {
	            return val;
	          }
	          val = "auto";
	        }

	        // Support: IE 9 - 11 only
	        // Use offsetWidth/offsetHeight for when box sizing is unreliable.
	        // In those cases, the computed value can be trusted to be border-box.
	        if ((!support.boxSizingReliable() && isBorderBox ||
	        // Support: IE 10 - 11+, Edge 15 - 18+
	        // IE/Edge misreport `getComputedStyle` of table rows with width/height
	        // set in CSS while `offset*` properties report correct values.
	        // Interestingly, in some cases IE 9 doesn't suffer from this issue.
	        !support.reliableTrDimensions() && nodeName(elem, "tr") ||
	        // Fall back to offsetWidth/offsetHeight when value is "auto"
	        // This happens for inline elements with no explicit setting (gh-3571)
	        val === "auto" ||
	        // Support: Android <=4.1 - 4.3 only
	        // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
	        !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") &&
	        // Make sure the element is visible & connected
	        elem.getClientRects().length) {
	          isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";

	          // Where available, offsetWidth/offsetHeight approximate border box dimensions.
	          // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
	          // retrieved value as a content box dimension.
	          valueIsBorderBox = offsetProp in elem;
	          if (valueIsBorderBox) {
	            val = elem[offsetProp];
	          }
	        }

	        // Normalize "" and auto
	        val = parseFloat(val) || 0;

	        // Adjust for the element's box model
	        return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles,
	        // Provide the current computed size to request scroll gutter calculation (gh-3589)
	        val) + "px";
	      }
	      jQuery.extend({
	        // Add in style property hooks for overriding the default
	        // behavior of getting and setting a style property
	        cssHooks: {
	          opacity: {
	            get: function (elem, computed) {
	              if (computed) {
	                // We should always get a number back from opacity
	                var ret = curCSS(elem, "opacity");
	                return ret === "" ? "1" : ret;
	              }
	            }
	          }
	        },
	        // Don't automatically add "px" to these possibly-unitless properties
	        cssNumber: {
	          animationIterationCount: true,
	          aspectRatio: true,
	          borderImageSlice: true,
	          columnCount: true,
	          flexGrow: true,
	          flexShrink: true,
	          fontWeight: true,
	          gridArea: true,
	          gridColumn: true,
	          gridColumnEnd: true,
	          gridColumnStart: true,
	          gridRow: true,
	          gridRowEnd: true,
	          gridRowStart: true,
	          lineHeight: true,
	          opacity: true,
	          order: true,
	          orphans: true,
	          scale: true,
	          widows: true,
	          zIndex: true,
	          zoom: true,
	          // SVG-related
	          fillOpacity: true,
	          floodOpacity: true,
	          stopOpacity: true,
	          strokeMiterlimit: true,
	          strokeOpacity: true
	        },
	        // Add in properties whose names you wish to fix before
	        // setting or getting the value
	        cssProps: {},
	        // Get and set the style property on a DOM Node
	        style: function (elem, name, value, extra) {
	          // Don't set styles on text and comment nodes
	          if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
	            return;
	          }

	          // Make sure that we're working with the right name
	          var ret,
	            type,
	            hooks,
	            origName = camelCase(name),
	            isCustomProp = rcustomProp.test(name),
	            style = elem.style;

	          // Make sure that we're working with the right name. We don't
	          // want to query the value if it is a CSS custom property
	          // since they are user-defined.
	          if (!isCustomProp) {
	            name = finalPropName(origName);
	          }

	          // Gets hook for the prefixed version, then unprefixed version
	          hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];

	          // Check if we're setting a value
	          if (value !== undefined) {
	            type = typeof value;

	            // Convert "+=" or "-=" to relative numbers (trac-7345)
	            if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
	              value = adjustCSS(elem, name, ret);

	              // Fixes bug trac-9237
	              type = "number";
	            }

	            // Make sure that null and NaN values aren't set (trac-7116)
	            if (value == null || value !== value) {
	              return;
	            }

	            // If a number was passed in, add the unit (except for certain CSS properties)
	            // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
	            // "px" to a few hardcoded values.
	            if (type === "number" && !isCustomProp) {
	              value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
	            }

	            // background-* props affect original clone's values
	            if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
	              style[name] = "inherit";
	            }

	            // If a hook was provided, use that value, otherwise just set the specified value
	            if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
	              if (isCustomProp) {
	                style.setProperty(name, value);
	              } else {
	                style[name] = value;
	              }
	            }
	          } else {
	            // If a hook was provided get the non-computed value from there
	            if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
	              return ret;
	            }

	            // Otherwise just get the value from the style object
	            return style[name];
	          }
	        },
	        css: function (elem, name, extra, styles) {
	          var val,
	            num,
	            hooks,
	            origName = camelCase(name),
	            isCustomProp = rcustomProp.test(name);

	          // Make sure that we're working with the right name. We don't
	          // want to modify the value if it is a CSS custom property
	          // since they are user-defined.
	          if (!isCustomProp) {
	            name = finalPropName(origName);
	          }

	          // Try prefixed name followed by the unprefixed name
	          hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];

	          // If a hook was provided get the computed value from there
	          if (hooks && "get" in hooks) {
	            val = hooks.get(elem, true, extra);
	          }

	          // Otherwise, if a way to get the computed value exists, use that
	          if (val === undefined) {
	            val = curCSS(elem, name, styles);
	          }

	          // Convert "normal" to computed value
	          if (val === "normal" && name in cssNormalTransform) {
	            val = cssNormalTransform[name];
	          }

	          // Make numeric if forced or a qualifier was provided and val looks numeric
	          if (extra === "" || extra) {
	            num = parseFloat(val);
	            return extra === true || isFinite(num) ? num || 0 : val;
	          }
	          return val;
	        }
	      });
	      jQuery.each(["height", "width"], function (_i, dimension) {
	        jQuery.cssHooks[dimension] = {
	          get: function (elem, computed, extra) {
	            if (computed) {
	              // Certain elements can have dimension info if we invisibly show them
	              // but it must have a current display style that would benefit
	              return rdisplayswap.test(jQuery.css(elem, "display")) && (
	              // Support: Safari 8+
	              // Table columns in Safari have non-zero offsetWidth & zero
	              // getBoundingClientRect().width unless display is changed.
	              // Support: IE <=11 only
	              // Running getBoundingClientRect on a disconnected node
	              // in IE throws an error.
	              !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () {
	                return getWidthOrHeight(elem, dimension, extra);
	              }) : getWidthOrHeight(elem, dimension, extra);
	            }
	          },
	          set: function (elem, value, extra) {
	            var matches,
	              styles = getStyles(elem),
	              // Only read styles.position if the test has a chance to fail
	              // to avoid forcing a reflow.
	              scrollboxSizeBuggy = !support.scrollboxSize() && styles.position === "absolute",
	              // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
	              boxSizingNeeded = scrollboxSizeBuggy || extra,
	              isBorderBox = boxSizingNeeded && jQuery.css(elem, "boxSizing", false, styles) === "border-box",
	              subtract = extra ? boxModelAdjustment(elem, dimension, extra, isBorderBox, styles) : 0;

	            // Account for unreliable border-box dimensions by comparing offset* to computed and
	            // faking a content-box to get border and padding (gh-3699)
	            if (isBorderBox && scrollboxSizeBuggy) {
	              subtract -= Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, "border", false, styles) - 0.5);
	            }

	            // Convert to pixels if value adjustment is needed
	            if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") {
	              elem.style[dimension] = value;
	              value = jQuery.css(elem, dimension);
	            }
	            return setPositiveNumber(elem, value, subtract);
	          }
	        };
	      });
	      jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) {
	        if (computed) {
	          return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, {
	            marginLeft: 0
	          }, function () {
	            return elem.getBoundingClientRect().left;
	          })) + "px";
	        }
	      });

	      // These hooks are used by animate to expand properties
	      jQuery.each({
	        margin: "",
	        padding: "",
	        border: "Width"
	      }, function (prefix, suffix) {
	        jQuery.cssHooks[prefix + suffix] = {
	          expand: function (value) {
	            var i = 0,
	              expanded = {},
	              // Assumes a single number if not a string
	              parts = typeof value === "string" ? value.split(" ") : [value];
	            for (; i < 4; i++) {
	              expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];
	            }
	            return expanded;
	          }
	        };
	        if (prefix !== "margin") {
	          jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
	        }
	      });
	      jQuery.fn.extend({
	        css: function (name, value) {
	          return access(this, function (elem, name, value) {
	            var styles,
	              len,
	              map = {},
	              i = 0;
	            if (Array.isArray(name)) {
	              styles = getStyles(elem);
	              len = name.length;
	              for (; i < len; i++) {
	                map[name[i]] = jQuery.css(elem, name[i], false, styles);
	              }
	              return map;
	            }
	            return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name);
	          }, name, value, arguments.length > 1);
	        }
	      });
	      function Tween(elem, options, prop, end, easing) {
	        return new Tween.prototype.init(elem, options, prop, end, easing);
	      }
	      jQuery.Tween = Tween;
	      Tween.prototype = {
	        constructor: Tween,
	        init: function (elem, options, prop, end, easing, unit) {
	          this.elem = elem;
	          this.prop = prop;
	          this.easing = easing || jQuery.easing._default;
	          this.options = options;
	          this.start = this.now = this.cur();
	          this.end = end;
	          this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
	        },
	        cur: function () {
	          var hooks = Tween.propHooks[this.prop];
	          return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this);
	        },
	        run: function (percent) {
	          var eased,
	            hooks = Tween.propHooks[this.prop];
	          if (this.options.duration) {
	            this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration);
	          } else {
	            this.pos = eased = percent;
	          }
	          this.now = (this.end - this.start) * eased + this.start;
	          if (this.options.step) {
	            this.options.step.call(this.elem, this.now, this);
	          }
	          if (hooks && hooks.set) {
	            hooks.set(this);
	          } else {
	            Tween.propHooks._default.set(this);
	          }
	          return this;
	        }
	      };
	      Tween.prototype.init.prototype = Tween.prototype;
	      Tween.propHooks = {
	        _default: {
	          get: function (tween) {
	            var result;

	            // Use a property on the element directly when it is not a DOM element,
	            // or when there is no matching style property that exists.
	            if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
	              return tween.elem[tween.prop];
	            }

	            // Passing an empty string as a 3rd parameter to .css will automatically
	            // attempt a parseFloat and fallback to a string if the parse fails.
	            // Simple values such as "10px" are parsed to Float;
	            // complex values such as "rotate(1rad)" are returned as-is.
	            result = jQuery.css(tween.elem, tween.prop, "");

	            // Empty strings, null, undefined and "auto" are converted to 0.
	            return !result || result === "auto" ? 0 : result;
	          },
	          set: function (tween) {
	            // Use step hook for back compat.
	            // Use cssHook if its there.
	            // Use .style if available and use plain properties where available.
	            if (jQuery.fx.step[tween.prop]) {
	              jQuery.fx.step[tween.prop](tween);
	            } else if (tween.elem.nodeType === 1 && (jQuery.cssHooks[tween.prop] || tween.elem.style[finalPropName(tween.prop)] != null)) {
	              jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
	            } else {
	              tween.elem[tween.prop] = tween.now;
	            }
	          }
	        }
	      };

	      // Support: IE <=9 only
	      // Panic based approach to setting things on disconnected nodes
	      Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
	        set: function (tween) {
	          if (tween.elem.nodeType && tween.elem.parentNode) {
	            tween.elem[tween.prop] = tween.now;
	          }
	        }
	      };
	      jQuery.easing = {
	        linear: function (p) {
	          return p;
	        },
	        swing: function (p) {
	          return 0.5 - Math.cos(p * Math.PI) / 2;
	        },
	        _default: "swing"
	      };
	      jQuery.fx = Tween.prototype.init;

	      // Back compat <1.8 extension point
	      jQuery.fx.step = {};
	      var fxNow,
	        inProgress,
	        rfxtypes = /^(?:toggle|show|hide)$/,
	        rrun = /queueHooks$/;
	      function schedule() {
	        if (inProgress) {
	          if (document.hidden === false && window.requestAnimationFrame) {
	            window.requestAnimationFrame(schedule);
	          } else {
	            window.setTimeout(schedule, jQuery.fx.interval);
	          }
	          jQuery.fx.tick();
	        }
	      }

	      // Animations created synchronously will run synchronously
	      function createFxNow() {
	        window.setTimeout(function () {
	          fxNow = undefined;
	        });
	        return fxNow = Date.now();
	      }

	      // Generate parameters to create a standard animation
	      function genFx(type, includeWidth) {
	        var which,
	          i = 0,
	          attrs = {
	            height: type
	          };

	        // If we include width, step value is 1 to do all cssExpand values,
	        // otherwise step value is 2 to skip over Left and Right
	        includeWidth = includeWidth ? 1 : 0;
	        for (; i < 4; i += 2 - includeWidth) {
	          which = cssExpand[i];
	          attrs["margin" + which] = attrs["padding" + which] = type;
	        }
	        if (includeWidth) {
	          attrs.opacity = attrs.width = type;
	        }
	        return attrs;
	      }
	      function createTween(value, prop, animation) {
	        var tween,
	          collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
	          index = 0,
	          length = collection.length;
	        for (; index < length; index++) {
	          if (tween = collection[index].call(animation, prop, value)) {
	            // We're done with this property
	            return tween;
	          }
	        }
	      }
	      function defaultPrefilter(elem, props, opts) {
	        var prop,
	          value,
	          toggle,
	          hooks,
	          oldfire,
	          propTween,
	          restoreDisplay,
	          display,
	          isBox = "width" in props || "height" in props,
	          anim = this,
	          orig = {},
	          style = elem.style,
	          hidden = elem.nodeType && isHiddenWithinTree(elem),
	          dataShow = dataPriv.get(elem, "fxshow");

	        // Queue-skipping animations hijack the fx hooks
	        if (!opts.queue) {
	          hooks = jQuery._queueHooks(elem, "fx");
	          if (hooks.unqueued == null) {
	            hooks.unqueued = 0;
	            oldfire = hooks.empty.fire;
	            hooks.empty.fire = function () {
	              if (!hooks.unqueued) {
	                oldfire();
	              }
	            };
	          }
	          hooks.unqueued++;
	          anim.always(function () {
	            // Ensure the complete handler is called before this completes
	            anim.always(function () {
	              hooks.unqueued--;
	              if (!jQuery.queue(elem, "fx").length) {
	                hooks.empty.fire();
	              }
	            });
	          });
	        }

	        // Detect show/hide animations
	        for (prop in props) {
	          value = props[prop];
	          if (rfxtypes.test(value)) {
	            delete props[prop];
	            toggle = toggle || value === "toggle";
	            if (value === (hidden ? "hide" : "show")) {
	              // Pretend to be hidden if this is a "show" and
	              // there is still data from a stopped show/hide
	              if (value === "show" && dataShow && dataShow[prop] !== undefined) {
	                hidden = true;

	                // Ignore all other no-op show/hide data
	              } else {
	                continue;
	              }
	            }
	            orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
	          }
	        }

	        // Bail out if this is a no-op like .hide().hide()
	        propTween = !jQuery.isEmptyObject(props);
	        if (!propTween && jQuery.isEmptyObject(orig)) {
	          return;
	        }

	        // Restrict "overflow" and "display" styles during box animations
	        if (isBox && elem.nodeType === 1) {
	          // Support: IE <=9 - 11, Edge 12 - 15
	          // Record all 3 overflow attributes because IE does not infer the shorthand
	          // from identically-valued overflowX and overflowY and Edge just mirrors
	          // the overflowX value there.
	          opts.overflow = [style.overflow, style.overflowX, style.overflowY];

	          // Identify a display type, preferring old show/hide data over the CSS cascade
	          restoreDisplay = dataShow && dataShow.display;
	          if (restoreDisplay == null) {
	            restoreDisplay = dataPriv.get(elem, "display");
	          }
	          display = jQuery.css(elem, "display");
	          if (display === "none") {
	            if (restoreDisplay) {
	              display = restoreDisplay;
	            } else {
	              // Get nonempty value(s) by temporarily forcing visibility
	              showHide([elem], true);
	              restoreDisplay = elem.style.display || restoreDisplay;
	              display = jQuery.css(elem, "display");
	              showHide([elem]);
	            }
	          }

	          // Animate inline elements as inline-block
	          if (display === "inline" || display === "inline-block" && restoreDisplay != null) {
	            if (jQuery.css(elem, "float") === "none") {
	              // Restore the original display value at the end of pure show/hide animations
	              if (!propTween) {
	                anim.done(function () {
	                  style.display = restoreDisplay;
	                });
	                if (restoreDisplay == null) {
	                  display = style.display;
	                  restoreDisplay = display === "none" ? "" : display;
	                }
	              }
	              style.display = "inline-block";
	            }
	          }
	        }
	        if (opts.overflow) {
	          style.overflow = "hidden";
	          anim.always(function () {
	            style.overflow = opts.overflow[0];
	            style.overflowX = opts.overflow[1];
	            style.overflowY = opts.overflow[2];
	          });
	        }

	        // Implement show/hide animations
	        propTween = false;
	        for (prop in orig) {
	          // General show/hide setup for this element animation
	          if (!propTween) {
	            if (dataShow) {
	              if ("hidden" in dataShow) {
	                hidden = dataShow.hidden;
	              }
	            } else {
	              dataShow = dataPriv.access(elem, "fxshow", {
	                display: restoreDisplay
	              });
	            }

	            // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
	            if (toggle) {
	              dataShow.hidden = !hidden;
	            }

	            // Show elements before animating them
	            if (hidden) {
	              showHide([elem], true);
	            }

	            /* eslint-disable no-loop-func */

	            anim.done(function () {
	              /* eslint-enable no-loop-func */

	              // The final step of a "hide" animation is actually hiding the element
	              if (!hidden) {
	                showHide([elem]);
	              }
	              dataPriv.remove(elem, "fxshow");
	              for (prop in orig) {
	                jQuery.style(elem, prop, orig[prop]);
	              }
	            });
	          }

	          // Per-property setup
	          propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
	          if (!(prop in dataShow)) {
	            dataShow[prop] = propTween.start;
	            if (hidden) {
	              propTween.end = propTween.start;
	              propTween.start = 0;
	            }
	          }
	        }
	      }
	      function propFilter(props, specialEasing) {
	        var index, name, easing, value, hooks;

	        // camelCase, specialEasing and expand cssHook pass
	        for (index in props) {
	          name = camelCase(index);
	          easing = specialEasing[name];
	          value = props[index];
	          if (Array.isArray(value)) {
	            easing = value[1];
	            value = props[index] = value[0];
	          }
	          if (index !== name) {
	            props[name] = value;
	            delete props[index];
	          }
	          hooks = jQuery.cssHooks[name];
	          if (hooks && "expand" in hooks) {
	            value = hooks.expand(value);
	            delete props[name];

	            // Not quite $.extend, this won't overwrite existing keys.
	            // Reusing 'index' because we have the correct "name"
	            for (index in value) {
	              if (!(index in props)) {
	                props[index] = value[index];
	                specialEasing[index] = easing;
	              }
	            }
	          } else {
	            specialEasing[name] = easing;
	          }
	        }
	      }
	      function Animation(elem, properties, options) {
	        var result,
	          stopped,
	          index = 0,
	          length = Animation.prefilters.length,
	          deferred = jQuery.Deferred().always(function () {
	            // Don't match elem in the :animated selector
	            delete tick.elem;
	          }),
	          tick = function () {
	            if (stopped) {
	              return false;
	            }
	            var currentTime = fxNow || createFxNow(),
	              remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
	              // Support: Android 2.3 only
	              // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
	              temp = remaining / animation.duration || 0,
	              percent = 1 - temp,
	              index = 0,
	              length = animation.tweens.length;
	            for (; index < length; index++) {
	              animation.tweens[index].run(percent);
	            }
	            deferred.notifyWith(elem, [animation, percent, remaining]);

	            // If there's more to do, yield
	            if (percent < 1 && length) {
	              return remaining;
	            }

	            // If this was an empty animation, synthesize a final progress notification
	            if (!length) {
	              deferred.notifyWith(elem, [animation, 1, 0]);
	            }

	            // Resolve the animation and report its conclusion
	            deferred.resolveWith(elem, [animation]);
	            return false;
	          },
	          animation = deferred.promise({
	            elem: elem,
	            props: jQuery.extend({}, properties),
	            opts: jQuery.extend(true, {
	              specialEasing: {},
	              easing: jQuery.easing._default
	            }, options),
	            originalProperties: properties,
	            originalOptions: options,
	            startTime: fxNow || createFxNow(),
	            duration: options.duration,
	            tweens: [],
	            createTween: function (prop, end) {
	              var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);
	              animation.tweens.push(tween);
	              return tween;
	            },
	            stop: function (gotoEnd) {
	              var index = 0,
	                // If we are going to the end, we want to run all the tweens
	                // otherwise we skip this part
	                length = gotoEnd ? animation.tweens.length : 0;
	              if (stopped) {
	                return this;
	              }
	              stopped = true;
	              for (; index < length; index++) {
	                animation.tweens[index].run(1);
	              }

	              // Resolve when we played the last frame; otherwise, reject
	              if (gotoEnd) {
	                deferred.notifyWith(elem, [animation, 1, 0]);
	                deferred.resolveWith(elem, [animation, gotoEnd]);
	              } else {
	                deferred.rejectWith(elem, [animation, gotoEnd]);
	              }
	              return this;
	            }
	          }),
	          props = animation.props;
	        propFilter(props, animation.opts.specialEasing);
	        for (; index < length; index++) {
	          result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
	          if (result) {
	            if (isFunction(result.stop)) {
	              jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result);
	            }
	            return result;
	          }
	        }
	        jQuery.map(props, createTween, animation);
	        if (isFunction(animation.opts.start)) {
	          animation.opts.start.call(elem, animation);
	        }

	        // Attach callbacks from options
	        animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);
	        jQuery.fx.timer(jQuery.extend(tick, {
	          elem: elem,
	          anim: animation,
	          queue: animation.opts.queue
	        }));
	        return animation;
	      }
	      jQuery.Animation = jQuery.extend(Animation, {
	        tweeners: {
	          "*": [function (prop, value) {
	            var tween = this.createTween(prop, value);
	            adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
	            return tween;
	          }]
	        },
	        tweener: function (props, callback) {
	          if (isFunction(props)) {
	            callback = props;
	            props = ["*"];
	          } else {
	            props = props.match(rnothtmlwhite);
	          }
	          var prop,
	            index = 0,
	            length = props.length;
	          for (; index < length; index++) {
	            prop = props[index];
	            Animation.tweeners[prop] = Animation.tweeners[prop] || [];
	            Animation.tweeners[prop].unshift(callback);
	          }
	        },
	        prefilters: [defaultPrefilter],
	        prefilter: function (callback, prepend) {
	          if (prepend) {
	            Animation.prefilters.unshift(callback);
	          } else {
	            Animation.prefilters.push(callback);
	          }
	        }
	      });
	      jQuery.speed = function (speed, easing, fn) {
	        var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
	          complete: fn || !fn && easing || isFunction(speed) && speed,
	          duration: speed,
	          easing: fn && easing || easing && !isFunction(easing) && easing
	        };

	        // Go to the end state if fx are off
	        if (jQuery.fx.off) {
	          opt.duration = 0;
	        } else {
	          if (typeof opt.duration !== "number") {
	            if (opt.duration in jQuery.fx.speeds) {
	              opt.duration = jQuery.fx.speeds[opt.duration];
	            } else {
	              opt.duration = jQuery.fx.speeds._default;
	            }
	          }
	        }

	        // Normalize opt.queue - true/undefined/null -> "fx"
	        if (opt.queue == null || opt.queue === true) {
	          opt.queue = "fx";
	        }

	        // Queueing
	        opt.old = opt.complete;
	        opt.complete = function () {
	          if (isFunction(opt.old)) {
	            opt.old.call(this);
	          }
	          if (opt.queue) {
	            jQuery.dequeue(this, opt.queue);
	          }
	        };
	        return opt;
	      };
	      jQuery.fn.extend({
	        fadeTo: function (speed, to, easing, callback) {
	          // Show any hidden elements after setting opacity to 0
	          return this.filter(isHiddenWithinTree).css("opacity", 0).show()

	          // Animate to the value specified
	          .end().animate({
	            opacity: to
	          }, speed, easing, callback);
	        },
	        animate: function (prop, speed, easing, callback) {
	          var empty = jQuery.isEmptyObject(prop),
	            optall = jQuery.speed(speed, easing, callback),
	            doAnimation = function () {
	              // Operate on a copy of prop so per-property easing won't be lost
	              var anim = Animation(this, jQuery.extend({}, prop), optall);

	              // Empty animations, or finishing resolves immediately
	              if (empty || dataPriv.get(this, "finish")) {
	                anim.stop(true);
	              }
	            };
	          doAnimation.finish = doAnimation;
	          return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation);
	        },
	        stop: function (type, clearQueue, gotoEnd) {
	          var stopQueue = function (hooks) {
	            var stop = hooks.stop;
	            delete hooks.stop;
	            stop(gotoEnd);
	          };
	          if (typeof type !== "string") {
	            gotoEnd = clearQueue;
	            clearQueue = type;
	            type = undefined;
	          }
	          if (clearQueue) {
	            this.queue(type || "fx", []);
	          }
	          return this.each(function () {
	            var dequeue = true,
	              index = type != null && type + "queueHooks",
	              timers = jQuery.timers,
	              data = dataPriv.get(this);
	            if (index) {
	              if (data[index] && data[index].stop) {
	                stopQueue(data[index]);
	              }
	            } else {
	              for (index in data) {
	                if (data[index] && data[index].stop && rrun.test(index)) {
	                  stopQueue(data[index]);
	                }
	              }
	            }
	            for (index = timers.length; index--;) {
	              if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
	                timers[index].anim.stop(gotoEnd);
	                dequeue = false;
	                timers.splice(index, 1);
	              }
	            }

	            // Start the next in the queue if the last step wasn't forced.
	            // Timers currently will call their complete callbacks, which
	            // will dequeue but only if they were gotoEnd.
	            if (dequeue || !gotoEnd) {
	              jQuery.dequeue(this, type);
	            }
	          });
	        },
	        finish: function (type) {
	          if (type !== false) {
	            type = type || "fx";
	          }
	          return this.each(function () {
	            var index,
	              data = dataPriv.get(this),
	              queue = data[type + "queue"],
	              hooks = data[type + "queueHooks"],
	              timers = jQuery.timers,
	              length = queue ? queue.length : 0;

	            // Enable finishing flag on private data
	            data.finish = true;

	            // Empty the queue first
	            jQuery.queue(this, type, []);
	            if (hooks && hooks.stop) {
	              hooks.stop.call(this, true);
	            }

	            // Look for any active animations, and finish them
	            for (index = timers.length; index--;) {
	              if (timers[index].elem === this && timers[index].queue === type) {
	                timers[index].anim.stop(true);
	                timers.splice(index, 1);
	              }
	            }

	            // Look for any animations in the old queue and finish them
	            for (index = 0; index < length; index++) {
	              if (queue[index] && queue[index].finish) {
	                queue[index].finish.call(this);
	              }
	            }

	            // Turn off finishing flag
	            delete data.finish;
	          });
	        }
	      });
	      jQuery.each(["toggle", "show", "hide"], function (_i, name) {
	        var cssFn = jQuery.fn[name];
	        jQuery.fn[name] = function (speed, easing, callback) {
	          return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback);
	        };
	      });

	      // Generate shortcuts for custom animations
	      jQuery.each({
	        slideDown: genFx("show"),
	        slideUp: genFx("hide"),
	        slideToggle: genFx("toggle"),
	        fadeIn: {
	          opacity: "show"
	        },
	        fadeOut: {
	          opacity: "hide"
	        },
	        fadeToggle: {
	          opacity: "toggle"
	        }
	      }, function (name, props) {
	        jQuery.fn[name] = function (speed, easing, callback) {
	          return this.animate(props, speed, easing, callback);
	        };
	      });
	      jQuery.timers = [];
	      jQuery.fx.tick = function () {
	        var timer,
	          i = 0,
	          timers = jQuery.timers;
	        fxNow = Date.now();
	        for (; i < timers.length; i++) {
	          timer = timers[i];

	          // Run the timer and safely remove it when done (allowing for external removal)
	          if (!timer() && timers[i] === timer) {
	            timers.splice(i--, 1);
	          }
	        }
	        if (!timers.length) {
	          jQuery.fx.stop();
	        }
	        fxNow = undefined;
	      };
	      jQuery.fx.timer = function (timer) {
	        jQuery.timers.push(timer);
	        jQuery.fx.start();
	      };
	      jQuery.fx.interval = 13;
	      jQuery.fx.start = function () {
	        if (inProgress) {
	          return;
	        }
	        inProgress = true;
	        schedule();
	      };
	      jQuery.fx.stop = function () {
	        inProgress = null;
	      };
	      jQuery.fx.speeds = {
	        slow: 600,
	        fast: 200,
	        // Default speed
	        _default: 400
	      };

	      // Based off of the plugin by Clint Helfers, with permission.
	      jQuery.fn.delay = function (time, type) {
	        time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
	        type = type || "fx";
	        return this.queue(type, function (next, hooks) {
	          var timeout = window.setTimeout(next, time);
	          hooks.stop = function () {
	            window.clearTimeout(timeout);
	          };
	        });
	      };
	      (function () {
	        var input = document.createElement("input"),
	          select = document.createElement("select"),
	          opt = select.appendChild(document.createElement("option"));
	        input.type = "checkbox";

	        // Support: Android <=4.3 only
	        // Default value for a checkbox should be "on"
	        support.checkOn = input.value !== "";

	        // Support: IE <=11 only
	        // Must access selectedIndex to make default options select
	        support.optSelected = opt.selected;

	        // Support: IE <=11 only
	        // An input loses its value after becoming a radio
	        input = document.createElement("input");
	        input.value = "t";
	        input.type = "radio";
	        support.radioValue = input.value === "t";
	      })();
	      var boolHook,
	        attrHandle = jQuery.expr.attrHandle;
	      jQuery.fn.extend({
	        attr: function (name, value) {
	          return access(this, jQuery.attr, name, value, arguments.length > 1);
	        },
	        removeAttr: function (name) {
	          return this.each(function () {
	            jQuery.removeAttr(this, name);
	          });
	        }
	      });
	      jQuery.extend({
	        attr: function (elem, name, value) {
	          var ret,
	            hooks,
	            nType = elem.nodeType;

	          // Don't get/set attributes on text, comment and attribute nodes
	          if (nType === 3 || nType === 8 || nType === 2) {
	            return;
	          }

	          // Fallback to prop when attributes are not supported
	          if (typeof elem.getAttribute === "undefined") {
	            return jQuery.prop(elem, name, value);
	          }

	          // Attribute hooks are determined by the lowercase version
	          // Grab necessary hook if one is defined
	          if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
	            hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined);
	          }
	          if (value !== undefined) {
	            if (value === null) {
	              jQuery.removeAttr(elem, name);
	              return;
	            }
	            if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
	              return ret;
	            }
	            elem.setAttribute(name, value + "");
	            return value;
	          }
	          if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
	            return ret;
	          }
	          ret = jQuery.find.attr(elem, name);

	          // Non-existent attributes return null, we normalize to undefined
	          return ret == null ? undefined : ret;
	        },
	        attrHooks: {
	          type: {
	            set: function (elem, value) {
	              if (!support.radioValue && value === "radio" && nodeName(elem, "input")) {
	                var val = elem.value;
	                elem.setAttribute("type", value);
	                if (val) {
	                  elem.value = val;
	                }
	                return value;
	              }
	            }
	          }
	        },
	        removeAttr: function (elem, value) {
	          var name,
	            i = 0,
	            // Attribute names can contain non-HTML whitespace characters
	            // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
	            attrNames = value && value.match(rnothtmlwhite);
	          if (attrNames && elem.nodeType === 1) {
	            while (name = attrNames[i++]) {
	              elem.removeAttribute(name);
	            }
	          }
	        }
	      });

	      // Hooks for boolean attributes
	      boolHook = {
	        set: function (elem, value, name) {
	          if (value === false) {
	            // Remove boolean attributes when set to false
	            jQuery.removeAttr(elem, name);
	          } else {
	            elem.setAttribute(name, name);
	          }
	          return name;
	        }
	      };
	      jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (_i, name) {
	        var getter = attrHandle[name] || jQuery.find.attr;
	        attrHandle[name] = function (elem, name, isXML) {
	          var ret,
	            handle,
	            lowercaseName = name.toLowerCase();
	          if (!isXML) {
	            // Avoid an infinite loop by temporarily removing this function from the getter
	            handle = attrHandle[lowercaseName];
	            attrHandle[lowercaseName] = ret;
	            ret = getter(elem, name, isXML) != null ? lowercaseName : null;
	            attrHandle[lowercaseName] = handle;
	          }
	          return ret;
	        };
	      });
	      var rfocusable = /^(?:input|select|textarea|button)$/i,
	        rclickable = /^(?:a|area)$/i;
	      jQuery.fn.extend({
	        prop: function (name, value) {
	          return access(this, jQuery.prop, name, value, arguments.length > 1);
	        },
	        removeProp: function (name) {
	          return this.each(function () {
	            delete this[jQuery.propFix[name] || name];
	          });
	        }
	      });
	      jQuery.extend({
	        prop: function (elem, name, value) {
	          var ret,
	            hooks,
	            nType = elem.nodeType;

	          // Don't get/set properties on text, comment and attribute nodes
	          if (nType === 3 || nType === 8 || nType === 2) {
	            return;
	          }
	          if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
	            // Fix name and attach hooks
	            name = jQuery.propFix[name] || name;
	            hooks = jQuery.propHooks[name];
	          }
	          if (value !== undefined) {
	            if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
	              return ret;
	            }
	            return elem[name] = value;
	          }
	          if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
	            return ret;
	          }
	          return elem[name];
	        },
	        propHooks: {
	          tabIndex: {
	            get: function (elem) {
	              // Support: IE <=9 - 11 only
	              // elem.tabIndex doesn't always return the
	              // correct value when it hasn't been explicitly set
	              // Use proper attribute retrieval (trac-12072)
	              var tabindex = jQuery.find.attr(elem, "tabindex");
	              if (tabindex) {
	                return parseInt(tabindex, 10);
	              }
	              if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) {
	                return 0;
	              }
	              return -1;
	            }
	          }
	        },
	        propFix: {
	          "for": "htmlFor",
	          "class": "className"
	        }
	      });

	      // Support: IE <=11 only
	      // Accessing the selectedIndex property
	      // forces the browser to respect setting selected
	      // on the option
	      // The getter ensures a default option is selected
	      // when in an optgroup
	      // eslint rule "no-unused-expressions" is disabled for this code
	      // since it considers such accessions noop
	      if (!support.optSelected) {
	        jQuery.propHooks.selected = {
	          get: function (elem) {
	            /* eslint no-unused-expressions: "off" */

	            var parent = elem.parentNode;
	            if (parent && parent.parentNode) {
	              parent.parentNode.selectedIndex;
	            }
	            return null;
	          },
	          set: function (elem) {
	            /* eslint no-unused-expressions: "off" */

	            var parent = elem.parentNode;
	            if (parent) {
	              parent.selectedIndex;
	              if (parent.parentNode) {
	                parent.parentNode.selectedIndex;
	              }
	            }
	          }
	        };
	      }
	      jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
	        jQuery.propFix[this.toLowerCase()] = this;
	      });

	      // Strip and collapse whitespace according to HTML spec
	      // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
	      function stripAndCollapse(value) {
	        var tokens = value.match(rnothtmlwhite) || [];
	        return tokens.join(" ");
	      }
	      function getClass(elem) {
	        return elem.getAttribute && elem.getAttribute("class") || "";
	      }
	      function classesToArray(value) {
	        if (Array.isArray(value)) {
	          return value;
	        }
	        if (typeof value === "string") {
	          return value.match(rnothtmlwhite) || [];
	        }
	        return [];
	      }
	      jQuery.fn.extend({
	        addClass: function (value) {
	          var classNames, cur, curValue, className, i, finalValue;
	          if (isFunction(value)) {
	            return this.each(function (j) {
	              jQuery(this).addClass(value.call(this, j, getClass(this)));
	            });
	          }
	          classNames = classesToArray(value);
	          if (classNames.length) {
	            return this.each(function () {
	              curValue = getClass(this);
	              cur = this.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
	              if (cur) {
	                for (i = 0; i < classNames.length; i++) {
	                  className = classNames[i];
	                  if (cur.indexOf(" " + className + " ") < 0) {
	                    cur += className + " ";
	                  }
	                }

	                // Only assign if different to avoid unneeded rendering.
	                finalValue = stripAndCollapse(cur);
	                if (curValue !== finalValue) {
	                  this.setAttribute("class", finalValue);
	                }
	              }
	            });
	          }
	          return this;
	        },
	        removeClass: function (value) {
	          var classNames, cur, curValue, className, i, finalValue;
	          if (isFunction(value)) {
	            return this.each(function (j) {
	              jQuery(this).removeClass(value.call(this, j, getClass(this)));
	            });
	          }
	          if (!arguments.length) {
	            return this.attr("class", "");
	          }
	          classNames = classesToArray(value);
	          if (classNames.length) {
	            return this.each(function () {
	              curValue = getClass(this);

	              // This expression is here for better compressibility (see addClass)
	              cur = this.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
	              if (cur) {
	                for (i = 0; i < classNames.length; i++) {
	                  className = classNames[i];

	                  // Remove *all* instances
	                  while (cur.indexOf(" " + className + " ") > -1) {
	                    cur = cur.replace(" " + className + " ", " ");
	                  }
	                }

	                // Only assign if different to avoid unneeded rendering.
	                finalValue = stripAndCollapse(cur);
	                if (curValue !== finalValue) {
	                  this.setAttribute("class", finalValue);
	                }
	              }
	            });
	          }
	          return this;
	        },
	        toggleClass: function (value, stateVal) {
	          var classNames,
	            className,
	            i,
	            self,
	            type = typeof value,
	            isValidValue = type === "string" || Array.isArray(value);
	          if (isFunction(value)) {
	            return this.each(function (i) {
	              jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal);
	            });
	          }
	          if (typeof stateVal === "boolean" && isValidValue) {
	            return stateVal ? this.addClass(value) : this.removeClass(value);
	          }
	          classNames = classesToArray(value);
	          return this.each(function () {
	            if (isValidValue) {
	              // Toggle individual class names
	              self = jQuery(this);
	              for (i = 0; i < classNames.length; i++) {
	                className = classNames[i];

	                // Check each className given, space separated list
	                if (self.hasClass(className)) {
	                  self.removeClass(className);
	                } else {
	                  self.addClass(className);
	                }
	              }

	              // Toggle whole class name
	            } else if (value === undefined || type === "boolean") {
	              className = getClass(this);
	              if (className) {
	                // Store className if set
	                dataPriv.set(this, "__className__", className);
	              }

	              // If the element has a class name or if we're passed `false`,
	              // then remove the whole classname (if there was one, the above saved it).
	              // Otherwise bring back whatever was previously saved (if anything),
	              // falling back to the empty string if nothing was stored.
	              if (this.setAttribute) {
	                this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || "");
	              }
	            }
	          });
	        },
	        hasClass: function (selector) {
	          var className,
	            elem,
	            i = 0;
	          className = " " + selector + " ";
	          while (elem = this[i++]) {
	            if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {
	              return true;
	            }
	          }
	          return false;
	        }
	      });
	      var rreturn = /\r/g;
	      jQuery.fn.extend({
	        val: function (value) {
	          var hooks,
	            ret,
	            valueIsFunction,
	            elem = this[0];
	          if (!arguments.length) {
	            if (elem) {
	              hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
	              if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
	                return ret;
	              }
	              ret = elem.value;

	              // Handle most common string cases
	              if (typeof ret === "string") {
	                return ret.replace(rreturn, "");
	              }

	              // Handle cases where value is null/undef or number
	              return ret == null ? "" : ret;
	            }
	            return;
	          }
	          valueIsFunction = isFunction(value);
	          return this.each(function (i) {
	            var val;
	            if (this.nodeType !== 1) {
	              return;
	            }
	            if (valueIsFunction) {
	              val = value.call(this, i, jQuery(this).val());
	            } else {
	              val = value;
	            }

	            // Treat null/undefined as ""; convert numbers to string
	            if (val == null) {
	              val = "";
	            } else if (typeof val === "number") {
	              val += "";
	            } else if (Array.isArray(val)) {
	              val = jQuery.map(val, function (value) {
	                return value == null ? "" : value + "";
	              });
	            }
	            hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];

	            // If set returns undefined, fall back to normal setting
	            if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
	              this.value = val;
	            }
	          });
	        }
	      });
	      jQuery.extend({
	        valHooks: {
	          option: {
	            get: function (elem) {
	              var val = jQuery.find.attr(elem, "value");
	              return val != null ? val :
	              // Support: IE <=10 - 11 only
	              // option.text throws exceptions (trac-14686, trac-14858)
	              // Strip and collapse whitespace
	              // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
	              stripAndCollapse(jQuery.text(elem));
	            }
	          },
	          select: {
	            get: function (elem) {
	              var value,
	                option,
	                i,
	                options = elem.options,
	                index = elem.selectedIndex,
	                one = elem.type === "select-one",
	                values = one ? null : [],
	                max = one ? index + 1 : options.length;
	              if (index < 0) {
	                i = max;
	              } else {
	                i = one ? index : 0;
	              }

	              // Loop through all the selected options
	              for (; i < max; i++) {
	                option = options[i];

	                // Support: IE <=9 only
	                // IE8-9 doesn't update selected after form reset (trac-2551)
	                if ((option.selected || i === index) &&
	                // Don't return options that are disabled or in a disabled optgroup
	                !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) {
	                  // Get the specific value for the option
	                  value = jQuery(option).val();

	                  // We don't need an array for one selects
	                  if (one) {
	                    return value;
	                  }

	                  // Multi-Selects return an array
	                  values.push(value);
	                }
	              }
	              return values;
	            },
	            set: function (elem, value) {
	              var optionSet,
	                option,
	                options = elem.options,
	                values = jQuery.makeArray(value),
	                i = options.length;
	              while (i--) {
	                option = options[i];

	                /* eslint-disable no-cond-assign */

	                if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) {
	                  optionSet = true;
	                }

	                /* eslint-enable no-cond-assign */
	              }

	              // Force browsers to behave consistently when non-matching value is set
	              if (!optionSet) {
	                elem.selectedIndex = -1;
	              }
	              return values;
	            }
	          }
	        }
	      });

	      // Radios and checkboxes getter/setter
	      jQuery.each(["radio", "checkbox"], function () {
	        jQuery.valHooks[this] = {
	          set: function (elem, value) {
	            if (Array.isArray(value)) {
	              return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1;
	            }
	          }
	        };
	        if (!support.checkOn) {
	          jQuery.valHooks[this].get = function (elem) {
	            return elem.getAttribute("value") === null ? "on" : elem.value;
	          };
	        }
	      });

	      // Return jQuery for attributes-only inclusion
	      var location = window.location;
	      var nonce = {
	        guid: Date.now()
	      };
	      var rquery = /\?/;

	      // Cross-browser xml parsing
	      jQuery.parseXML = function (data) {
	        var xml, parserErrorElem;
	        if (!data || typeof data !== "string") {
	          return null;
	        }

	        // Support: IE 9 - 11 only
	        // IE throws on parseFromString with invalid input.
	        try {
	          xml = new window.DOMParser().parseFromString(data, "text/xml");
	        } catch (e) {}
	        parserErrorElem = xml && xml.getElementsByTagName("parsererror")[0];
	        if (!xml || parserErrorElem) {
	          jQuery.error("Invalid XML: " + (parserErrorElem ? jQuery.map(parserErrorElem.childNodes, function (el) {
	            return el.textContent;
	          }).join("\n") : data));
	        }
	        return xml;
	      };
	      var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
	        stopPropagationCallback = function (e) {
	          e.stopPropagation();
	        };
	      jQuery.extend(jQuery.event, {
	        trigger: function (event, data, elem, onlyHandlers) {
	          var i,
	            cur,
	            tmp,
	            bubbleType,
	            ontype,
	            handle,
	            special,
	            lastElement,
	            eventPath = [elem || document],
	            type = hasOwn.call(event, "type") ? event.type : event,
	            namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
	          cur = lastElement = tmp = elem = elem || document;

	          // Don't do events on text and comment nodes
	          if (elem.nodeType === 3 || elem.nodeType === 8) {
	            return;
	          }

	          // focus/blur morphs to focusin/out; ensure we're not firing them right now
	          if (rfocusMorph.test(type + jQuery.event.triggered)) {
	            return;
	          }
	          if (type.indexOf(".") > -1) {
	            // Namespaced trigger; create a regexp to match event type in handle()
	            namespaces = type.split(".");
	            type = namespaces.shift();
	            namespaces.sort();
	          }
	          ontype = type.indexOf(":") < 0 && "on" + type;

	          // Caller can pass in a jQuery.Event object, Object, or just an event type string
	          event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event);

	          // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
	          event.isTrigger = onlyHandlers ? 2 : 3;
	          event.namespace = namespaces.join(".");
	          event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;

	          // Clean up the event in case it is being reused
	          event.result = undefined;
	          if (!event.target) {
	            event.target = elem;
	          }

	          // Clone any incoming data and prepend the event, creating the handler arg list
	          data = data == null ? [event] : jQuery.makeArray(data, [event]);

	          // Allow special events to draw outside the lines
	          special = jQuery.event.special[type] || {};
	          if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
	            return;
	          }

	          // Determine event propagation path in advance, per W3C events spec (trac-9951)
	          // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
	          if (!onlyHandlers && !special.noBubble && !isWindow(elem)) {
	            bubbleType = special.delegateType || type;
	            if (!rfocusMorph.test(bubbleType + type)) {
	              cur = cur.parentNode;
	            }
	            for (; cur; cur = cur.parentNode) {
	              eventPath.push(cur);
	              tmp = cur;
	            }

	            // Only add window if we got to document (e.g., not plain obj or detached DOM)
	            if (tmp === (elem.ownerDocument || document)) {
	              eventPath.push(tmp.defaultView || tmp.parentWindow || window);
	            }
	          }

	          // Fire handlers on the event path
	          i = 0;
	          while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
	            lastElement = cur;
	            event.type = i > 1 ? bubbleType : special.bindType || type;

	            // jQuery handler
	            handle = (dataPriv.get(cur, "events") || Object.create(null))[event.type] && dataPriv.get(cur, "handle");
	            if (handle) {
	              handle.apply(cur, data);
	            }

	            // Native handler
	            handle = ontype && cur[ontype];
	            if (handle && handle.apply && acceptData(cur)) {
	              event.result = handle.apply(cur, data);
	              if (event.result === false) {
	                event.preventDefault();
	              }
	            }
	          }
	          event.type = type;

	          // If nobody prevented the default action, do it now
	          if (!onlyHandlers && !event.isDefaultPrevented()) {
	            if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) {
	              // Call a native DOM method on the target with the same name as the event.
	              // Don't do default actions on window, that's where global variables be (trac-6170)
	              if (ontype && isFunction(elem[type]) && !isWindow(elem)) {
	                // Don't re-trigger an onFOO event when we call its FOO() method
	                tmp = elem[ontype];
	                if (tmp) {
	                  elem[ontype] = null;
	                }

	                // Prevent re-triggering of the same event, since we already bubbled it above
	                jQuery.event.triggered = type;
	                if (event.isPropagationStopped()) {
	                  lastElement.addEventListener(type, stopPropagationCallback);
	                }
	                elem[type]();
	                if (event.isPropagationStopped()) {
	                  lastElement.removeEventListener(type, stopPropagationCallback);
	                }
	                jQuery.event.triggered = undefined;
	                if (tmp) {
	                  elem[ontype] = tmp;
	                }
	              }
	            }
	          }
	          return event.result;
	        },
	        // Piggyback on a donor event to simulate a different one
	        // Used only for `focus(in | out)` events
	        simulate: function (type, elem, event) {
	          var e = jQuery.extend(new jQuery.Event(), event, {
	            type: type,
	            isSimulated: true
	          });
	          jQuery.event.trigger(e, null, elem);
	        }
	      });
	      jQuery.fn.extend({
	        trigger: function (type, data) {
	          return this.each(function () {
	            jQuery.event.trigger(type, data, this);
	          });
	        },
	        triggerHandler: function (type, data) {
	          var elem = this[0];
	          if (elem) {
	            return jQuery.event.trigger(type, data, elem, true);
	          }
	        }
	      });
	      var rbracket = /\[\]$/,
	        rCRLF = /\r?\n/g,
	        rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
	        rsubmittable = /^(?:input|select|textarea|keygen)/i;
	      function buildParams(prefix, obj, traditional, add) {
	        var name;
	        if (Array.isArray(obj)) {
	          // Serialize array item.
	          jQuery.each(obj, function (i, v) {
	            if (traditional || rbracket.test(prefix)) {
	              // Treat each array item as a scalar.
	              add(prefix, v);
	            } else {
	              // Item is non-scalar (array or object), encode its numeric index.
	              buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, traditional, add);
	            }
	          });
	        } else if (!traditional && toType(obj) === "object") {
	          // Serialize object item.
	          for (name in obj) {
	            buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
	          }
	        } else {
	          // Serialize scalar item.
	          add(prefix, obj);
	        }
	      }

	      // Serialize an array of form elements or a set of
	      // key/values into a query string
	      jQuery.param = function (a, traditional) {
	        var prefix,
	          s = [],
	          add = function (key, valueOrFunction) {
	            // If value is a function, invoke it and use its return value
	            var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;
	            s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value);
	          };
	        if (a == null) {
	          return "";
	        }

	        // If an array was passed in, assume that it is an array of form elements.
	        if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
	          // Serialize the form elements
	          jQuery.each(a, function () {
	            add(this.name, this.value);
	          });
	        } else {
	          // If traditional, encode the "old" way (the way 1.3.2 or older
	          // did it), otherwise encode params recursively.
	          for (prefix in a) {
	            buildParams(prefix, a[prefix], traditional, add);
	          }
	        }

	        // Return the resulting serialization
	        return s.join("&");
	      };
	      jQuery.fn.extend({
	        serialize: function () {
	          return jQuery.param(this.serializeArray());
	        },
	        serializeArray: function () {
	          return this.map(function () {
	            // Can add propHook for "elements" to filter or add form elements
	            var elements = jQuery.prop(this, "elements");
	            return elements ? jQuery.makeArray(elements) : this;
	          }).filter(function () {
	            var type = this.type;

	            // Use .is( ":disabled" ) so that fieldset[disabled] works
	            return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));
	          }).map(function (_i, elem) {
	            var val = jQuery(this).val();
	            if (val == null) {
	              return null;
	            }
	            if (Array.isArray(val)) {
	              return jQuery.map(val, function (val) {
	                return {
	                  name: elem.name,
	                  value: val.replace(rCRLF, "\r\n")
	                };
	              });
	            }
	            return {
	              name: elem.name,
	              value: val.replace(rCRLF, "\r\n")
	            };
	          }).get();
	        }
	      });
	      var r20 = /%20/g,
	        rhash = /#.*$/,
	        rantiCache = /([?&])_=[^&]*/,
	        rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
	        // trac-7653, trac-8125, trac-8152: local protocol detection
	        rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
	        rnoContent = /^(?:GET|HEAD)$/,
	        rprotocol = /^\/\//,
	        /* Prefilters
	         * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
	         * 2) These are called:
	         *    - BEFORE asking for a transport
	         *    - AFTER param serialization (s.data is a string if s.processData is true)
	         * 3) key is the dataType
	         * 4) the catchall symbol "*" can be used
	         * 5) execution will start with transport dataType and THEN continue down to "*" if needed
	         */
	        prefilters = {},
	        /* Transports bindings
	         * 1) key is the dataType
	         * 2) the catchall symbol "*" can be used
	         * 3) selection will start with transport dataType and THEN go to "*" if needed
	         */
	        transports = {},
	        // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
	        allTypes = "*/".concat("*"),
	        // Anchor tag for parsing the document origin
	        originAnchor = document.createElement("a");
	      originAnchor.href = location.href;

	      // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	      function addToPrefiltersOrTransports(structure) {
	        // dataTypeExpression is optional and defaults to "*"
	        return function (dataTypeExpression, func) {
	          if (typeof dataTypeExpression !== "string") {
	            func = dataTypeExpression;
	            dataTypeExpression = "*";
	          }
	          var dataType,
	            i = 0,
	            dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];
	          if (isFunction(func)) {
	            // For each dataType in the dataTypeExpression
	            while (dataType = dataTypes[i++]) {
	              // Prepend if requested
	              if (dataType[0] === "+") {
	                dataType = dataType.slice(1) || "*";
	                (structure[dataType] = structure[dataType] || []).unshift(func);

	                // Otherwise append
	              } else {
	                (structure[dataType] = structure[dataType] || []).push(func);
	              }
	            }
	          }
	        };
	      }

	      // Base inspection function for prefilters and transports
	      function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
	        var inspected = {},
	          seekingTransport = structure === transports;
	        function inspect(dataType) {
	          var selected;
	          inspected[dataType] = true;
	          jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
	            var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
	            if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
	              options.dataTypes.unshift(dataTypeOrTransport);
	              inspect(dataTypeOrTransport);
	              return false;
	            } else if (seekingTransport) {
	              return !(selected = dataTypeOrTransport);
	            }
	          });
	          return selected;
	        }
	        return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
	      }

	      // A special extend for ajax options
	      // that takes "flat" options (not to be deep extended)
	      // Fixes trac-9887
	      function ajaxExtend(target, src) {
	        var key,
	          deep,
	          flatOptions = jQuery.ajaxSettings.flatOptions || {};
	        for (key in src) {
	          if (src[key] !== undefined) {
	            (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
	          }
	        }
	        if (deep) {
	          jQuery.extend(true, target, deep);
	        }
	        return target;
	      }

	      /* Handles responses to an ajax request:
	       * - finds the right dataType (mediates between content-type and expected dataType)
	       * - returns the corresponding response
	       */
	      function ajaxHandleResponses(s, jqXHR, responses) {
	        var ct,
	          type,
	          finalDataType,
	          firstDataType,
	          contents = s.contents,
	          dataTypes = s.dataTypes;

	        // Remove auto dataType and get content-type in the process
	        while (dataTypes[0] === "*") {
	          dataTypes.shift();
	          if (ct === undefined) {
	            ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
	          }
	        }

	        // Check if we're dealing with a known content-type
	        if (ct) {
	          for (type in contents) {
	            if (contents[type] && contents[type].test(ct)) {
	              dataTypes.unshift(type);
	              break;
	            }
	          }
	        }

	        // Check to see if we have a response for the expected dataType
	        if (dataTypes[0] in responses) {
	          finalDataType = dataTypes[0];
	        } else {
	          // Try convertible dataTypes
	          for (type in responses) {
	            if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
	              finalDataType = type;
	              break;
	            }
	            if (!firstDataType) {
	              firstDataType = type;
	            }
	          }

	          // Or just use first one
	          finalDataType = finalDataType || firstDataType;
	        }

	        // If we found a dataType
	        // We add the dataType to the list if needed
	        // and return the corresponding response
	        if (finalDataType) {
	          if (finalDataType !== dataTypes[0]) {
	            dataTypes.unshift(finalDataType);
	          }
	          return responses[finalDataType];
	        }
	      }

	      /* Chain conversions given the request and the original response
	       * Also sets the responseXXX fields on the jqXHR instance
	       */
	      function ajaxConvert(s, response, jqXHR, isSuccess) {
	        var conv2,
	          current,
	          conv,
	          tmp,
	          prev,
	          converters = {},
	          // Work with a copy of dataTypes in case we need to modify it for conversion
	          dataTypes = s.dataTypes.slice();

	        // Create converters map with lowercased keys
	        if (dataTypes[1]) {
	          for (conv in s.converters) {
	            converters[conv.toLowerCase()] = s.converters[conv];
	          }
	        }
	        current = dataTypes.shift();

	        // Convert to each sequential dataType
	        while (current) {
	          if (s.responseFields[current]) {
	            jqXHR[s.responseFields[current]] = response;
	          }

	          // Apply the dataFilter if provided
	          if (!prev && isSuccess && s.dataFilter) {
	            response = s.dataFilter(response, s.dataType);
	          }
	          prev = current;
	          current = dataTypes.shift();
	          if (current) {
	            // There's only work to do if current dataType is non-auto
	            if (current === "*") {
	              current = prev;

	              // Convert response if prev dataType is non-auto and differs from current
	            } else if (prev !== "*" && prev !== current) {
	              // Seek a direct converter
	              conv = converters[prev + " " + current] || converters["* " + current];

	              // If none found, seek a pair
	              if (!conv) {
	                for (conv2 in converters) {
	                  // If conv2 outputs current
	                  tmp = conv2.split(" ");
	                  if (tmp[1] === current) {
	                    // If prev can be converted to accepted input
	                    conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
	                    if (conv) {
	                      // Condense equivalence converters
	                      if (conv === true) {
	                        conv = converters[conv2];

	                        // Otherwise, insert the intermediate dataType
	                      } else if (converters[conv2] !== true) {
	                        current = tmp[0];
	                        dataTypes.unshift(tmp[1]);
	                      }
	                      break;
	                    }
	                  }
	                }
	              }

	              // Apply converter (if not an equivalence)
	              if (conv !== true) {
	                // Unless errors are allowed to bubble, catch and return them
	                if (conv && s.throws) {
	                  response = conv(response);
	                } else {
	                  try {
	                    response = conv(response);
	                  } catch (e) {
	                    return {
	                      state: "parsererror",
	                      error: conv ? e : "No conversion from " + prev + " to " + current
	                    };
	                  }
	                }
	              }
	            }
	          }
	        }
	        return {
	          state: "success",
	          data: response
	        };
	      }
	      jQuery.extend({
	        // Counter for holding the number of active queries
	        active: 0,
	        // Last-Modified header cache for next request
	        lastModified: {},
	        etag: {},
	        ajaxSettings: {
	          url: location.href,
	          type: "GET",
	          isLocal: rlocalProtocol.test(location.protocol),
	          global: true,
	          processData: true,
	          async: true,
	          contentType: "application/x-www-form-urlencoded; charset=UTF-8",
	          /*
	          timeout: 0,
	          data: null,
	          dataType: null,
	          username: null,
	          password: null,
	          cache: null,
	          throws: false,
	          traditional: false,
	          headers: {},
	          */

	          accepts: {
	            "*": allTypes,
	            text: "text/plain",
	            html: "text/html",
	            xml: "application/xml, text/xml",
	            json: "application/json, text/javascript"
	          },
	          contents: {
	            xml: /\bxml\b/,
	            html: /\bhtml/,
	            json: /\bjson\b/
	          },
	          responseFields: {
	            xml: "responseXML",
	            text: "responseText",
	            json: "responseJSON"
	          },
	          // Data converters
	          // Keys separate source (or catchall "*") and destination types with a single space
	          converters: {
	            // Convert anything to text
	            "* text": String,
	            // Text to html (true = no transformation)
	            "text html": true,
	            // Evaluate text as a json expression
	            "text json": JSON.parse,
	            // Parse text as xml
	            "text xml": jQuery.parseXML
	          },
	          // For options that shouldn't be deep extended:
	          // you can add your own custom options here if
	          // and when you create one that shouldn't be
	          // deep extended (see ajaxExtend)
	          flatOptions: {
	            url: true,
	            context: true
	          }
	        },
	        // Creates a full fledged settings object into target
	        // with both ajaxSettings and settings fields.
	        // If target is omitted, writes into ajaxSettings.
	        ajaxSetup: function (target, settings) {
	          return settings ?
	          // Building a settings object
	          ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
	          // Extending ajaxSettings
	          ajaxExtend(jQuery.ajaxSettings, target);
	        },
	        ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
	        ajaxTransport: addToPrefiltersOrTransports(transports),
	        // Main method
	        ajax: function (url, options) {
	          // If url is an object, simulate pre-1.5 signature
	          if (typeof url === "object") {
	            options = url;
	            url = undefined;
	          }

	          // Force options to be an object
	          options = options || {};
	          var transport,
	            // URL without anti-cache param
	            cacheURL,
	            // Response headers
	            responseHeadersString,
	            responseHeaders,
	            // timeout handle
	            timeoutTimer,
	            // Url cleanup var
	            urlAnchor,
	            // Request state (becomes false upon send and true upon completion)
	            completed,
	            // To know if global events are to be dispatched
	            fireGlobals,
	            // Loop variable
	            i,
	            // uncached part of the url
	            uncached,
	            // Create the final options object
	            s = jQuery.ajaxSetup({}, options),
	            // Callbacks context
	            callbackContext = s.context || s,
	            // Context for global events is callbackContext if it is a DOM node or jQuery collection
	            globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,
	            // Deferreds
	            deferred = jQuery.Deferred(),
	            completeDeferred = jQuery.Callbacks("once memory"),
	            // Status-dependent callbacks
	            statusCode = s.statusCode || {},
	            // Headers (they are sent all at once)
	            requestHeaders = {},
	            requestHeadersNames = {},
	            // Default abort message
	            strAbort = "canceled",
	            // Fake xhr
	            jqXHR = {
	              readyState: 0,
	              // Builds headers hashtable if needed
	              getResponseHeader: function (key) {
	                var match;
	                if (completed) {
	                  if (!responseHeaders) {
	                    responseHeaders = {};
	                    while (match = rheaders.exec(responseHeadersString)) {
	                      responseHeaders[match[1].toLowerCase() + " "] = (responseHeaders[match[1].toLowerCase() + " "] || []).concat(match[2]);
	                    }
	                  }
	                  match = responseHeaders[key.toLowerCase() + " "];
	                }
	                return match == null ? null : match.join(", ");
	              },
	              // Raw string
	              getAllResponseHeaders: function () {
	                return completed ? responseHeadersString : null;
	              },
	              // Caches the header
	              setRequestHeader: function (name, value) {
	                if (completed == null) {
	                  name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name;
	                  requestHeaders[name] = value;
	                }
	                return this;
	              },
	              // Overrides response content-type header
	              overrideMimeType: function (type) {
	                if (completed == null) {
	                  s.mimeType = type;
	                }
	                return this;
	              },
	              // Status-dependent callbacks
	              statusCode: function (map) {
	                var code;
	                if (map) {
	                  if (completed) {
	                    // Execute the appropriate callbacks
	                    jqXHR.always(map[jqXHR.status]);
	                  } else {
	                    // Lazy-add the new callbacks in a way that preserves old ones
	                    for (code in map) {
	                      statusCode[code] = [statusCode[code], map[code]];
	                    }
	                  }
	                }
	                return this;
	              },
	              // Cancel the request
	              abort: function (statusText) {
	                var finalText = statusText || strAbort;
	                if (transport) {
	                  transport.abort(finalText);
	                }
	                done(0, finalText);
	                return this;
	              }
	            };

	          // Attach deferreds
	          deferred.promise(jqXHR);

	          // Add protocol if not provided (prefilters might expect it)
	          // Handle falsy url in the settings object (trac-10093: consistency with old signature)
	          // We also use the url parameter if available
	          s.url = ((url || s.url || location.href) + "").replace(rprotocol, location.protocol + "//");

	          // Alias method option to type as per ticket trac-12004
	          s.type = options.method || options.type || s.method || s.type;

	          // Extract dataTypes list
	          s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""];

	          // A cross-domain request is in order when the origin doesn't match the current origin.
	          if (s.crossDomain == null) {
	            urlAnchor = document.createElement("a");

	            // Support: IE <=8 - 11, Edge 12 - 15
	            // IE throws exception on accessing the href property if url is malformed,
	            // e.g. http://example.com:80x/
	            try {
	              urlAnchor.href = s.url;

	              // Support: IE <=8 - 11 only
	              // Anchor's host property isn't correctly set when s.url is relative
	              urlAnchor.href = urlAnchor.href;
	              s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host;
	            } catch (e) {
	              // If there is an error parsing the URL, assume it is crossDomain,
	              // it can be rejected by the transport if it is invalid
	              s.crossDomain = true;
	            }
	          }

	          // Convert data if not already a string
	          if (s.data && s.processData && typeof s.data !== "string") {
	            s.data = jQuery.param(s.data, s.traditional);
	          }

	          // Apply prefilters
	          inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);

	          // If request was aborted inside a prefilter, stop there
	          if (completed) {
	            return jqXHR;
	          }

	          // We can fire global events as of now if asked to
	          // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
	          fireGlobals = jQuery.event && s.global;

	          // Watch for a new set of requests
	          if (fireGlobals && jQuery.active++ === 0) {
	            jQuery.event.trigger("ajaxStart");
	          }

	          // Uppercase the type
	          s.type = s.type.toUpperCase();

	          // Determine if request has content
	          s.hasContent = !rnoContent.test(s.type);

	          // Save the URL in case we're toying with the If-Modified-Since
	          // and/or If-None-Match header later on
	          // Remove hash to simplify url manipulation
	          cacheURL = s.url.replace(rhash, "");

	          // More options handling for requests with no content
	          if (!s.hasContent) {
	            // Remember the hash so we can put it back
	            uncached = s.url.slice(cacheURL.length);

	            // If data is available and should be processed, append data to url
	            if (s.data && (s.processData || typeof s.data === "string")) {
	              cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data;

	              // trac-9682: remove data so that it's not used in an eventual retry
	              delete s.data;
	            }

	            // Add or update anti-cache param if needed
	            if (s.cache === false) {
	              cacheURL = cacheURL.replace(rantiCache, "$1");
	              uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce.guid++ + uncached;
	            }

	            // Put hash and anti-cache on the URL that will be requested (gh-1732)
	            s.url = cacheURL + uncached;

	            // Change '%20' to '+' if this is encoded form body content (gh-2658)
	          } else if (s.data && s.processData && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) {
	            s.data = s.data.replace(r20, "+");
	          }

	          // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
	          if (s.ifModified) {
	            if (jQuery.lastModified[cacheURL]) {
	              jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
	            }
	            if (jQuery.etag[cacheURL]) {
	              jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
	            }
	          }

	          // Set the correct header, if data is being sent
	          if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
	            jqXHR.setRequestHeader("Content-Type", s.contentType);
	          }

	          // Set the Accepts header for the server, depending on the dataType
	          jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]);

	          // Check for headers option
	          for (i in s.headers) {
	            jqXHR.setRequestHeader(i, s.headers[i]);
	          }

	          // Allow custom headers/mimetypes and early abort
	          if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) {
	            // Abort if not done already and return
	            return jqXHR.abort();
	          }

	          // Aborting is no longer a cancellation
	          strAbort = "abort";

	          // Install callbacks on deferreds
	          completeDeferred.add(s.complete);
	          jqXHR.done(s.success);
	          jqXHR.fail(s.error);

	          // Get transport
	          transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);

	          // If no transport, we auto-abort
	          if (!transport) {
	            done(-1, "No Transport");
	          } else {
	            jqXHR.readyState = 1;

	            // Send global event
	            if (fireGlobals) {
	              globalEventContext.trigger("ajaxSend", [jqXHR, s]);
	            }

	            // If request was aborted inside ajaxSend, stop there
	            if (completed) {
	              return jqXHR;
	            }

	            // Timeout
	            if (s.async && s.timeout > 0) {
	              timeoutTimer = window.setTimeout(function () {
	                jqXHR.abort("timeout");
	              }, s.timeout);
	            }
	            try {
	              completed = false;
	              transport.send(requestHeaders, done);
	            } catch (e) {
	              // Rethrow post-completion exceptions
	              if (completed) {
	                throw e;
	              }

	              // Propagate others as results
	              done(-1, e);
	            }
	          }

	          // Callback for when everything is done
	          function done(status, nativeStatusText, responses, headers) {
	            var isSuccess,
	              success,
	              error,
	              response,
	              modified,
	              statusText = nativeStatusText;

	            // Ignore repeat invocations
	            if (completed) {
	              return;
	            }
	            completed = true;

	            // Clear timeout if it exists
	            if (timeoutTimer) {
	              window.clearTimeout(timeoutTimer);
	            }

	            // Dereference transport for early garbage collection
	            // (no matter how long the jqXHR object will be used)
	            transport = undefined;

	            // Cache response headers
	            responseHeadersString = headers || "";

	            // Set readyState
	            jqXHR.readyState = status > 0 ? 4 : 0;

	            // Determine if successful
	            isSuccess = status >= 200 && status < 300 || status === 304;

	            // Get response data
	            if (responses) {
	              response = ajaxHandleResponses(s, jqXHR, responses);
	            }

	            // Use a noop converter for missing script but not if jsonp
	            if (!isSuccess && jQuery.inArray("script", s.dataTypes) > -1 && jQuery.inArray("json", s.dataTypes) < 0) {
	              s.converters["text script"] = function () {};
	            }

	            // Convert no matter what (that way responseXXX fields are always set)
	            response = ajaxConvert(s, response, jqXHR, isSuccess);

	            // If successful, handle type chaining
	            if (isSuccess) {
	              // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
	              if (s.ifModified) {
	                modified = jqXHR.getResponseHeader("Last-Modified");
	                if (modified) {
	                  jQuery.lastModified[cacheURL] = modified;
	                }
	                modified = jqXHR.getResponseHeader("etag");
	                if (modified) {
	                  jQuery.etag[cacheURL] = modified;
	                }
	              }

	              // if no content
	              if (status === 204 || s.type === "HEAD") {
	                statusText = "nocontent";

	                // if not modified
	              } else if (status === 304) {
	                statusText = "notmodified";

	                // If we have data, let's convert it
	              } else {
	                statusText = response.state;
	                success = response.data;
	                error = response.error;
	                isSuccess = !error;
	              }
	            } else {
	              // Extract error from statusText and normalize for non-aborts
	              error = statusText;
	              if (status || !statusText) {
	                statusText = "error";
	                if (status < 0) {
	                  status = 0;
	                }
	              }
	            }

	            // Set data for the fake xhr object
	            jqXHR.status = status;
	            jqXHR.statusText = (nativeStatusText || statusText) + "";

	            // Success/Error
	            if (isSuccess) {
	              deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
	            } else {
	              deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
	            }

	            // Status-dependent callbacks
	            jqXHR.statusCode(statusCode);
	            statusCode = undefined;
	            if (fireGlobals) {
	              globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
	            }

	            // Complete
	            completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
	            if (fireGlobals) {
	              globalEventContext.trigger("ajaxComplete", [jqXHR, s]);

	              // Handle the global AJAX counter
	              if (! --jQuery.active) {
	                jQuery.event.trigger("ajaxStop");
	              }
	            }
	          }
	          return jqXHR;
	        },
	        getJSON: function (url, data, callback) {
	          return jQuery.get(url, data, callback, "json");
	        },
	        getScript: function (url, callback) {
	          return jQuery.get(url, undefined, callback, "script");
	        }
	      });
	      jQuery.each(["get", "post"], function (_i, method) {
	        jQuery[method] = function (url, data, callback, type) {
	          // Shift arguments if data argument was omitted
	          if (isFunction(data)) {
	            type = type || callback;
	            callback = data;
	            data = undefined;
	          }

	          // The url can be an options object (which then must have .url)
	          return jQuery.ajax(jQuery.extend({
	            url: url,
	            type: method,
	            dataType: type,
	            data: data,
	            success: callback
	          }, jQuery.isPlainObject(url) && url));
	        };
	      });
	      jQuery.ajaxPrefilter(function (s) {
	        var i;
	        for (i in s.headers) {
	          if (i.toLowerCase() === "content-type") {
	            s.contentType = s.headers[i] || "";
	          }
	        }
	      });
	      jQuery._evalUrl = function (url, options, doc) {
	        return jQuery.ajax({
	          url: url,
	          // Make this explicit, since user can override this through ajaxSetup (trac-11264)
	          type: "GET",
	          dataType: "script",
	          cache: true,
	          async: false,
	          global: false,
	          // Only evaluate the response if it is successful (gh-4126)
	          // dataFilter is not invoked for failure responses, so using it instead
	          // of the default converter is kludgy but it works.
	          converters: {
	            "text script": function () {}
	          },
	          dataFilter: function (response) {
	            jQuery.globalEval(response, options, doc);
	          }
	        });
	      };
	      jQuery.fn.extend({
	        wrapAll: function (html) {
	          var wrap;
	          if (this[0]) {
	            if (isFunction(html)) {
	              html = html.call(this[0]);
	            }

	            // The elements to wrap the target around
	            wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
	            if (this[0].parentNode) {
	              wrap.insertBefore(this[0]);
	            }
	            wrap.map(function () {
	              var elem = this;
	              while (elem.firstElementChild) {
	                elem = elem.firstElementChild;
	              }
	              return elem;
	            }).append(this);
	          }
	          return this;
	        },
	        wrapInner: function (html) {
	          if (isFunction(html)) {
	            return this.each(function (i) {
	              jQuery(this).wrapInner(html.call(this, i));
	            });
	          }
	          return this.each(function () {
	            var self = jQuery(this),
	              contents = self.contents();
	            if (contents.length) {
	              contents.wrapAll(html);
	            } else {
	              self.append(html);
	            }
	          });
	        },
	        wrap: function (html) {
	          var htmlIsFunction = isFunction(html);
	          return this.each(function (i) {
	            jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html);
	          });
	        },
	        unwrap: function (selector) {
	          this.parent(selector).not("body").each(function () {
	            jQuery(this).replaceWith(this.childNodes);
	          });
	          return this;
	        }
	      });
	      jQuery.expr.pseudos.hidden = function (elem) {
	        return !jQuery.expr.pseudos.visible(elem);
	      };
	      jQuery.expr.pseudos.visible = function (elem) {
	        return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
	      };
	      jQuery.ajaxSettings.xhr = function () {
	        try {
	          return new window.XMLHttpRequest();
	        } catch (e) {}
	      };
	      var xhrSuccessStatus = {
	          // File protocol always yields status code 0, assume 200
	          0: 200,
	          // Support: IE <=9 only
	          // trac-1450: sometimes IE returns 1223 when it should be 204
	          1223: 204
	        },
	        xhrSupported = jQuery.ajaxSettings.xhr();
	      support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
	      support.ajax = xhrSupported = !!xhrSupported;
	      jQuery.ajaxTransport(function (options) {
	        var callback, errorCallback;

	        // Cross domain only allowed if supported through XMLHttpRequest
	        if (support.cors || xhrSupported && !options.crossDomain) {
	          return {
	            send: function (headers, complete) {
	              var i,
	                xhr = options.xhr();
	              xhr.open(options.type, options.url, options.async, options.username, options.password);

	              // Apply custom fields if provided
	              if (options.xhrFields) {
	                for (i in options.xhrFields) {
	                  xhr[i] = options.xhrFields[i];
	                }
	              }

	              // Override mime type if needed
	              if (options.mimeType && xhr.overrideMimeType) {
	                xhr.overrideMimeType(options.mimeType);
	              }

	              // X-Requested-With header
	              // For cross-domain requests, seeing as conditions for a preflight are
	              // akin to a jigsaw puzzle, we simply never set it to be sure.
	              // (it can always be set on a per-request basis or even using ajaxSetup)
	              // For same-domain requests, won't change header if already provided.
	              if (!options.crossDomain && !headers["X-Requested-With"]) {
	                headers["X-Requested-With"] = "XMLHttpRequest";
	              }

	              // Set headers
	              for (i in headers) {
	                xhr.setRequestHeader(i, headers[i]);
	              }

	              // Callback
	              callback = function (type) {
	                return function () {
	                  if (callback) {
	                    callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null;
	                    if (type === "abort") {
	                      xhr.abort();
	                    } else if (type === "error") {
	                      // Support: IE <=9 only
	                      // On a manual native abort, IE9 throws
	                      // errors on any property access that is not readyState
	                      if (typeof xhr.status !== "number") {
	                        complete(0, "error");
	                      } else {
	                        complete(
	                        // File: protocol always yields status 0; see trac-8605, trac-14207
	                        xhr.status, xhr.statusText);
	                      }
	                    } else {
	                      complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText,
	                      // Support: IE <=9 only
	                      // IE9 has no XHR2 but throws on binary (trac-11426)
	                      // For XHR2 non-text, let the caller handle it (gh-2498)
	                      (xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? {
	                        binary: xhr.response
	                      } : {
	                        text: xhr.responseText
	                      }, xhr.getAllResponseHeaders());
	                    }
	                  }
	                };
	              };

	              // Listen to events
	              xhr.onload = callback();
	              errorCallback = xhr.onerror = xhr.ontimeout = callback("error");

	              // Support: IE 9 only
	              // Use onreadystatechange to replace onabort
	              // to handle uncaught aborts
	              if (xhr.onabort !== undefined) {
	                xhr.onabort = errorCallback;
	              } else {
	                xhr.onreadystatechange = function () {
	                  // Check readyState before timeout as it changes
	                  if (xhr.readyState === 4) {
	                    // Allow onerror to be called first,
	                    // but that will not handle a native abort
	                    // Also, save errorCallback to a variable
	                    // as xhr.onerror cannot be accessed
	                    window.setTimeout(function () {
	                      if (callback) {
	                        errorCallback();
	                      }
	                    });
	                  }
	                };
	              }

	              // Create the abort callback
	              callback = callback("abort");
	              try {
	                // Do send the request (this may raise an exception)
	                xhr.send(options.hasContent && options.data || null);
	              } catch (e) {
	                // trac-14683: Only rethrow if this hasn't been notified as an error yet
	                if (callback) {
	                  throw e;
	                }
	              }
	            },
	            abort: function () {
	              if (callback) {
	                callback();
	              }
	            }
	          };
	        }
	      });

	      // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
	      jQuery.ajaxPrefilter(function (s) {
	        if (s.crossDomain) {
	          s.contents.script = false;
	        }
	      });

	      // Install script dataType
	      jQuery.ajaxSetup({
	        accepts: {
	          script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript"
	        },
	        contents: {
	          script: /\b(?:java|ecma)script\b/
	        },
	        converters: {
	          "text script": function (text) {
	            jQuery.globalEval(text);
	            return text;
	          }
	        }
	      });

	      // Handle cache's special case and crossDomain
	      jQuery.ajaxPrefilter("script", function (s) {
	        if (s.cache === undefined) {
	          s.cache = false;
	        }
	        if (s.crossDomain) {
	          s.type = "GET";
	        }
	      });

	      // Bind script tag hack transport
	      jQuery.ajaxTransport("script", function (s) {
	        // This transport only deals with cross domain or forced-by-attrs requests
	        if (s.crossDomain || s.scriptAttrs) {
	          var script, callback;
	          return {
	            send: function (_, complete) {
	              script = jQuery("<script>").attr(s.scriptAttrs || {}).prop({
	                charset: s.scriptCharset,
	                src: s.url
	              }).on("load error", callback = function (evt) {
	                script.remove();
	                callback = null;
	                if (evt) {
	                  complete(evt.type === "error" ? 404 : 200, evt.type);
	                }
	              });

	              // Use native DOM manipulation to avoid our domManip AJAX trickery
	              document.head.appendChild(script[0]);
	            },
	            abort: function () {
	              if (callback) {
	                callback();
	              }
	            }
	          };
	        }
	      });
	      var oldCallbacks = [],
	        rjsonp = /(=)\?(?=&|$)|\?\?/;

	      // Default jsonp settings
	      jQuery.ajaxSetup({
	        jsonp: "callback",
	        jsonpCallback: function () {
	          var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce.guid++;
	          this[callback] = true;
	          return callback;
	        }
	      });

	      // Detect, normalize options and install callbacks for jsonp requests
	      jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
	        var callbackName,
	          overwritten,
	          responseContainer,
	          jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0 && rjsonp.test(s.data) && "data");

	        // Handle iff the expected data type is "jsonp" or we have a parameter to set
	        if (jsonProp || s.dataTypes[0] === "jsonp") {
	          // Get callback name, remembering preexisting value associated with it
	          callbackName = s.jsonpCallback = isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;

	          // Insert callback into url or form data
	          if (jsonProp) {
	            s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
	          } else if (s.jsonp !== false) {
	            s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
	          }

	          // Use data converter to retrieve json after script execution
	          s.converters["script json"] = function () {
	            if (!responseContainer) {
	              jQuery.error(callbackName + " was not called");
	            }
	            return responseContainer[0];
	          };

	          // Force json dataType
	          s.dataTypes[0] = "json";

	          // Install callback
	          overwritten = window[callbackName];
	          window[callbackName] = function () {
	            responseContainer = arguments;
	          };

	          // Clean-up function (fires after converters)
	          jqXHR.always(function () {
	            // If previous value didn't exist - remove it
	            if (overwritten === undefined) {
	              jQuery(window).removeProp(callbackName);

	              // Otherwise restore preexisting value
	            } else {
	              window[callbackName] = overwritten;
	            }

	            // Save back as free
	            if (s[callbackName]) {
	              // Make sure that re-using the options doesn't screw things around
	              s.jsonpCallback = originalSettings.jsonpCallback;

	              // Save the callback name for future use
	              oldCallbacks.push(callbackName);
	            }

	            // Call if it was a function and we have a response
	            if (responseContainer && isFunction(overwritten)) {
	              overwritten(responseContainer[0]);
	            }
	            responseContainer = overwritten = undefined;
	          });

	          // Delegate to script
	          return "script";
	        }
	      });

	      // Support: Safari 8 only
	      // In Safari 8 documents created via document.implementation.createHTMLDocument
	      // collapse sibling forms: the second one becomes a child of the first one.
	      // Because of that, this security measure has to be disabled in Safari 8.
	      // https://bugs.webkit.org/show_bug.cgi?id=137337
	      support.createHTMLDocument = function () {
	        var body = document.implementation.createHTMLDocument("").body;
	        body.innerHTML = "<form></form><form></form>";
	        return body.childNodes.length === 2;
	      }();

	      // Argument "data" should be string of html
	      // context (optional): If specified, the fragment will be created in this context,
	      // defaults to document
	      // keepScripts (optional): If true, will include scripts passed in the html string
	      jQuery.parseHTML = function (data, context, keepScripts) {
	        if (typeof data !== "string") {
	          return [];
	        }
	        if (typeof context === "boolean") {
	          keepScripts = context;
	          context = false;
	        }
	        var base, parsed, scripts;
	        if (!context) {
	          // Stop scripts or inline event handlers from being executed immediately
	          // by using document.implementation
	          if (support.createHTMLDocument) {
	            context = document.implementation.createHTMLDocument("");

	            // Set the base href for the created document
	            // so any parsed elements with URLs
	            // are based on the document's URL (gh-2965)
	            base = context.createElement("base");
	            base.href = document.location.href;
	            context.head.appendChild(base);
	          } else {
	            context = document;
	          }
	        }
	        parsed = rsingleTag.exec(data);
	        scripts = !keepScripts && [];

	        // Single tag
	        if (parsed) {
	          return [context.createElement(parsed[1])];
	        }
	        parsed = buildFragment([data], context, scripts);
	        if (scripts && scripts.length) {
	          jQuery(scripts).remove();
	        }
	        return jQuery.merge([], parsed.childNodes);
	      };

	      /**
	       * Load a url into a page
	       */
	      jQuery.fn.load = function (url, params, callback) {
	        var selector,
	          type,
	          response,
	          self = this,
	          off = url.indexOf(" ");
	        if (off > -1) {
	          selector = stripAndCollapse(url.slice(off));
	          url = url.slice(0, off);
	        }

	        // If it's a function
	        if (isFunction(params)) {
	          // We assume that it's the callback
	          callback = params;
	          params = undefined;

	          // Otherwise, build a param string
	        } else if (params && typeof params === "object") {
	          type = "POST";
	        }

	        // If we have elements to modify, make the request
	        if (self.length > 0) {
	          jQuery.ajax({
	            url: url,
	            // If "type" variable is undefined, then "GET" method will be used.
	            // Make value of this field explicit since
	            // user can override it through ajaxSetup method
	            type: type || "GET",
	            dataType: "html",
	            data: params
	          }).done(function (responseText) {
	            // Save response for use in complete callback
	            response = arguments;
	            self.html(selector ?
	            // If a selector was specified, locate the right elements in a dummy div
	            // Exclude scripts to avoid IE 'Permission Denied' errors
	            jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
	            // Otherwise use the full result
	            responseText);

	            // If the request succeeds, this function gets "data", "status", "jqXHR"
	            // but they are ignored because response was set above.
	            // If it fails, this function gets "jqXHR", "status", "error"
	          }).always(callback && function (jqXHR, status) {
	            self.each(function () {
	              callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
	            });
	          });
	        }
	        return this;
	      };
	      jQuery.expr.pseudos.animated = function (elem) {
	        return jQuery.grep(jQuery.timers, function (fn) {
	          return elem === fn.elem;
	        }).length;
	      };
	      jQuery.offset = {
	        setOffset: function (elem, options, i) {
	          var curPosition,
	            curLeft,
	            curCSSTop,
	            curTop,
	            curOffset,
	            curCSSLeft,
	            calculatePosition,
	            position = jQuery.css(elem, "position"),
	            curElem = jQuery(elem),
	            props = {};

	          // Set position first, in-case top/left are set even on static elem
	          if (position === "static") {
	            elem.style.position = "relative";
	          }
	          curOffset = curElem.offset();
	          curCSSTop = jQuery.css(elem, "top");
	          curCSSLeft = jQuery.css(elem, "left");
	          calculatePosition = (position === "absolute" || position === "fixed") && (curCSSTop + curCSSLeft).indexOf("auto") > -1;

	          // Need to be able to calculate position if either
	          // top or left is auto and position is either absolute or fixed
	          if (calculatePosition) {
	            curPosition = curElem.position();
	            curTop = curPosition.top;
	            curLeft = curPosition.left;
	          } else {
	            curTop = parseFloat(curCSSTop) || 0;
	            curLeft = parseFloat(curCSSLeft) || 0;
	          }
	          if (isFunction(options)) {
	            // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
	            options = options.call(elem, i, jQuery.extend({}, curOffset));
	          }
	          if (options.top != null) {
	            props.top = options.top - curOffset.top + curTop;
	          }
	          if (options.left != null) {
	            props.left = options.left - curOffset.left + curLeft;
	          }
	          if ("using" in options) {
	            options.using.call(elem, props);
	          } else {
	            curElem.css(props);
	          }
	        }
	      };
	      jQuery.fn.extend({
	        // offset() relates an element's border box to the document origin
	        offset: function (options) {
	          // Preserve chaining for setter
	          if (arguments.length) {
	            return options === undefined ? this : this.each(function (i) {
	              jQuery.offset.setOffset(this, options, i);
	            });
	          }
	          var rect,
	            win,
	            elem = this[0];
	          if (!elem) {
	            return;
	          }

	          // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
	          // Support: IE <=11 only
	          // Running getBoundingClientRect on a
	          // disconnected node in IE throws an error
	          if (!elem.getClientRects().length) {
	            return {
	              top: 0,
	              left: 0
	            };
	          }

	          // Get document-relative position by adding viewport scroll to viewport-relative gBCR
	          rect = elem.getBoundingClientRect();
	          win = elem.ownerDocument.defaultView;
	          return {
	            top: rect.top + win.pageYOffset,
	            left: rect.left + win.pageXOffset
	          };
	        },
	        // position() relates an element's margin box to its offset parent's padding box
	        // This corresponds to the behavior of CSS absolute positioning
	        position: function () {
	          if (!this[0]) {
	            return;
	          }
	          var offsetParent,
	            offset,
	            doc,
	            elem = this[0],
	            parentOffset = {
	              top: 0,
	              left: 0
	            };

	          // position:fixed elements are offset from the viewport, which itself always has zero offset
	          if (jQuery.css(elem, "position") === "fixed") {
	            // Assume position:fixed implies availability of getBoundingClientRect
	            offset = elem.getBoundingClientRect();
	          } else {
	            offset = this.offset();

	            // Account for the *real* offset parent, which can be the document or its root element
	            // when a statically positioned element is identified
	            doc = elem.ownerDocument;
	            offsetParent = elem.offsetParent || doc.documentElement;
	            while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && jQuery.css(offsetParent, "position") === "static") {
	              offsetParent = offsetParent.parentNode;
	            }
	            if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
	              // Incorporate borders into its offset, since they are outside its content origin
	              parentOffset = jQuery(offsetParent).offset();
	              parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true);
	              parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true);
	            }
	          }

	          // Subtract parent offsets and element margins
	          return {
	            top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
	            left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
	          };
	        },
	        // This method will return documentElement in the following cases:
	        // 1) For the element inside the iframe without offsetParent, this method will return
	        //    documentElement of the parent window
	        // 2) For the hidden or detached element
	        // 3) For body or html element, i.e. in case of the html node - it will return itself
	        //
	        // but those exceptions were never presented as a real life use-cases
	        // and might be considered as more preferable results.
	        //
	        // This logic, however, is not guaranteed and can change at any point in the future
	        offsetParent: function () {
	          return this.map(function () {
	            var offsetParent = this.offsetParent;
	            while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
	              offsetParent = offsetParent.offsetParent;
	            }
	            return offsetParent || documentElement;
	          });
	        }
	      });

	      // Create scrollLeft and scrollTop methods
	      jQuery.each({
	        scrollLeft: "pageXOffset",
	        scrollTop: "pageYOffset"
	      }, function (method, prop) {
	        var top = "pageYOffset" === prop;
	        jQuery.fn[method] = function (val) {
	          return access(this, function (elem, method, val) {
	            // Coalesce documents and windows
	            var win;
	            if (isWindow(elem)) {
	              win = elem;
	            } else if (elem.nodeType === 9) {
	              win = elem.defaultView;
	            }
	            if (val === undefined) {
	              return win ? win[prop] : elem[method];
	            }
	            if (win) {
	              win.scrollTo(!top ? val : win.pageXOffset, top ? val : win.pageYOffset);
	            } else {
	              elem[method] = val;
	            }
	          }, method, val, arguments.length);
	        };
	      });

	      // Support: Safari <=7 - 9.1, Chrome <=37 - 49
	      // Add the top/left cssHooks using jQuery.fn.position
	      // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
	      // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
	      // getComputedStyle returns percent when specified for top/left/bottom/right;
	      // rather than make the css module depend on the offset module, just check for it here
	      jQuery.each(["top", "left"], function (_i, prop) {
	        jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) {
	          if (computed) {
	            computed = curCSS(elem, prop);

	            // If curCSS returns percentage, fallback to offset
	            return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed;
	          }
	        });
	      });

	      // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
	      jQuery.each({
	        Height: "height",
	        Width: "width"
	      }, function (name, type) {
	        jQuery.each({
	          padding: "inner" + name,
	          content: type,
	          "": "outer" + name
	        }, function (defaultExtra, funcName) {
	          // Margin is only for outerHeight, outerWidth
	          jQuery.fn[funcName] = function (margin, value) {
	            var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
	              extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
	            return access(this, function (elem, type, value) {
	              var doc;
	              if (isWindow(elem)) {
	                // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
	                return funcName.indexOf("outer") === 0 ? elem["inner" + name] : elem.document.documentElement["client" + name];
	              }

	              // Get document width or height
	              if (elem.nodeType === 9) {
	                doc = elem.documentElement;

	                // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
	                // whichever is greatest
	                return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);
	              }
	              return value === undefined ?
	              // Get width or height on the element, requesting but not forcing parseFloat
	              jQuery.css(elem, type, extra) :
	              // Set width or height on the element
	              jQuery.style(elem, type, value, extra);
	            }, type, chainable ? margin : undefined, chainable);
	          };
	        });
	      });
	      jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (_i, type) {
	        jQuery.fn[type] = function (fn) {
	          return this.on(type, fn);
	        };
	      });
	      jQuery.fn.extend({
	        bind: function (types, data, fn) {
	          return this.on(types, null, data, fn);
	        },
	        unbind: function (types, fn) {
	          return this.off(types, null, fn);
	        },
	        delegate: function (selector, types, data, fn) {
	          return this.on(types, selector, data, fn);
	        },
	        undelegate: function (selector, types, fn) {
	          // ( namespace ) or ( selector, types [, fn] )
	          return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
	        },
	        hover: function (fnOver, fnOut) {
	          return this.on("mouseenter", fnOver).on("mouseleave", fnOut || fnOver);
	        }
	      });
	      jQuery.each(("blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu").split(" "), function (_i, name) {
	        // Handle event binding
	        jQuery.fn[name] = function (data, fn) {
	          return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);
	        };
	      });

	      // Support: Android <=4.0 only
	      // Make sure we trim BOM and NBSP
	      // Require that the "whitespace run" starts from a non-whitespace
	      // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
	      var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;

	      // Bind a function to a context, optionally partially applying any
	      // arguments.
	      // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
	      // However, it is not slated for removal any time soon
	      jQuery.proxy = function (fn, context) {
	        var tmp, args, proxy;
	        if (typeof context === "string") {
	          tmp = fn[context];
	          context = fn;
	          fn = tmp;
	        }

	        // Quick check to determine if target is callable, in the spec
	        // this throws a TypeError, but we will just return undefined.
	        if (!isFunction(fn)) {
	          return undefined;
	        }

	        // Simulated bind
	        args = slice.call(arguments, 2);
	        proxy = function () {
	          return fn.apply(context || this, args.concat(slice.call(arguments)));
	        };

	        // Set the guid of unique handler to the same of original handler, so it can be removed
	        proxy.guid = fn.guid = fn.guid || jQuery.guid++;
	        return proxy;
	      };
	      jQuery.holdReady = function (hold) {
	        if (hold) {
	          jQuery.readyWait++;
	        } else {
	          jQuery.ready(true);
	        }
	      };
	      jQuery.isArray = Array.isArray;
	      jQuery.parseJSON = JSON.parse;
	      jQuery.nodeName = nodeName;
	      jQuery.isFunction = isFunction;
	      jQuery.isWindow = isWindow;
	      jQuery.camelCase = camelCase;
	      jQuery.type = toType;
	      jQuery.now = Date.now;
	      jQuery.isNumeric = function (obj) {
	        // As of jQuery 3.0, isNumeric is limited to
	        // strings and numbers (primitives or objects)
	        // that can be coerced to finite numbers (gh-2662)
	        var type = jQuery.type(obj);
	        return (type === "number" || type === "string") &&
	        // parseFloat NaNs numeric-cast false positives ("")
	        // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
	        // subtraction forces infinities to NaN
	        !isNaN(obj - parseFloat(obj));
	      };
	      jQuery.trim = function (text) {
	        return text == null ? "" : (text + "").replace(rtrim, "$1");
	      };
	      var
	        // Map over jQuery in case of overwrite
	        _jQuery = window.jQuery,
	        // Map over the $ in case of overwrite
	        _$ = window.$;
	      jQuery.noConflict = function (deep) {
	        if (window.$ === jQuery) {
	          window.$ = _$;
	        }
	        if (deep && window.jQuery === jQuery) {
	          window.jQuery = _jQuery;
	        }
	        return jQuery;
	      };

	      // Expose jQuery and $ identifiers, even in AMD
	      // (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
	      // and CommonJS for browser emulators (trac-13566)
	      if (typeof noGlobal === "undefined") {
	        window.jQuery = window.$ = jQuery;
	      }
	      return jQuery;
	    });
	  })(jquery$1);
	  return jquery$1.exports;
	}

	var jqueryExports = requireJquery();
	var $$2 = /*@__PURE__*/getDefaultExportFromCjs(jqueryExports);

	var Object_Disclaimer_LimitedData = {
	  id: "Object.Disclaimer.LimitedData",
	  locale: {
	    "en-US": "Currently showing a limited data set.",
	    "zh-TW": "目前顯示的是有限的資料集。",
	    "zh-CN": "当前正显示有限的数据集。",
	    "tr-TR": "Şu anda sınırlı bir veri kümesi gösteriliyor.",
	    "sv-SE": "Just nu visas en begränsad uppsättning data.",
	    "it-IT": "Attualmente viene visualizzata una serie di dati limitata.",
	    "es-ES": "Mostrando actualmente un conjunto limitado de datos.",
	    "de-DE": "Zurzeit wird nur ein beschränkter Datensatz angezeigt.",
	    "pl-PL": "Aktualnie przedstawiany jest ograniczony zestaw danych.",
	    "nl-NL": "Momenteel wordt een beperkte gegevensverzameling getoond.",
	    "ko-KR": "현재 제한된 데이터 집합을 표시하고 있습니다.",
	    "pt-BR": "Mostrando um conjunto de dados limitado.",
	    "fr-FR": "Affichage d'un ensemble de données limité pour l'instant.",
	    "ja-JP": "現在、限定的なデータ セットを表示しています。",
	    "ru-RU": "В настоящее время отображается ограниченный набор данных."
	  }
	};
	var Object_Disclaimer_OnlyNanData = {
	  id: "Object.Disclaimer.OnlyNanData",
	  locale: {
	    "en-US": "The chart is not displayed because it contains only undefined values.",
	    "zh-TW": "系統不會顯示圖表，因為該圖表僅包含未定義的值。",
	    "zh-CN": "未显示图表，因为它仅包含未定义的值。",
	    "tr-TR": "Yalnızca tanımsız değerleri içermesi nedeniyle grafik görüntülenmiyor.",
	    "sv-SE": "Diagrammet visas inte eftersom det enbart innehåller odefinierade värden.",
	    "it-IT": "Il grafico non è visualizzato poiché contiene solo valori non definiti.",
	    "es-ES": "El gráfico no se muestra porque solo contiene valores indefinidos.",
	    "de-DE": "Das Diagramm wird nicht angezeigt, da es nur nicht definierte Werte enthält.",
	    "pl-PL": "Wykres nie jest wyświetlany, ponieważ zawiera wartości niezdefiniowane.",
	    "nl-NL": "De grafiek wordt niet weergegeven omdat deze alleen ongedefinieerde waarden bevat.",
	    "ko-KR": "정의되지 않은 값만 포함되어 있으므로 차트가 표시되지 않습니다.",
	    "pt-BR": "O gráfico não foi exibido, porque contém apenas valores não definidos.",
	    "fr-FR": "Le graphique n'est pas affiché, car il contient uniquement des valeurs non définies.",
	    "ja-JP": "未定義の値しか含まれていないため、チャートは表示されていません。",
	    "ru-RU": "Диаграмма не отображается, поскольку она содержит только неопределенные значения."
	  }
	};
	var Object_Disclaimer_OnlyNegativeOrZeroValues = {
	  id: "Object.Disclaimer.OnlyNegativeOrZeroValues",
	  locale: {
	    "en-US": "The chart is not displayed because it contains only negative or zero values.",
	    "zh-TW": "系統不會顯示圖表，因為該圖表僅包含負值或零值。",
	    "zh-CN": "未显示图表，因为它仅包含负值或零值。",
	    "tr-TR": "Yalnızca negatif veya sıfır değerlerini içermesi nedeniyle grafik görüntülenmiyor.",
	    "sv-SE": "Diagrammet visas inte eftersom det enbart innehåller negativa eller nollvärden",
	    "it-IT": "Il grafico non viene visualizzato poiché contiene solo valori negativi o uguali a zero.",
	    "es-ES": "El gráfico no se muestra porque sólo contiene valores negativos o valores cero.",
	    "de-DE": "Das Diagramm wird nicht angezeigt, da es nur negative oder 0-Werte enthält.",
	    "pl-PL": "Wykres nie jest wyświetlany, ponieważ zawiera wartości ujemne lub zerowe.",
	    "nl-NL": "De grafiek wordt niet weergegeven omdat het alleen negatieve waarden of nulwaarden bevat.",
	    "ko-KR": "음수 또는 zero 값만 포함되어 있으므로 차트가 표시되지 않습니다.",
	    "pt-BR": "O gráfico não foi exibido, porque contém apenas valores negativos ou zero.",
	    "fr-FR": "Le graphique n'est pas affiché, car il contient uniquement des valeurs négatives ou égales à zéro.",
	    "ja-JP": "チャートは負の値またはゼロ値しか含まれていないため、表示されていません。",
	    "ru-RU": "Диаграмма не отображается, поскольку она содержит только отрицательные или нулевые значения."
	  }
	};
	var Object_Disclaimer_RequireNumericDimension = {
	  id: "Object.Disclaimer.RequireNumericDimension",
	  locale: {
	    "en-US": "This visualization requires a numeric diemnsion."
	  }
	};
	var all = {
	  "Visualization.Histogram.MeasureAxisLabel": {
	    id: "Visualization.Histogram.MeasureAxisLabel",
	    locale: {
	      "en-US": "Frequency",
	      "zh-TW": "頻率",
	      "zh-CN": "频率",
	      "tr-TR": "Sıklık",
	      "sv-SE": "Frekvens",
	      "it-IT": "Frequenza",
	      "es-ES": "Frecuencia",
	      "de-DE": "Häufigkeit",
	      "pl-PL": "Częstotliwość",
	      "nl-NL": "Frequentie",
	      "ko-KR": "빈도",
	      "pt-BR": "Frequência",
	      "fr-FR": "Fréquence",
	      "ja-JP": "レコード数",
	      "ru-RU": "Частота"
	    }
	  },
	  "waterfall.legend.positiveValue.label": {
	    id: "waterfall.legend.positiveValue.label",
	    locale: {
	      "en-US": "Positive",
	      "zh-TW": "正值",
	      "zh-CN": "正",
	      "tr-TR": "Pozitif",
	      "sv-SE": "Positiv",
	      "it-IT": "Positivi",
	      "es-ES": "Positivo",
	      "de-DE": "Positiv",
	      "pl-PL": "Dodatnie",
	      "nl-NL": "Positief",
	      "ko-KR": "양수",
	      "pt-BR": "Positivo",
	      "fr-FR": "Positive",
	      "ja-JP": "正",
	      "ru-RU": "Положительное"
	    }
	  },
	  "waterfall.legend.negativeValue.label": {
	    id: "waterfall.legend.negativeValue.label",
	    locale: {
	      "en-US": "Negative",
	      "zh-TW": "負值",
	      "zh-CN": "负",
	      "tr-TR": "Negatif",
	      "sv-SE": "Negativ",
	      "it-IT": "Negativi",
	      "es-ES": "Negativo",
	      "de-DE": "Negativ",
	      "pl-PL": "Ujemne",
	      "nl-NL": "Negatief",
	      "ko-KR": "음수",
	      "pt-BR": "Negativo",
	      "fr-FR": "Négative",
	      "ja-JP": "負",
	      "ru-RU": "Отрицательное"
	    }
	  },
	  "waterfall.legend.subtotal.label": {
	    id: "waterfall.legend.subtotal.label",
	    locale: {
	      "en-US": "Subtotal",
	      "zh-TW": "小計",
	      "zh-CN": "小计",
	      "tr-TR": "Ara Toplam",
	      "sv-SE": "Deltotal",
	      "it-IT": "Subtotale",
	      "es-ES": "Subtotal",
	      "de-DE": "Teilsumme",
	      "pl-PL": "Suma częściowa",
	      "nl-NL": "Subtotaal",
	      "ko-KR": "소계",
	      "pt-BR": "Subtotal",
	      "fr-FR": "Sous-total",
	      "ja-JP": "小計",
	      "ru-RU": "Подытог"
	    }
	  },
	  Object_Disclaimer_LimitedData: Object_Disclaimer_LimitedData,
	  Object_Disclaimer_OnlyNanData: Object_Disclaimer_OnlyNanData,
	  Object_Disclaimer_OnlyNegativeOrZeroValues: Object_Disclaimer_OnlyNegativeOrZeroValues,
	  Object_Disclaimer_RequireNumericDimension: Object_Disclaimer_RequireNumericDimension,
	  "properties.boxplot.calculationMode.tukey.elements.boxEnd": {
	    id: "properties.boxplot.calculationMode.tukey.elements.boxEnd",
	    locale: {
	      "en-US": "Third quartile",
	      "zh-TW": "第三四分位數",
	      "zh-CN": "第 3 个四分位",
	      "tr-TR": "Üçüncü çeyrek",
	      "sv-SE": "Tredje kvartilen",
	      "it-IT": "Terzo quartile",
	      "es-ES": "Tercer cuartil",
	      "de-DE": "Drittes Quartil",
	      "pl-PL": "Trzeci kwartyl",
	      "nl-NL": "Derde kwartiel",
	      "ko-KR": "3번째 사분위수",
	      "pt-BR": "Terceiro quartil",
	      "fr-FR": "Troisième quartile",
	      "ja-JP": "第 3 四分位数",
	      "ru-RU": "Третий квартиль"
	    }
	  },
	  "properties.boxplot.calculationMode.tukey.elements.boxMiddle": {
	    id: "properties.boxplot.calculationMode.tukey.elements.boxMiddle",
	    locale: {
	      "en-US": "Median",
	      "zh-TW": "中位數",
	      "zh-CN": "中间值",
	      "tr-TR": "Medyan",
	      "sv-SE": "Median",
	      "it-IT": "Mediana",
	      "es-ES": "Mediana",
	      "de-DE": "Drittes Quartil",
	      "pl-PL": "Mediana",
	      "nl-NL": "Mediaan",
	      "ko-KR": "중앙값",
	      "pt-BR": "Mediano",
	      "fr-FR": "Médiane",
	      "ja-JP": "中央値",
	      "ru-RU": "Медианное"
	    }
	  },
	  "properties.boxplot.calculationMode.tukey.elements.boxStart": {
	    id: "properties.boxplot.calculationMode.tukey.elements.boxStart",
	    locale: {
	      "en-US": "First quartile",
	      "zh-TW": "第一四分位數",
	      "zh-CN": "第 1 个四分位",
	      "tr-TR": "İlk çeyrek",
	      "sv-SE": "Första kvartilen",
	      "it-IT": "Primo quartile",
	      "es-ES": "Primer cuartil",
	      "de-DE": "Erstes Quartil",
	      "pl-PL": "Pierwszy kwartyl",
	      "nl-NL": "Eerste kwartiel",
	      "ko-KR": "1번째 사분위수",
	      "pt-BR": "Primeiro quartil",
	      "fr-FR": "Premier quartile",
	      "ja-JP": "第 1 四分位数",
	      "ru-RU": "Первый квартиль"
	    }
	  },
	  "properties.boxplot.calculationMode.tukey.elements.firstWhisker": {
	    id: "properties.boxplot.calculationMode.tukey.elements.firstWhisker",
	    locale: {
	      "en-US": "Box start - {0} IQR",
	      "zh-TW": "方塊開始 - {0} IQR",
	      "zh-CN": "框开始 - {0} IQR",
	      "tr-TR": "Kutu başlangıcı - {0} IQR",
	      "sv-SE": "Rutans start - {0} IQR",
	      "it-IT": "Inizio scatola - {0} IQR",
	      "es-ES": "Inicio de caja - {0} IQR",
	      "de-DE": "Box-Beginn - {0} IQR",
	      "pl-PL": "Początek wykresu pudełkowego - {0} IQR",
	      "nl-NL": "Begin box - {0} IQR",
	      "ko-KR": "상자 시작 - {0} IQR",
	      "pt-BR": "Início da caixa - {0} IQR",
	      "fr-FR": "Début de la boîte - {0} IQR",
	      "ja-JP": "ボックス開始 - {0} IQR",
	      "ru-RU": "Начало поля - {0} IQR"
	    }
	  },
	  "properties.boxplot.calculationMode.tukey.elements.lastWhisker": {
	    id: "properties.boxplot.calculationMode.tukey.elements.lastWhisker",
	    locale: {
	      "en-US": "Box end + {0} IQR",
	      "zh-TW": "方塊結束 + {0} IQR",
	      "zh-CN": "框结束 + {0} IQR",
	      "tr-TR": "Kutu bitişi + {0} IQR",
	      "sv-SE": "Rutans slut + {0} IQR",
	      "it-IT": "Fine scatola + {0} IQR",
	      "es-ES": "Fin de caja + {0} IQR",
	      "de-DE": "Box-Ende + {0} IQR",
	      "pl-PL": "Koniec wykresu pudełkowego - {0} IQR",
	      "nl-NL": "Einde box + {0} IQR",
	      "ko-KR": "상자 끝 + {0} IQR",
	      "pt-BR": "Fim da caixa + {0} IQR",
	      "fr-FR": "Fin de la boîte + {0} IQR",
	      "ja-JP": "ボックス終了 + {0} IQR",
	      "ru-RU": "Конец поля + {0} IQR"
	    }
	  },
	  "properties.boxplot.calculationMode.stdDev.elements.boxEnd": {
	    id: "properties.boxplot.calculationMode.stdDev.elements.boxEnd",
	    locale: {
	      "en-US": "Box middle + 1 standard deviation",
	      "zh-TW": "方塊中間 + 1 個標準差",
	      "zh-CN": "框中部 + 1 个标准偏差",
	      "tr-TR": "Kutu ortası + 1 standart sapma",
	      "sv-SE": "Rutans mitt + 1 standardavvikelse",
	      "it-IT": "Centro scatola + 1 deviazione standard",
	      "es-ES": "Mitad de la caja + 1 desviación estándar",
	      "de-DE": "Box-Mitte +1 Standardabweichung",
	      "pl-PL": "Środek wykresu pudełkowego + 1 odch. stand",
	      "nl-NL": "Midden box + 1 standaardafwijking",
	      "ko-KR": "상자 중간 + 1개 표준 편차",
	      "pt-BR": "Meio da caixa + 1 desvio padrão",
	      "fr-FR": "Milieu de la boîte + 1 écart type",
	      "ja-JP": "ボックス中間 + 1 標準偏差",
	      "ru-RU": "Середина поля + 1 стандартное отклонение"
	    }
	  },
	  "properties.boxplot.calculationMode.stdDev.elements.boxMiddle": {
	    id: "properties.boxplot.calculationMode.stdDev.elements.boxMiddle",
	    locale: {
	      "en-US": "Average",
	      "zh-TW": "平均值",
	      "zh-CN": "平均值",
	      "tr-TR": "Ortalama",
	      "sv-SE": "Medel",
	      "it-IT": "Media",
	      "es-ES": "Media",
	      "de-DE": "Durchschnitt",
	      "pl-PL": "Średnia",
	      "nl-NL": "Gemiddelde",
	      "ko-KR": "평균",
	      "pt-BR": "Média",
	      "fr-FR": "Moyenne",
	      "ja-JP": "平均値",
	      "ru-RU": "Среднее"
	    }
	  },
	  "properties.boxplot.calculationMode.stdDev.elements.boxStart": {
	    id: "properties.boxplot.calculationMode.stdDev.elements.boxStart",
	    locale: {
	      "en-US": "Box middle - 1 standard deviation",
	      "zh-TW": "方塊中間 - 1 個標準差",
	      "zh-CN": "框中部 - 1 个标准偏差",
	      "tr-TR": "Kutu ortası - 1 standart sapma",
	      "sv-SE": "Rutans mitt - 1 standardavvikelse",
	      "it-IT": "Centro scatola - 1 deviazione standard",
	      "es-ES": "Mitad de la caja - {1} desviación estándar",
	      "de-DE": "Box-Mitte -1 Standardabweichung",
	      "pl-PL": "Środek wykresu pudełkowego - 1 odch. stand",
	      "nl-NL": "Midden box - 1 standaardafwijking",
	      "ko-KR": "상자 중간 - 1개 표준 편차",
	      "pt-BR": "Середина поля - 1 стандартное отклонение",
	      "fr-FR": "Milieu de la boîte - 1 écart type",
	      "ja-JP": "ボックス中間 - 1 標準偏差",
	      "ru-RU": "Первый квартиль"
	    }
	  },
	  "properties.boxplot.calculationMode.stdDev.elements.firstWhisker": {
	    id: "properties.boxplot.calculationMode.stdDev.elements.firstWhisker",
	    locale: {
	      "en-US": "Box middle - {0} standard deviations",
	      "zh-TW": "方塊中間 - {0} 個標準差",
	      "zh-CN": "框中部 - {0} 个标准偏差",
	      "tr-TR": "Kutu ortası - {0} standart sapma",
	      "sv-SE": "Rutans mitt - {0} standardavvikelser",
	      "it-IT": "Centro scatola - {0} deviazioni standard",
	      "es-ES": "Mitad de la caja - {0} desviaciones estándar",
	      "de-DE": "Box-Mitte -{0} Standardabweichung",
	      "pl-PL": "Środek wykresu pudełkowego - {0} odch. stand",
	      "nl-NL": "Midden box - {0} standaardafwijkingen",
	      "ko-KR": "상자 중간 - {0}개 표준 편차",
	      "pt-BR": "Meio da caixa - {0} desvios padrão",
	      "fr-FR": "Milieu de la boîte - {0} écarts types",
	      "ja-JP": "ボックス中間 - {0} 標準偏差",
	      "ru-RU": "Середина поля - {0} стандартное(ых) отклонение(й)"
	    }
	  },
	  "properties.boxplot.calculationMode.stdDev.elements.lastWhisker": {
	    id: "properties.boxplot.calculationMode.stdDev.elements.lastWhisker",
	    locale: {
	      "en-US": "Box middle + {0} standard deviations",
	      "zh-TW": "方塊中間 + {0} 個標準差",
	      "zh-CN": "框中部 + {0} 个标准偏差",
	      "tr-TR": "Kutu ortası + {0} standart sapma",
	      "sv-SE": "Rutans mitt + {0} standardavvikelser",
	      "it-IT": "Centro scatola + {0} deviazioni standard",
	      "es-ES": "Mitad de la caja + {0} desviaciones estándar",
	      "de-DE": "Box-Mitte +{0} Standardabweichung",
	      "pl-PL": "Środek wykresu pudełkowego + {0} odch. stand",
	      "nl-NL": "Midden box + {0} standaardafwijkingen",
	      "ko-KR": "상자 중간 + {0}개 표준 편차",
	      "pt-BR": "Meio da caixa + {0} desvios padrão",
	      "fr-FR": "Milieu de la boîte + {0} écarts types",
	      "ja-JP": "ボックス中間 + {0} 標準偏差",
	      "ru-RU": "Середина поля + {0} стандартное(ых) отклонение(й)"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.boxEnd": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.boxEnd",
	    locale: {
	      "en-US": "Third quartile",
	      "zh-TW": "第三四分位數",
	      "zh-CN": "第 3 个四分位",
	      "tr-TR": "Üçüncü çeyrek",
	      "sv-SE": "Tredje kvartilen",
	      "it-IT": "Terzo quartile<",
	      "es-ES": "Tercer cuartil",
	      "de-DE": "Drittes Quartil",
	      "pl-PL": "Trzeci kwartyl",
	      "nl-NL": "Derde kwartiel",
	      "ko-KR": "3번째 사분위수",
	      "pt-BR": "Terceiro quartil",
	      "fr-FR": "Troisième quartile",
	      "ja-JP": "第 3 四分位数",
	      "ru-RU": "Третий квартиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.boxMiddle": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.boxMiddle",
	    locale: {
	      "en-US": "Median",
	      "zh-TW": "中位數",
	      "zh-CN": "中间值",
	      "tr-TR": "Medyan",
	      "sv-SE": "Median",
	      "it-IT": "Mediana",
	      "es-ES": "Mediana",
	      "de-DE": "Median",
	      "pl-PL": "Mediana",
	      "nl-NL": "Mediaan",
	      "ko-KR": "중앙값",
	      "pt-BR": "Mediano",
	      "fr-FR": "Médiane",
	      "ja-JP": "中央値",
	      "ru-RU": "Медианное"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.boxStart": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.boxStart",
	    locale: {
	      "en-US": "First quartile",
	      "zh-TW": "第一四分位數",
	      "zh-CN": "第 1 个四分位",
	      "tr-TR": "İlk çeyrek",
	      "sv-SE": "Första kvartilen",
	      "it-IT": "Primo quartile",
	      "es-ES": "Primer cuartil",
	      "de-DE": "Erstes Quartil",
	      "pl-PL": "Pierwszy kwartyl",
	      "nl-NL": "Eerste kwartiel",
	      "ko-KR": "1번째 사분위수",
	      "pt-BR": "Primeiro quartil",
	      "fr-FR": "Premier quartile",
	      "ja-JP": "第 1 四分位数",
	      "ru-RU": "Первый квартиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.fifth": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.fifth",
	    locale: {
	      "en-US": "5th percentile",
	      "zh-TW": "第 5 個百分位數",
	      "zh-CN": "第 5 个百分位",
	      "tr-TR": "5. yüzdebirlik",
	      "sv-SE": "5:e percentilen",
	      "it-IT": "5° percentile",
	      "es-ES": "5º percentil",
	      "de-DE": "5. Perzentil",
	      "pl-PL": "5. percentyl",
	      "nl-NL": "5e percentiel",
	      "ko-KR": "5번째 백분위수",
	      "pt-BR": "5º percentil",
	      "fr-FR": "5e centile",
	      "ja-JP": "5 番目のパーセンタイル",
	      "ru-RU": "5-й процентиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.first": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.first",
	    locale: {
	      "en-US": "1st percentile",
	      "zh-TW": "第 1 個百分位數",
	      "zh-CN": "第 1 个百分位",
	      "tr-TR": "1. yüzdebirlik",
	      "sv-SE": "1:e percentilen",
	      "it-IT": "1° percentile",
	      "es-ES": "1er percentil",
	      "de-DE": "1. Perzentil",
	      "pl-PL": "1. percentyl",
	      "nl-NL": "1e percentiel",
	      "ko-KR": "1번째 백분위수",
	      "pt-BR": "1º percentil",
	      "fr-FR": "1er centile",
	      "ja-JP": "1 番目のパーセンタイル",
	      "ru-RU": "1-й процентиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.min": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.min",
	    locale: {
	      "en-US": "Minimum",
	      "zh-TW": "最小",
	      "zh-CN": "最小值",
	      "tr-TR": "En az",
	      "sv-SE": "Min",
	      "it-IT": "Minimo",
	      "es-ES": "Mínimo",
	      "de-DE": "Minimum",
	      "pl-PL": "Minimum",
	      "nl-NL": "Minimum",
	      "ko-KR": "최소",
	      "pt-BR": "Mínimo",
	      "fr-FR": "Minimale",
	      "ja-JP": "最小値",
	      "ru-RU": "Минимум"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.tenth": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.firstWhisker.tenth",
	    locale: {
	      "en-US": "10th percentile",
	      "zh-TW": "第 10 個百分位數",
	      "zh-CN": "第 10 个百分位",
	      "tr-TR": "10. yüzdebirlik",
	      "sv-SE": "10:e percentilen",
	      "it-IT": "10° percentile",
	      "es-ES": "10º percentil",
	      "de-DE": "10. Perzentil",
	      "pl-PL": "10. percentyl",
	      "nl-NL": "10e percentiel",
	      "ko-KR": "10번째 백분위수",
	      "pt-BR": "10º percentil",
	      "fr-FR": "10e centile",
	      "ja-JP": "10 番目のパーセンタイル",
	      "ru-RU": "10-й процентиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.max": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.max",
	    locale: {
	      "en-US": "Maximum",
	      "zh-TW": "最大",
	      "zh-CN": "最大值",
	      "tr-TR": "En fazla",
	      "sv-SE": "Max",
	      "it-IT": "Massimo",
	      "es-ES": "Máximo",
	      "de-DE": "Maximum",
	      "pl-PL": "Maksimum",
	      "nl-NL": "Maximum",
	      "ko-KR": "최대",
	      "pt-BR": "Máximo",
	      "fr-FR": "Maximale",
	      "ja-JP": "最大値",
	      "ru-RU": "Максимум"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.ninetieth": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.ninetieth",
	    locale: {
	      "en-US": "90th percentile",
	      "zh-TW": "第 90 個百分位數",
	      "zh-CN": "第 90 个百分位",
	      "tr-TR": "90. yüzdebirlik",
	      "sv-SE": "90:e percentilen",
	      "it-IT": "90° percentile",
	      "es-ES": "90º percentil",
	      "de-DE": "90. Perzentil",
	      "pl-PL": "90. percentyl",
	      "nl-NL": "90e percentiel",
	      "ko-KR": "90번째 백분위수",
	      "pt-BR": "90º percentil",
	      "fr-FR": "90e centile",
	      "ja-JP": "90 番目の百分位数",
	      "ru-RU": "90-й процентиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.ninetyfifth": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.ninetyfifth",
	    locale: {
	      "en-US": "95th percentile",
	      "zh-TW": "第 95 個百分位數",
	      "zh-CN": "第 95 个百分位",
	      "tr-TR": "95. yüzdebirlik",
	      "sv-SE": "95:e percentilen",
	      "it-IT": "95° percentile",
	      "es-ES": "95º percentil",
	      "de-DE": "95. Perzentil",
	      "pl-PL": "95. percentyl",
	      "nl-NL": "95e percentiel",
	      "ko-KR": "95번째 백분위수",
	      "pt-BR": "95º percentil",
	      "fr-FR": "95e centile",
	      "ja-JP": "95 番目の百分位数",
	      "ru-RU": "95-й процентиль"
	    }
	  },
	  "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.ninetynineth": {
	    id: "properties.boxplot.calculationMode.fractiles.elements.lastWhisker.ninetynineth",
	    locale: {
	      "en-US": "99th percentile",
	      "zh-TW": "第 99 個百分位數",
	      "zh-CN": "第 99 个百分位",
	      "tr-TR": "99. yüzdebirlik",
	      "sv-SE": "99:e percentilen",
	      "it-IT": "99° percentile",
	      "es-ES": "99º percentil",
	      "de-DE": "99. Perzentil",
	      "pl-PL": "99. percentyl",
	      "nl-NL": "99e percentiel",
	      "ko-KR": "99번째 백분위수",
	      "pt-BR": "99º percentil",
	      "fr-FR": "99e centile",
	      "ja-JP": "99 番目の百分位数",
	      "ru-RU": "99-й процентиль"
	    }
	  }
	};

	function autoRegister(translator) {
	  if (translator && translator.get && translator.add) {
	    const t = 'Object.Disclaimer.LimitedData';
	    const g = translator.get(t);
	    // if translated string is different from its id
	    // assume translations already exists for current locale
	    if (g !== t) {
	      return;
	    }
	    Object.keys(all).forEach(key => {
	      translator.add(all[key]);
	    });
	  }
	}

	/*
	* picasso.js v2.8.2
	* Copyright (c) 2025 QlikTech International AB
	* Released under the MIT license.
	*/var hasOwn$1=Object.prototype.hasOwnProperty;var toStr$1=Object.prototype.toString;var defineProperty$1=Object.defineProperty;var gOPD$1=Object.getOwnPropertyDescriptor;var isArray$2=function isArray(arr){if(typeof Array.isArray==='function'){return Array.isArray(arr);}return toStr$1.call(arr)==='[object Array]';};var isPlainObject$1=function isPlainObject(obj){if(!obj||toStr$1.call(obj)!=='[object Object]'){return false;}var hasOwnConstructor=hasOwn$1.call(obj,'constructor');var hasIsPrototypeOf=obj.constructor&&obj.constructor.prototype&&hasOwn$1.call(obj.constructor.prototype,'isPrototypeOf');// Not own constructor property must be Object
	if(obj.constructor&&!hasOwnConstructor&&!hasIsPrototypeOf){return false;}// Own properties are enumerated firstly, so to speed up,
	// if last one is own, then all properties are own.
	var key;for(key in obj){/**/}return typeof key==='undefined'||hasOwn$1.call(obj,key);};// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
	var setProperty$1=function setProperty(target,options){if(defineProperty$1&&options.name==='__proto__'){defineProperty$1(target,options.name,{enumerable:true,configurable:true,value:options.newValue,writable:true});}else {target[options.name]=options.newValue;}};// Return undefined instead of __proto__ if '__proto__' is not an own property
	var getProperty$1=function getProperty(obj,name){if(name==='__proto__'){if(!hasOwn$1.call(obj,name)){return void 0;}else if(gOPD$1){// In early versions of node, obj['__proto__'] is buggy when obj has
	// __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
	return gOPD$1(obj,name).value;}}return obj[name];};var extend$1$1=function extend(){var options,name,src,copy,copyIsArray,clone;var target=arguments[0];var i=1;var length=arguments.length;var deep=false;// Handle a deep copy situation
	if(typeof target==='boolean'){deep=target;target=arguments[1]||{};// skip the boolean and the target
	i=2;}if(target==null||typeof target!=='object'&&typeof target!=='function'){target={};}for(;i<length;++i){options=arguments[i];// Only deal with non-null/undefined values
	if(options!=null){// Extend the base object
	for(name in options){src=getProperty$1(target,name);copy=getProperty$1(options,name);// Prevent never-ending loop
	if(target!==copy){// Recurse if we're merging plain objects or arrays
	if(deep&&copy&&(isPlainObject$1(copy)||(copyIsArray=isArray$2(copy)))){if(copyIsArray){copyIsArray=false;clone=src&&isArray$2(src)?src:[];}else {clone=src&&isPlainObject$1(src)?src:{};}// Never move original objects, clone them
	setProperty$1(target,{name:name,newValue:extend(deep,clone,copy)});// Don't bring in undefined values
	}else if(typeof copy!=='undefined'){setProperty$1(target,{name:name,newValue:copy});}}}}}// Return the modified object
	return target;};var about={version:'2.8.2'};function _defineProperty$1(e,r,t){return (r=_toPropertyKey$1(r))in e?Object.defineProperty(e,r,{value:t,enumerable:true,configurable:true,writable:true}):e[r]=t,e;}function ownKeys$1(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable;})),t.push.apply(t,o);}return t;}function _objectSpread2$1(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys$1(Object(t),true).forEach(function(r){_defineProperty$1(e,r,t[r]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys$1(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r));});}return e;}function _toPrimitive$1(t,r){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r);if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.");}return ("string"===r?String:Number)(t);}function _toPropertyKey$1(t){var i=_toPrimitive$1(t,"string");return "symbol"==typeof i?i:i+"";}/* global navigator */function detectTouchSupport(e){if('ontouchstart'in e&&'ontouchend'in e||navigator.maxTouchPoints>1){return true;}return false;}function isTouchEvent(e){return !!e.changedTouches;}function isValidTapEvent(e,eventInfo){const isTouch=isTouchEvent(e);const ee=isTouch?e.changedTouches[0]:e;const dt=Date.now()-eventInfo.time;const dx=isNaN(eventInfo.x)?0:Math.abs(ee.clientX-eventInfo.x);const dy=isNaN(eventInfo.y)?0:Math.abs(ee.clientY-eventInfo.y);return (e.button===0||isTouch)&&!eventInfo.multiTouch&&dx<=12&&dy<=12&&dt<=300;}function isNumber(v){return typeof v==='number'&&!isNaN(v);}function notNumber(value){return typeof value!=='number'||isNaN(value);}function getMinMax$1(points){const num=points.length;let xMin=NaN;let xMax=NaN;let yMin=NaN;let yMax=NaN;for(let i=0;i<num;i++){xMin=isNaN(xMin)?points[i].x:Math.min(xMin,points[i].x);xMax=isNaN(xMax)?points[i].x:Math.max(xMax,points[i].x);yMin=isNaN(yMin)?points[i].y:Math.min(yMin,points[i].y);yMax=isNaN(yMax)?points[i].y:Math.max(yMax,points[i].y);}return [xMin,yMin,xMax,yMax];}/**
	 * @ignore
	 * @param {oject} line
	 * @returns {Point[]} Array of points
	 */function lineToPoints(line){const x1=line.x1||0;const y1=line.y1||0;const x2=line.x2||0;const y2=line.y2||0;return [{x:x1,y:y1},{x:x2,y:y2}];}/**
	 * @ignore
	 * @param {oject} rect
	 * @returns {Point[]} Array of points
	 */function rectToPoints(rect){return [{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];}function pointsToRect(points){const[xMin,yMin,xMax,yMax]=getMinMax$1(points);return {x:xMin,y:yMin,width:xMax-xMin,height:yMax-yMin};}function pointsToCircle(points,r){return {cx:points[0].x,cy:points[0].y,r};}function pointsToLine(points){return {x1:points[0].x,y1:points[0].y,x2:points[1].x,y2:points[1].y};}/**
	 * @ignore
	 * @param {oject}
	 * @returns {string} Type of geometry
	 */function getShapeType(shape){const{x,y,// Point
	width,height,// Rect
	x1,x2,y1,y2,// Line
	cx,cy,r,// Circle
	vertices// Polygon or GeoPolygon
	}=shape||{};if(isNumber(cx)&&isNumber(cy)&&isNumber(r)){return 'circle';}if(isNumber(x1)&&isNumber(x2)&&isNumber(y1)&&isNumber(y2)){return 'line';}if(isNumber(x)&&isNumber(y)&&isNumber(width)&&isNumber(height)){return 'rect';}if(isNumber(x)&&isNumber(y)){return 'point';}if(Array.isArray(vertices)){return vertices.every(item=>Array.isArray(item))?'geopolygon':'polygon';}return null;}function expandRect(size,rect){return {x:rect.x-size,y:rect.y-size,width:rect.width+size,height:rect.height+size};}// import types from './types';
	/**
	 * @ignore
	 * @param {Array<DataSource>} dataSources
	 * @param {any} { logger }
	 * @returns {function}
	 */function datasets(dataSources,_ref){let{types,logger}=_ref;const data={};const sets=[];if(!Array.isArray(dataSources)){logger.warn('Deprecated: "data-source" configuration"');sets.push(dataSources);}else {sets.push(...dataSources);}sets.forEach((d,i)=>{let datasetFactory=types(d.type);if(datasetFactory){let key=d.key;if(typeof d.key==='undefined'){logger.warn("Missing key for dataset. Using index '".concat(i,"' as key."));key=i;}let dataset=datasetFactory({key,data:d.data,config:d.config});data[key]=dataset;}});/**
	   * Returns the `dataset` which has `key` as identifier
	   * @ignore
	   * @param {string} key - The dataset identifier
	   * @returns {Dataset}
	   */const fn=key=>{if(key){return data[key];}return data[Object.keys(data)[0]];};return fn;}/**
	 * @typedef {object} DataSource
	 * @property {string=} key - Unique identifier for this data source
	 * @property {string} type - The dataset type
	 * @property {any} data - Data
	 */var pi$1=Math.PI,tau$1=2*pi$1,epsilon$1=1e-6,tauEpsilon=tau$1-epsilon$1;function Path$1(){this._x0=this._y0=// start of current subpath
	this._x1=this._y1=null;// end of current subpath
	this._="";}function path(){return new Path$1();}Path$1.prototype=path.prototype={constructor:Path$1,moveTo:function(x,y){this._+="M"+(this._x0=this._x1=+x)+","+(this._y0=this._y1=+y);},closePath:function(){if(this._x1!==null){this._x1=this._x0,this._y1=this._y0;this._+="Z";}},lineTo:function(x,y){this._+="L"+(this._x1=+x)+","+(this._y1=+y);},quadraticCurveTo:function(x1,y1,x,y){this._+="Q"+ +x1+","+ +y1+","+(this._x1=+x)+","+(this._y1=+y);},bezierCurveTo:function(x1,y1,x2,y2,x,y){this._+="C"+ +x1+","+ +y1+","+ +x2+","+ +y2+","+(this._x1=+x)+","+(this._y1=+y);},arcTo:function(x1,y1,x2,y2,r){x1=+x1,y1=+y1,x2=+x2,y2=+y2,r=+r;var x0=this._x1,y0=this._y1,x21=x2-x1,y21=y2-y1,x01=x0-x1,y01=y0-y1,l01_2=x01*x01+y01*y01;// Is the radius negative? Error.
	if(r<0)throw new Error("negative radius: "+r);// Is this path empty? Move to (x1,y1).
	if(this._x1===null){this._+="M"+(this._x1=x1)+","+(this._y1=y1);}// Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
	else if(!(l01_2>epsilon$1));// Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
	// Equivalently, is (x1,y1) coincident with (x2,y2)?
	// Or, is the radius zero? Line to (x1,y1).
	else if(!(Math.abs(y01*x21-y21*x01)>epsilon$1)||!r){this._+="L"+(this._x1=x1)+","+(this._y1=y1);}// Otherwise, draw an arc!
	else {var x20=x2-x0,y20=y2-y0,l21_2=x21*x21+y21*y21,l20_2=x20*x20+y20*y20,l21=Math.sqrt(l21_2),l01=Math.sqrt(l01_2),l=r*Math.tan((pi$1-Math.acos((l21_2+l01_2-l20_2)/(2*l21*l01)))/2),t01=l/l01,t21=l/l21;// If the start tangent is not coincident with (x0,y0), line to.
	if(Math.abs(t01-1)>epsilon$1){this._+="L"+(x1+t01*x01)+","+(y1+t01*y01);}this._+="A"+r+","+r+",0,0,"+ +(y01*x20>x01*y20)+","+(this._x1=x1+t21*x21)+","+(this._y1=y1+t21*y21);}},arc:function(x,y,r,a0,a1,ccw){x=+x,y=+y,r=+r,ccw=!!ccw;var dx=r*Math.cos(a0),dy=r*Math.sin(a0),x0=x+dx,y0=y+dy,cw=1^ccw,da=ccw?a0-a1:a1-a0;// Is the radius negative? Error.
	if(r<0)throw new Error("negative radius: "+r);// Is this path empty? Move to (x0,y0).
	if(this._x1===null){this._+="M"+x0+","+y0;}// Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
	else if(Math.abs(this._x1-x0)>epsilon$1||Math.abs(this._y1-y0)>epsilon$1){this._+="L"+x0+","+y0;}// Is this arc empty? We’re done.
	if(!r)return;// Does the angle go the wrong way? Flip the direction.
	if(da<0)da=da%tau$1+tau$1;// Is this a complete circle? Draw two arcs to complete the circle.
	if(da>tauEpsilon){this._+="A"+r+","+r+",0,1,"+cw+","+(x-dx)+","+(y-dy)+"A"+r+","+r+",0,1,"+cw+","+(this._x1=x0)+","+(this._y1=y0);}// Is this arc non-empty? Draw an arc!
	else if(da>epsilon$1){this._+="A"+r+","+r+",0,"+ +(da>=pi$1)+","+cw+","+(this._x1=x+r*Math.cos(a1))+","+(this._y1=y+r*Math.sin(a1));}},rect:function(x,y,w,h){this._+="M"+(this._x0=this._x1=+x)+","+(this._y0=this._y1=+y)+"h"+ +w+"v"+ +h+"h"+-w+"Z";},toString:function(){return this._;}};function constant$2(x){return function constant(){return x;};}var abs=Math.abs;var atan2=Math.atan2;var cos=Math.cos;var max=Math.max;var min=Math.min;var sin=Math.sin;var sqrt=Math.sqrt;var epsilon=1e-12;var pi=Math.PI;var halfPi=pi/2;var tau=2*pi;function acos(x){return x>1?0:x<-1?pi:Math.acos(x);}function asin(x){return x>=1?halfPi:x<=-1?-halfPi:Math.asin(x);}function arcInnerRadius(d){return d.innerRadius;}function arcOuterRadius(d){return d.outerRadius;}function arcStartAngle(d){return d.startAngle;}function arcEndAngle(d){return d.endAngle;}function arcPadAngle(d){return d&&d.padAngle;// Note: optional!
	}function intersect(x0,y0,x1,y1,x2,y2,x3,y3){var x10=x1-x0,y10=y1-y0,x32=x3-x2,y32=y3-y2,t=y32*x10-x32*y10;if(t*t<epsilon)return;t=(x32*(y0-y2)-y32*(x0-x2))/t;return [x0+t*x10,y0+t*y10];}// Compute perpendicular offset line of length rc.
	// http://mathworld.wolfram.com/Circle-LineIntersection.html
	function cornerTangents(x0,y0,x1,y1,r1,rc,cw){var x01=x0-x1,y01=y0-y1,lo=(cw?rc:-rc)/sqrt(x01*x01+y01*y01),ox=lo*y01,oy=-lo*x01,x11=x0+ox,y11=y0+oy,x10=x1+ox,y10=y1+oy,x00=(x11+x10)/2,y00=(y11+y10)/2,dx=x10-x11,dy=y10-y11,d2=dx*dx+dy*dy,r=r1-rc,D=x11*y10-x10*y11,d=(dy<0?-1:1)*sqrt(max(0,r*r*d2-D*D)),cx0=(D*dy-dx*d)/d2,cy0=(-D*dx-dy*d)/d2,cx1=(D*dy+dx*d)/d2,cy1=(-D*dx+dy*d)/d2,dx0=cx0-x00,dy0=cy0-y00,dx1=cx1-x00,dy1=cy1-y00;// Pick the closer of the two intersection points.
	// TODO Is there a faster way to determine which intersection to use?
	if(dx0*dx0+dy0*dy0>dx1*dx1+dy1*dy1)cx0=cx1,cy0=cy1;return {cx:cx0,cy:cy0,x01:-ox,y01:-oy,x11:cx0*(r1/r-1),y11:cy0*(r1/r-1)};}function arc(){var innerRadius=arcInnerRadius,outerRadius=arcOuterRadius,cornerRadius=constant$2(0),padRadius=null,startAngle=arcStartAngle,endAngle=arcEndAngle,padAngle=arcPadAngle,context=null;function arc(){var buffer,r,r0=+innerRadius.apply(this,arguments),r1=+outerRadius.apply(this,arguments),a0=startAngle.apply(this,arguments)-halfPi,a1=endAngle.apply(this,arguments)-halfPi,da=abs(a1-a0),cw=a1>a0;if(!context)context=buffer=path();// Ensure that the outer radius is always larger than the inner radius.
	if(r1<r0)r=r1,r1=r0,r0=r;// Is it a point?
	if(!(r1>epsilon))context.moveTo(0,0);// Or is it a circle or annulus?
	else if(da>tau-epsilon){context.moveTo(r1*cos(a0),r1*sin(a0));context.arc(0,0,r1,a0,a1,!cw);if(r0>epsilon){context.moveTo(r0*cos(a1),r0*sin(a1));context.arc(0,0,r0,a1,a0,cw);}}// Or is it a circular or annular sector?
	else {var a01=a0,a11=a1,a00=a0,a10=a1,da0=da,da1=da,ap=padAngle.apply(this,arguments)/2,rp=ap>epsilon&&(padRadius?+padRadius.apply(this,arguments):sqrt(r0*r0+r1*r1)),rc=min(abs(r1-r0)/2,+cornerRadius.apply(this,arguments)),rc0=rc,rc1=rc,t0,t1;// Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
	if(rp>epsilon){var p0=asin(rp/r0*sin(ap)),p1=asin(rp/r1*sin(ap));if((da0-=p0*2)>epsilon)p0*=cw?1:-1,a00+=p0,a10-=p0;else da0=0,a00=a10=(a0+a1)/2;if((da1-=p1*2)>epsilon)p1*=cw?1:-1,a01+=p1,a11-=p1;else da1=0,a01=a11=(a0+a1)/2;}var x01=r1*cos(a01),y01=r1*sin(a01),x10=r0*cos(a10),y10=r0*sin(a10);// Apply rounded corners?
	if(rc>epsilon){var x11=r1*cos(a11),y11=r1*sin(a11),x00=r0*cos(a00),y00=r0*sin(a00),oc;// Restrict the corner radius according to the sector angle.
	if(da<pi&&(oc=intersect(x01,y01,x00,y00,x11,y11,x10,y10))){var ax=x01-oc[0],ay=y01-oc[1],bx=x11-oc[0],by=y11-oc[1],kc=1/sin(acos((ax*bx+ay*by)/(sqrt(ax*ax+ay*ay)*sqrt(bx*bx+by*by)))/2),lc=sqrt(oc[0]*oc[0]+oc[1]*oc[1]);rc0=min(rc,(r0-lc)/(kc-1));rc1=min(rc,(r1-lc)/(kc+1));}}// Is the sector collapsed to a line?
	if(!(da1>epsilon))context.moveTo(x01,y01);// Does the sector’s outer ring have rounded corners?
	else if(rc1>epsilon){t0=cornerTangents(x00,y00,x01,y01,r1,rc1,cw);t1=cornerTangents(x11,y11,x10,y10,r1,rc1,cw);context.moveTo(t0.cx+t0.x01,t0.cy+t0.y01);// Have the corners merged?
	if(rc1<rc)context.arc(t0.cx,t0.cy,rc1,atan2(t0.y01,t0.x01),atan2(t1.y01,t1.x01),!cw);// Otherwise, draw the two corners and the ring.
	else {context.arc(t0.cx,t0.cy,rc1,atan2(t0.y01,t0.x01),atan2(t0.y11,t0.x11),!cw);context.arc(0,0,r1,atan2(t0.cy+t0.y11,t0.cx+t0.x11),atan2(t1.cy+t1.y11,t1.cx+t1.x11),!cw);context.arc(t1.cx,t1.cy,rc1,atan2(t1.y11,t1.x11),atan2(t1.y01,t1.x01),!cw);}}// Or is the outer ring just a circular arc?
	else context.moveTo(x01,y01),context.arc(0,0,r1,a01,a11,!cw);// Is there no inner ring, and it’s a circular sector?
	// Or perhaps it’s an annular sector collapsed due to padding?
	if(!(r0>epsilon)||!(da0>epsilon))context.lineTo(x10,y10);// Does the sector’s inner ring (or point) have rounded corners?
	else if(rc0>epsilon){t0=cornerTangents(x10,y10,x11,y11,r0,-rc0,cw);t1=cornerTangents(x01,y01,x00,y00,r0,-rc0,cw);context.lineTo(t0.cx+t0.x01,t0.cy+t0.y01);// Have the corners merged?
	if(rc0<rc)context.arc(t0.cx,t0.cy,rc0,atan2(t0.y01,t0.x01),atan2(t1.y01,t1.x01),!cw);// Otherwise, draw the two corners and the ring.
	else {context.arc(t0.cx,t0.cy,rc0,atan2(t0.y01,t0.x01),atan2(t0.y11,t0.x11),!cw);context.arc(0,0,r0,atan2(t0.cy+t0.y11,t0.cx+t0.x11),atan2(t1.cy+t1.y11,t1.cx+t1.x11),cw);context.arc(t1.cx,t1.cy,rc0,atan2(t1.y11,t1.x11),atan2(t1.y01,t1.x01),!cw);}}// Or is the inner ring just a circular arc?
	else context.arc(0,0,r0,a10,a00,cw);}context.closePath();if(buffer)return context=null,buffer+""||null;}arc.centroid=function(){var r=(+innerRadius.apply(this,arguments)+ +outerRadius.apply(this,arguments))/2,a=(+startAngle.apply(this,arguments)+ +endAngle.apply(this,arguments))/2-pi/2;return [cos(a)*r,sin(a)*r];};arc.innerRadius=function(_){return arguments.length?(innerRadius=typeof _==="function"?_:constant$2(+_),arc):innerRadius;};arc.outerRadius=function(_){return arguments.length?(outerRadius=typeof _==="function"?_:constant$2(+_),arc):outerRadius;};arc.cornerRadius=function(_){return arguments.length?(cornerRadius=typeof _==="function"?_:constant$2(+_),arc):cornerRadius;};arc.padRadius=function(_){return arguments.length?(padRadius=_==null?null:typeof _==="function"?_:constant$2(+_),arc):padRadius;};arc.startAngle=function(_){return arguments.length?(startAngle=typeof _==="function"?_:constant$2(+_),arc):startAngle;};arc.endAngle=function(_){return arguments.length?(endAngle=typeof _==="function"?_:constant$2(+_),arc):endAngle;};arc.padAngle=function(_){return arguments.length?(padAngle=typeof _==="function"?_:constant$2(+_),arc):padAngle;};arc.context=function(_){return arguments.length?(context=_==null?null:_,arc):context;};return arc;}function Linear(context){this._context=context;}Linear.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._point=0;},lineEnd:function(){if(this._line||this._line!==0&&this._point===1)this._context.closePath();this._line=1-this._line;},point:function(x,y){x=+x,y=+y;switch(this._point){case 0:this._point=1;this._line?this._context.lineTo(x,y):this._context.moveTo(x,y);break;case 1:this._point=2;// proceed
	default:this._context.lineTo(x,y);break;}}};function curveLinear(context){return new Linear(context);}function x$1(p){return p[0];}function y$1(p){return p[1];}function line$2(){var x=x$1,y=y$1,defined=constant$2(true),context=null,curve=curveLinear,output=null;function line(data){var i,n=data.length,d,defined0=false,buffer;if(context==null)output=curve(buffer=path());for(i=0;i<=n;++i){if(!(i<n&&defined(d=data[i],i,data))===defined0){if(defined0=!defined0)output.lineStart();else output.lineEnd();}if(defined0)output.point(+x(d,i,data),+y(d,i,data));}if(buffer)return output=null,buffer+""||null;}line.x=function(_){return arguments.length?(x=typeof _==="function"?_:constant$2(+_),line):x;};line.y=function(_){return arguments.length?(y=typeof _==="function"?_:constant$2(+_),line):y;};line.defined=function(_){return arguments.length?(defined=typeof _==="function"?_:constant$2(!!_),line):defined;};line.curve=function(_){return arguments.length?(curve=_,context!=null&&(output=curve(context)),line):curve;};line.context=function(_){return arguments.length?(_==null?context=output=null:output=curve(context=_),line):context;};return line;}function area(){var x0=x$1,x1=null,y0=constant$2(0),y1=y$1,defined=constant$2(true),context=null,curve=curveLinear,output=null;function area(data){var i,j,k,n=data.length,d,defined0=false,buffer,x0z=new Array(n),y0z=new Array(n);if(context==null)output=curve(buffer=path());for(i=0;i<=n;++i){if(!(i<n&&defined(d=data[i],i,data))===defined0){if(defined0=!defined0){j=i;output.areaStart();output.lineStart();}else {output.lineEnd();output.lineStart();for(k=i-1;k>=j;--k){output.point(x0z[k],y0z[k]);}output.lineEnd();output.areaEnd();}}if(defined0){x0z[i]=+x0(d,i,data),y0z[i]=+y0(d,i,data);output.point(x1?+x1(d,i,data):x0z[i],y1?+y1(d,i,data):y0z[i]);}}if(buffer)return output=null,buffer+""||null;}function arealine(){return line$2().defined(defined).curve(curve).context(context);}area.x=function(_){return arguments.length?(x0=typeof _==="function"?_:constant$2(+_),x1=null,area):x0;};area.x0=function(_){return arguments.length?(x0=typeof _==="function"?_:constant$2(+_),area):x0;};area.x1=function(_){return arguments.length?(x1=_==null?null:typeof _==="function"?_:constant$2(+_),area):x1;};area.y=function(_){return arguments.length?(y0=typeof _==="function"?_:constant$2(+_),y1=null,area):y0;};area.y0=function(_){return arguments.length?(y0=typeof _==="function"?_:constant$2(+_),area):y0;};area.y1=function(_){return arguments.length?(y1=_==null?null:typeof _==="function"?_:constant$2(+_),area):y1;};area.lineX0=area.lineY0=function(){return arealine().x(x0).y(y0);};area.lineY1=function(){return arealine().x(x0).y(y1);};area.lineX1=function(){return arealine().x(x1).y(y0);};area.defined=function(_){return arguments.length?(defined=typeof _==="function"?_:constant$2(!!_),area):defined;};area.curve=function(_){return arguments.length?(curve=_,context!=null&&(output=curve(context)),area):curve;};area.context=function(_){return arguments.length?(_==null?context=output=null:output=curve(context=_),area):context;};return area;}function descending$1(a,b){return b<a?-1:b>a?1:b>=a?0:NaN;}function identity$2(d){return d;}function pie$1(){var value=identity$2,sortValues=descending$1,sort=null,startAngle=constant$2(0),endAngle=constant$2(tau),padAngle=constant$2(0);function pie(data){var i,n=data.length,j,k,sum=0,index=new Array(n),arcs=new Array(n),a0=+startAngle.apply(this,arguments),da=Math.min(tau,Math.max(-tau,endAngle.apply(this,arguments)-a0)),a1,p=Math.min(Math.abs(da)/n,padAngle.apply(this,arguments)),pa=p*(da<0?-1:1),v;for(i=0;i<n;++i){if((v=arcs[index[i]=i]=+value(data[i],i,data))>0){sum+=v;}}// Optionally sort the arcs by previously-computed values or by data.
	if(sortValues!=null)index.sort(function(i,j){return sortValues(arcs[i],arcs[j]);});else if(sort!=null)index.sort(function(i,j){return sort(data[i],data[j]);});// Compute the arcs! They are stored in the original data's order.
	for(i=0,k=sum?(da-n*pa)/sum:0;i<n;++i,a0=a1){j=index[i],v=arcs[j],a1=a0+(v>0?v*k:0)+pa,arcs[j]={data:data[j],index:i,value:v,startAngle:a0,endAngle:a1,padAngle:p};}return arcs;}pie.value=function(_){return arguments.length?(value=typeof _==="function"?_:constant$2(+_),pie):value;};pie.sortValues=function(_){return arguments.length?(sortValues=_,sort=null,pie):sortValues;};pie.sort=function(_){return arguments.length?(sort=_,sortValues=null,pie):sort;};pie.startAngle=function(_){return arguments.length?(startAngle=typeof _==="function"?_:constant$2(+_),pie):startAngle;};pie.endAngle=function(_){return arguments.length?(endAngle=typeof _==="function"?_:constant$2(+_),pie):endAngle;};pie.padAngle=function(_){return arguments.length?(padAngle=typeof _==="function"?_:constant$2(+_),pie):padAngle;};return pie;}var slice=Array.prototype.slice;function point$3(that,x,y){that._context.bezierCurveTo((2*that._x0+that._x1)/3,(2*that._y0+that._y1)/3,(that._x0+2*that._x1)/3,(that._y0+2*that._y1)/3,(that._x0+4*that._x1+x)/6,(that._y0+4*that._y1+y)/6);}function Basis(context){this._context=context;}Basis.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN;this._point=0;},lineEnd:function(){switch(this._point){case 3:point$3(this,this._x1,this._y1);// proceed
	case 2:this._context.lineTo(this._x1,this._y1);break;}if(this._line||this._line!==0&&this._point===1)this._context.closePath();this._line=1-this._line;},point:function(x,y){x=+x,y=+y;switch(this._point){case 0:this._point=1;this._line?this._context.lineTo(x,y):this._context.moveTo(x,y);break;case 1:this._point=2;break;case 2:this._point=3;this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);// proceed
	default:point$3(this,x,y);break;}this._x0=this._x1,this._x1=x;this._y0=this._y1,this._y1=y;}};function curveBasis(context){return new Basis(context);}function point$2(that,x,y){that._context.bezierCurveTo(that._x1+that._k*(that._x2-that._x0),that._y1+that._k*(that._y2-that._y0),that._x2+that._k*(that._x1-x),that._y2+that._k*(that._y1-y),that._x2,that._y2);}function Cardinal(context,tension){this._context=context;this._k=(1-tension)/6;}Cardinal.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN;this._point=0;},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:point$2(this,this._x1,this._y1);break;}if(this._line||this._line!==0&&this._point===1)this._context.closePath();this._line=1-this._line;},point:function(x,y){x=+x,y=+y;switch(this._point){case 0:this._point=1;this._line?this._context.lineTo(x,y):this._context.moveTo(x,y);break;case 1:this._point=2;this._x1=x,this._y1=y;break;case 2:this._point=3;// proceed
	default:point$2(this,x,y);break;}this._x0=this._x1,this._x1=this._x2,this._x2=x;this._y0=this._y1,this._y1=this._y2,this._y2=y;}};var curveCardinal=function custom(tension){function cardinal(context){return new Cardinal(context,tension);}cardinal.tension=function(tension){return custom(+tension);};return cardinal;}(0);function point$1(that,x,y){var x1=that._x1,y1=that._y1,x2=that._x2,y2=that._y2;if(that._l01_a>epsilon){var a=2*that._l01_2a+3*that._l01_a*that._l12_a+that._l12_2a,n=3*that._l01_a*(that._l01_a+that._l12_a);x1=(x1*a-that._x0*that._l12_2a+that._x2*that._l01_2a)/n;y1=(y1*a-that._y0*that._l12_2a+that._y2*that._l01_2a)/n;}if(that._l23_a>epsilon){var b=2*that._l23_2a+3*that._l23_a*that._l12_a+that._l12_2a,m=3*that._l23_a*(that._l23_a+that._l12_a);x2=(x2*b+that._x1*that._l23_2a-x*that._l12_2a)/m;y2=(y2*b+that._y1*that._l23_2a-y*that._l12_2a)/m;}that._context.bezierCurveTo(x1,y1,x2,y2,that._x2,that._y2);}function CatmullRom(context,alpha){this._context=context;this._alpha=alpha;}CatmullRom.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN;this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0;},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break;}if(this._line||this._line!==0&&this._point===1)this._context.closePath();this._line=1-this._line;},point:function(x,y){x=+x,y=+y;if(this._point){var x23=this._x2-x,y23=this._y2-y;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha));}switch(this._point){case 0:this._point=1;this._line?this._context.lineTo(x,y):this._context.moveTo(x,y);break;case 1:this._point=2;break;case 2:this._point=3;// proceed
	default:point$1(this,x,y);break;}this._l01_a=this._l12_a,this._l12_a=this._l23_a;this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a;this._x0=this._x1,this._x1=this._x2,this._x2=x;this._y0=this._y1,this._y1=this._y2,this._y2=y;}};var curveCatmullRom=function custom(alpha){function catmullRom(context){return alpha?new CatmullRom(context,alpha):new Cardinal(context,0);}catmullRom.alpha=function(alpha){return custom(+alpha);};return catmullRom;}(0.5);function sign(x){return x<0?-1:1;}// Calculate the slopes of the tangents (Hermite-type interpolation) based on
	// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
	// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
	// NOV(II), P. 443, 1990.
	function slope3(that,x2,y2){var h0=that._x1-that._x0,h1=x2-that._x1,s0=(that._y1-that._y0)/(h0||h1<0&&-0),s1=(y2-that._y1)/(h1||h0<0&&-0),p=(s0*h1+s1*h0)/(h0+h1);return (sign(s0)+sign(s1))*Math.min(Math.abs(s0),Math.abs(s1),0.5*Math.abs(p))||0;}// Calculate a one-sided slope.
	function slope2(that,t){var h=that._x1-that._x0;return h?(3*(that._y1-that._y0)/h-t)/2:t;}// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
	// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
	// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
	function point(that,t0,t1){var x0=that._x0,y0=that._y0,x1=that._x1,y1=that._y1,dx=(x1-x0)/3;that._context.bezierCurveTo(x0+dx,y0+dx*t0,x1-dx,y1-dx*t1,x1,y1);}function MonotoneX(context){this._context=context;}MonotoneX.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN;this._point=0;},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:point(this,this._t0,slope2(this,this._t0));break;}if(this._line||this._line!==0&&this._point===1)this._context.closePath();this._line=1-this._line;},point:function(x,y){var t1=NaN;x=+x,y=+y;if(x===this._x1&&y===this._y1)return;// Ignore coincident points.
	switch(this._point){case 0:this._point=1;this._line?this._context.lineTo(x,y):this._context.moveTo(x,y);break;case 1:this._point=2;break;case 2:this._point=3;point(this,slope2(this,t1=slope3(this,x,y)),t1);break;default:point(this,this._t0,t1=slope3(this,x,y));break;}this._x0=this._x1,this._x1=x;this._y0=this._y1,this._y1=y;this._t0=t1;}};function MonotoneY(context){this._context=new ReflectContext(context);}(MonotoneY.prototype=Object.create(MonotoneX.prototype)).point=function(x,y){MonotoneX.prototype.point.call(this,y,x);};function ReflectContext(context){this._context=context;}ReflectContext.prototype={moveTo:function(x,y){this._context.moveTo(y,x);},closePath:function(){this._context.closePath();},lineTo:function(x,y){this._context.lineTo(y,x);},bezierCurveTo:function(x1,y1,x2,y2,x,y){this._context.bezierCurveTo(y1,x1,y2,x2,y,x);}};function monotoneX(context){return new MonotoneX(context);}function monotoneY(context){return new MonotoneY(context);}function Natural(context){this._context=context;}Natural.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x=[];this._y=[];},lineEnd:function(){var x=this._x,y=this._y,n=x.length;if(n){this._line?this._context.lineTo(x[0],y[0]):this._context.moveTo(x[0],y[0]);if(n===2){this._context.lineTo(x[1],y[1]);}else {var px=controlPoints(x),py=controlPoints(y);for(var i0=0,i1=1;i1<n;++i0,++i1){this._context.bezierCurveTo(px[0][i0],py[0][i0],px[1][i0],py[1][i0],x[i1],y[i1]);}}}if(this._line||this._line!==0&&n===1)this._context.closePath();this._line=1-this._line;this._x=this._y=null;},point:function(x,y){this._x.push(+x);this._y.push(+y);}};// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
	function controlPoints(x){var i,n=x.length-1,m,a=new Array(n),b=new Array(n),r=new Array(n);a[0]=0,b[0]=2,r[0]=x[0]+2*x[1];for(i=1;i<n-1;++i)a[i]=1,b[i]=4,r[i]=4*x[i]+2*x[i+1];a[n-1]=2,b[n-1]=7,r[n-1]=8*x[n-1]+x[n];for(i=1;i<n;++i)m=a[i]/b[i-1],b[i]-=m,r[i]-=m*r[i-1];a[n-1]=r[n-1]/b[n-1];for(i=n-2;i>=0;--i)a[i]=(r[i]-a[i+1])/b[i];b[n-1]=(x[n]+a[n-1])/2;for(i=0;i<n-1;++i)b[i]=2*x[i+1]-a[i+1];return [a,b];}function curveNatural(context){return new Natural(context);}function Step(context,t){this._context=context;this._t=t;}Step.prototype={areaStart:function(){this._line=0;},areaEnd:function(){this._line=NaN;},lineStart:function(){this._x=this._y=NaN;this._point=0;},lineEnd:function(){if(0<this._t&&this._t<1&&this._point===2)this._context.lineTo(this._x,this._y);if(this._line||this._line!==0&&this._point===1)this._context.closePath();if(this._line>=0)this._t=1-this._t,this._line=1-this._line;},point:function(x,y){x=+x,y=+y;switch(this._point){case 0:this._point=1;this._line?this._context.lineTo(x,y):this._context.moveTo(x,y);break;case 1:this._point=2;// proceed
	default:{if(this._t<=0){this._context.lineTo(this._x,y);this._context.lineTo(x,y);}else {var x1=this._x*(1-this._t)+x*this._t;this._context.lineTo(x1,this._y);this._context.lineTo(x1,y);}break;}}this._x=x,this._y=y;}};function curveStep(context){return new Step(context,0.5);}function stepBefore(context){return new Step(context,0);}function stepAfter(context){return new Step(context,1);}function stackOffsetNone(series,order){if(!((n=series.length)>1))return;for(var i=1,j,s0,s1=series[order[0]],n,m=s1.length;i<n;++i){s0=s1,s1=series[order[i]];for(j=0;j<m;++j){s1[j][1]+=s1[j][0]=isNaN(s0[j][1])?s0[j][0]:s0[j][1];}}}function stackOrderNone(series){var n=series.length,o=new Array(n);while(--n>=0)o[n]=n;return o;}function stackValue(d,key){return d[key];}function stack(){var keys=constant$2([]),order=stackOrderNone,offset=stackOffsetNone,value=stackValue;function stack(data){var kz=keys.apply(this,arguments),i,m=data.length,n=kz.length,sz=new Array(n),oz;for(i=0;i<n;++i){for(var ki=kz[i],si=sz[i]=new Array(m),j=0,sij;j<m;++j){si[j]=sij=[0,+value(data[j],ki,j,data)];sij.data=data[j];}si.key=ki;}for(i=0,oz=order(sz);i<n;++i){sz[oz[i]].index=i;}offset(sz,oz);return sz;}stack.keys=function(_){return arguments.length?(keys=typeof _==="function"?_:constant$2(slice.call(_)),stack):keys;};stack.value=function(_){return arguments.length?(value=typeof _==="function"?_:constant$2(+_),stack):value;};stack.order=function(_){return arguments.length?(order=_==null?stackOrderNone:typeof _==="function"?_:constant$2(slice.call(_)),stack):order;};stack.offset=function(_){return arguments.length?(offset=_==null?stackOffsetNone:_,stack):offset;};return stack;}function stackOffsetExpand(series,order){if(!((n=series.length)>0))return;for(var i,n,j=0,m=series[0].length,y;j<m;++j){for(y=i=0;i<n;++i)y+=series[i][j][1]||0;if(y)for(i=0;i<n;++i)series[i][j][1]/=y;}stackOffsetNone(series,order);}function stackOffsetDiverging(series,order){if(!((n=series.length)>0))return;for(var i,j=0,d,dy,yp,yn,n,m=series[order[0]].length;j<m;++j){for(yp=yn=0,i=0;i<n;++i){if((dy=(d=series[order[i]][j])[1]-d[0])>=0){d[0]=yp,d[1]=yp+=dy;}else if(dy<0){d[1]=yn,d[0]=yn+=dy;}else {d[0]=yp;}}}}function stackOffsetSilhouette(series,order){if(!((n=series.length)>0))return;for(var j=0,s0=series[order[0]],n,m=s0.length;j<m;++j){for(var i=0,y=0;i<n;++i)y+=series[i][j][1]||0;s0[j][1]+=s0[j][0]=-y/2;}stackOffsetNone(series,order);}function stackOffsetWiggle(series,order){if(!((n=series.length)>0)||!((m=(s0=series[order[0]]).length)>0))return;for(var y=0,j=1,s0,m,n;j<m;++j){for(var i=0,s1=0,s2=0;i<n;++i){var si=series[order[i]],sij0=si[j][1]||0,sij1=si[j-1][1]||0,s3=(sij0-sij1)/2;for(var k=0;k<i;++k){var sk=series[order[k]],skj0=sk[j][1]||0,skj1=sk[j-1][1]||0;s3+=skj0-skj1;}s1+=sij0,s2+=s3*sij0;}s0[j-1][1]+=s0[j-1][0]=y;if(s1)y-=s2/s1;}s0[j-1][1]+=s0[j-1][0]=y;stackOffsetNone(series,order);}function appearance(series){var peaks=series.map(peak);return stackOrderNone(series).sort(function(a,b){return peaks[a]-peaks[b];});}function peak(series){var i=-1,j=0,n=series.length,vi,vj=-Infinity;while(++i<n)if((vi=+series[i][1])>vj)vj=vi,j=i;return j;}function stackOrderAscending(series){var sums=series.map(sum);return stackOrderNone(series).sort(function(a,b){return sums[a]-sums[b];});}function sum(series){var s=0,i=-1,n=series.length,v;while(++i<n)if(v=+series[i][1])s+=v;return s;}function stackOrderInsideOut(series){var n=series.length,i,j,sums=series.map(sum),order=appearance(series),top=0,bottom=0,tops=[],bottoms=[];for(i=0;i<n;++i){j=order[i];if(top<bottom){top+=sums[j];tops.push(j);}else {bottom+=sums[j];bottoms.push(j);}}return bottoms.reverse().concat(tops);}function stackOrderReverse(series){return stackOrderNone(series).reverse();}function registryFactory(parentRegistry){let registerName=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'unspecified';let logger=arguments.length>2?arguments[2]:undefined;let defaultValue;const reg={};const parent=parentRegistry||{get:()=>undefined,has:()=>false,default:()=>undefined};defaultValue=parent.default();/**
	   * @private
	   * @param {string} key
	   * @param {any} value
	   * @throws {TypeError} Key must be a non-empty string
	   * @returns {boolean} False if the given key already exists, true otherwise
	   * @example
	   * var r = registry();
	   * r.add( "marker", function(args) {
	   *   return new markers[args.type](args);
	   * });
	   *
	   */function add(key,value){if(!key||typeof key!=='string'){throw new TypeError('Invalid argument: key must be a non-empty string');}if(key in reg){return false;}reg[key]=value;return true;}function get(key){return reg[key]||parent.get(key);}function has(key){return !!reg[key]||parent.has(key);}function remove(key){const d=reg[key];delete reg[key];return d;}function getKeys(){return Object.keys(reg);}function getValues(){return Object.keys(reg).map(key=>reg[key]);}function deflt(d){if(typeof d!=='undefined'){defaultValue=d;}return defaultValue;}/**
	   * Register a `value` with the given `key`. If `value` is omitted, returns the `value` of `key`.
	   * @alias registry
	   * @param {string} key Name of the type to register
	   * @param {any} [value] Value to store in the registry.
	   * @returns {any} Registered value
	   */function registry(key,value){if(typeof value!=='undefined'){return add(key,value);}const ret=get(key);if(logger&&typeof ret==='undefined'){logger.warn("".concat(key," does not exist in ").concat(registerName," registry"));}return ret||get(defaultValue);}registry.add=add;registry.get=get;registry.has=has;registry.remove=remove;registry.getKeys=getKeys;registry.getValues=getValues;registry.default=deflt;registry.register=add;// deprecated
	return registry;}function formatDecimal(x){return Math.abs(x=Math.round(x))>=1e21?x.toLocaleString("en").replace(/,/g,""):x.toString(10);}// Computes the decimal coefficient and exponent of the specified number x with
	// significant digits p, where x is positive and p is in [1, 21] or undefined.
	// For example, formatDecimalParts(1.23) returns ["123", 0].
	function formatDecimalParts(x,p){if((i=(x=p?x.toExponential(p-1):x.toExponential()).indexOf("e"))<0)return null;// NaN, ±Infinity
	var i,coefficient=x.slice(0,i);// The string returned by toExponential either has the form \d\.\d+e[-+]\d+
	// (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
	return [coefficient.length>1?coefficient[0]+coefficient.slice(2):coefficient,+x.slice(i+1)];}function exponent(x){return x=formatDecimalParts(Math.abs(x)),x?x[1]:NaN;}function formatGroup(grouping,thousands){return function(value,width){var i=value.length,t=[],j=0,g=grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=grouping[j=(j+1)%grouping.length];}return t.reverse().join(thousands);};}function formatNumerals(numerals){return function(value){return value.replace(/[0-9]/g,function(i){return numerals[+i];});};}// [[fill]align][sign][symbol][0][width][,][.precision][~][type]
	var re=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function formatSpecifier(specifier){if(!(match=re.exec(specifier)))throw new Error("invalid format: "+specifier);var match;return new FormatSpecifier({fill:match[1],align:match[2],sign:match[3],symbol:match[4],zero:match[5],width:match[6],comma:match[7],precision:match[8]&&match[8].slice(1),trim:match[9],type:match[10]});}formatSpecifier.prototype=FormatSpecifier.prototype;// instanceof
	function FormatSpecifier(specifier){this.fill=specifier.fill===undefined?" ":specifier.fill+"";this.align=specifier.align===undefined?">":specifier.align+"";this.sign=specifier.sign===undefined?"-":specifier.sign+"";this.symbol=specifier.symbol===undefined?"":specifier.symbol+"";this.zero=!!specifier.zero;this.width=specifier.width===undefined?undefined:+specifier.width;this.comma=!!specifier.comma;this.precision=specifier.precision===undefined?undefined:+specifier.precision;this.trim=!!specifier.trim;this.type=specifier.type===undefined?"":specifier.type+"";}FormatSpecifier.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===undefined?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===undefined?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type;};// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.
	function formatTrim(s){out:for(var n=s.length,i=1,i0=-1,i1;i<n;++i){switch(s[i]){case ".":i0=i1=i;break;case "0":if(i0===0)i0=i;i1=i;break;default:if(!+s[i])break out;if(i0>0)i0=0;break;}}return i0>0?s.slice(0,i0)+s.slice(i1+1):s;}var prefixExponent;function formatPrefixAuto(x,p){var d=formatDecimalParts(x,p);if(!d)return x+"";var coefficient=d[0],exponent=d[1],i=exponent-(prefixExponent=Math.max(-8,Math.min(8,Math.floor(exponent/3)))*3)+1,n=coefficient.length;return i===n?coefficient:i>n?coefficient+new Array(i-n+1).join("0"):i>0?coefficient.slice(0,i)+"."+coefficient.slice(i):"0."+new Array(1-i).join("0")+formatDecimalParts(x,Math.max(0,p+i-1))[0];// less than 1y!
	}function formatRounded(x,p){var d=formatDecimalParts(x,p);if(!d)return x+"";var coefficient=d[0],exponent=d[1];return exponent<0?"0."+new Array(-exponent).join("0")+coefficient:coefficient.length>exponent+1?coefficient.slice(0,exponent+1)+"."+coefficient.slice(exponent+1):coefficient+new Array(exponent-coefficient.length+2).join("0");}var formatTypes={"%":(x,p)=>(x*100).toFixed(p),"b":x=>Math.round(x).toString(2),"c":x=>x+"","d":formatDecimal,"e":(x,p)=>x.toExponential(p),"f":(x,p)=>x.toFixed(p),"g":(x,p)=>x.toPrecision(p),"o":x=>Math.round(x).toString(8),"p":(x,p)=>formatRounded(x*100,p),"r":formatRounded,"s":formatPrefixAuto,"X":x=>Math.round(x).toString(16).toUpperCase(),"x":x=>Math.round(x).toString(16)};function identity$1(x){return x;}var map=Array.prototype.map,prefixes=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function formatLocale$1(locale){var group=locale.grouping===undefined||locale.thousands===undefined?identity$1:formatGroup(map.call(locale.grouping,Number),locale.thousands+""),currencyPrefix=locale.currency===undefined?"":locale.currency[0]+"",currencySuffix=locale.currency===undefined?"":locale.currency[1]+"",decimal=locale.decimal===undefined?".":locale.decimal+"",numerals=locale.numerals===undefined?identity$1:formatNumerals(map.call(locale.numerals,String)),percent=locale.percent===undefined?"%":locale.percent+"",minus=locale.minus===undefined?"−":locale.minus+"",nan=locale.nan===undefined?"NaN":locale.nan+"";function newFormat(specifier){specifier=formatSpecifier(specifier);var fill=specifier.fill,align=specifier.align,sign=specifier.sign,symbol=specifier.symbol,zero=specifier.zero,width=specifier.width,comma=specifier.comma,precision=specifier.precision,trim=specifier.trim,type=specifier.type;// The "n" type is an alias for ",g".
	if(type==="n")comma=true,type="g";// The "" type, and any invalid type, is an alias for ".12~g".
	else if(!formatTypes[type])precision===undefined&&(precision=12),trim=true,type="g";// If zero fill is specified, padding goes after sign and before digits.
	if(zero||fill==="0"&&align==="=")zero=true,fill="0",align="=";// Compute the prefix and suffix.
	// For SI-prefix, the suffix is lazily computed.
	var prefix=symbol==="$"?currencyPrefix:symbol==="#"&&/[boxX]/.test(type)?"0"+type.toLowerCase():"",suffix=symbol==="$"?currencySuffix:/[%p]/.test(type)?percent:"";// What format function should we use?
	// Is this an integer type?
	// Can this type generate exponential notation?
	var formatType=formatTypes[type],maybeSuffix=/[defgprs%]/.test(type);// Set the default precision if not specified,
	// or clamp the specified precision to the supported range.
	// For significant precision, it must be in [1, 21].
	// For fixed precision, it must be in [0, 20].
	precision=precision===undefined?6:/[gprs]/.test(type)?Math.max(1,Math.min(21,precision)):Math.max(0,Math.min(20,precision));function format(value){var valuePrefix=prefix,valueSuffix=suffix,i,n,c;if(type==="c"){valueSuffix=formatType(value)+valueSuffix;value="";}else {value=+value;// Determine the sign. -0 is not less than 0, but 1 / -0 is!
	var valueNegative=value<0||1/value<0;// Perform the initial formatting.
	value=isNaN(value)?nan:formatType(Math.abs(value),precision);// Trim insignificant zeros.
	if(trim)value=formatTrim(value);// If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.
	if(valueNegative&&+value===0&&sign!=="+")valueNegative=false;// Compute the prefix and suffix.
	valuePrefix=(valueNegative?sign==="("?sign:minus:sign==="-"||sign==="("?"":sign)+valuePrefix;valueSuffix=(type==="s"?prefixes[8+prefixExponent/3]:"")+valueSuffix+(valueNegative&&sign==="("?")":"");// Break the formatted value into the integer “value” part that can be
	// grouped, and fractional or exponential “suffix” part that is not.
	if(maybeSuffix){i=-1,n=value.length;while(++i<n){if(c=value.charCodeAt(i),48>c||c>57){valueSuffix=(c===46?decimal+value.slice(i+1):value.slice(i))+valueSuffix;value=value.slice(0,i);break;}}}}// If the fill character is not "0", grouping is applied before padding.
	if(comma&&!zero)value=group(value,Infinity);// Compute the padding.
	var length=valuePrefix.length+value.length+valueSuffix.length,padding=length<width?new Array(width-length+1).join(fill):"";// If the fill character is "0", grouping is applied after padding.
	if(comma&&zero)value=group(padding+value,padding.length?width-valueSuffix.length:Infinity),padding="";// Reconstruct the final output based on the desired alignment.
	switch(align){case "<":value=valuePrefix+value+valueSuffix+padding;break;case "=":value=valuePrefix+padding+value+valueSuffix;break;case "^":value=padding.slice(0,length=padding.length>>1)+valuePrefix+value+valueSuffix+padding.slice(length);break;default:value=padding+valuePrefix+value+valueSuffix;break;}return numerals(value);}format.toString=function(){return specifier+"";};return format;}function formatPrefix(specifier,value){var f=newFormat((specifier=formatSpecifier(specifier),specifier.type="f",specifier)),e=Math.max(-8,Math.min(8,Math.floor(exponent(value)/3)))*3,k=Math.pow(10,-e),prefix=prefixes[8+e/3];return function(value){return f(k*value)+prefix;};}return {format:newFormat,formatPrefix:formatPrefix};}var locale;var format;var formatPrefix;defaultLocale({thousands:",",grouping:[3],currency:["$",""]});function defaultLocale(definition){locale=formatLocale$1(definition);format=locale.format;formatPrefix=locale.formatPrefix;return locale;}function precisionFixed(step){return Math.max(0,-exponent(Math.abs(step)));}function precisionPrefix(step,value){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(exponent(value)/3)))*3-exponent(Math.abs(step)));}function precisionRound(step,max){step=Math.abs(step),max=Math.abs(max)-step;return Math.max(0,exponent(max)-exponent(step))+1;}function formatter$1$1(pattern,thousand,decimal){let locale,d3format;/**
	   * Format a value according to the specified pattern created at construct
	   * @private
	   *
	   * @param  {Number} value   The number to be formatted
	   * @return {String}         [description]
	   */function format(value){return d3format(value);}/**
	   * Set the locale for the formatter
	   *
	   * @param  {Object} args   Locale object for formatting
	   * @return {Undefined}      Returns nothing
	   */format.locale=function localeFn(settings){locale=formatLocale$1(settings);d3format=locale.format(pattern);return this;};/**
	   * Resets the formatter using format.locale
	   * @ignore
	   */function reset(){format.locale({decimal:decimal||'.',thousands:thousand||',',grouping:[3],currency:['$','']});}reset();/**
	   * Format a value according to a specific pattern
	   * that is not the one specified in the constructor
	   *
	   * @param  {String} p   Pattern
	   * @param  {Number} v   Value
	   * @param  {String} t   Thousand
	   * @param  {String} d   Decimal
	   * @return {String}     Formatted value
	   */format.format=function formatFn(p,v,t,d){if(t||d){thousand=t;decimal=d;reset();}return locale.format(p)(v);};/**
	   * Change the pattern on existing formatter
	   *
	   * @param  {String} p     Pattern (optional)
	   * @return {String}       Returns the pattern
	   */format.pattern=function patternFn(p){if(p){pattern=p;d3format=locale.format(p);}return pattern;};return format;}const t0=new Date(),t1=new Date();function timeInterval(floori,offseti,count,field){function interval(date){return floori(date=arguments.length===0?new Date():new Date(+date)),date;}interval.floor=date=>{return floori(date=new Date(+date)),date;};interval.ceil=date=>{return floori(date=new Date(date-1)),offseti(date,1),floori(date),date;};interval.round=date=>{const d0=interval(date),d1=interval.ceil(date);return date-d0<d1-date?d0:d1;};interval.offset=(date,step)=>{return offseti(date=new Date(+date),step==null?1:Math.floor(step)),date;};interval.range=(start,stop,step)=>{const range=[];start=interval.ceil(start);step=step==null?1:Math.floor(step);if(!(start<stop)||!(step>0))return range;// also handles Invalid Date
	let previous;do range.push(previous=new Date(+start)),offseti(start,step),floori(start);while(previous<start&&start<stop);return range;};interval.filter=test=>{return timeInterval(date=>{if(date>=date)while(floori(date),!test(date))date.setTime(date-1);},(date,step)=>{if(date>=date){if(step<0)while(++step<=0){while(offseti(date,-1),!test(date)){}// eslint-disable-line no-empty
	}else while(--step>=0){while(offseti(date,1),!test(date)){}// eslint-disable-line no-empty
	}}});};if(count){interval.count=(start,end)=>{t0.setTime(+start),t1.setTime(+end);floori(t0),floori(t1);return Math.floor(count(t0,t1));};interval.every=step=>{step=Math.floor(step);return !isFinite(step)||!(step>0)?null:!(step>1)?interval:interval.filter(field?d=>field(d)%step===0:d=>interval.count(0,d)%step===0);};}return interval;}const durationSecond=1000;const durationMinute=durationSecond*60;const durationHour=durationMinute*60;const durationDay=durationHour*24;const durationWeek=durationDay*7;const timeDay=timeInterval(date=>date.setHours(0,0,0,0),(date,step)=>date.setDate(date.getDate()+step),(start,end)=>(end-start-(end.getTimezoneOffset()-start.getTimezoneOffset())*durationMinute)/durationDay,date=>date.getDate()-1);timeDay.range;const utcDay=timeInterval(date=>{date.setUTCHours(0,0,0,0);},(date,step)=>{date.setUTCDate(date.getUTCDate()+step);},(start,end)=>{return (end-start)/durationDay;},date=>{return date.getUTCDate()-1;});utcDay.range;const unixDay=timeInterval(date=>{date.setUTCHours(0,0,0,0);},(date,step)=>{date.setUTCDate(date.getUTCDate()+step);},(start,end)=>{return (end-start)/durationDay;},date=>{return Math.floor(date/durationDay);});unixDay.range;function timeWeekday(i){return timeInterval(date=>{date.setDate(date.getDate()-(date.getDay()+7-i)%7);date.setHours(0,0,0,0);},(date,step)=>{date.setDate(date.getDate()+step*7);},(start,end)=>{return (end-start-(end.getTimezoneOffset()-start.getTimezoneOffset())*durationMinute)/durationWeek;});}const timeSunday=timeWeekday(0);const timeMonday=timeWeekday(1);const timeTuesday=timeWeekday(2);const timeWednesday=timeWeekday(3);const timeThursday=timeWeekday(4);const timeFriday=timeWeekday(5);const timeSaturday=timeWeekday(6);timeSunday.range;timeMonday.range;timeTuesday.range;timeWednesday.range;timeThursday.range;timeFriday.range;timeSaturday.range;function utcWeekday(i){return timeInterval(date=>{date.setUTCDate(date.getUTCDate()-(date.getUTCDay()+7-i)%7);date.setUTCHours(0,0,0,0);},(date,step)=>{date.setUTCDate(date.getUTCDate()+step*7);},(start,end)=>{return (end-start)/durationWeek;});}const utcSunday=utcWeekday(0);const utcMonday=utcWeekday(1);const utcTuesday=utcWeekday(2);const utcWednesday=utcWeekday(3);const utcThursday=utcWeekday(4);const utcFriday=utcWeekday(5);const utcSaturday=utcWeekday(6);utcSunday.range;utcMonday.range;utcTuesday.range;utcWednesday.range;utcThursday.range;utcFriday.range;utcSaturday.range;const timeYear=timeInterval(date=>{date.setMonth(0,1);date.setHours(0,0,0,0);},(date,step)=>{date.setFullYear(date.getFullYear()+step);},(start,end)=>{return end.getFullYear()-start.getFullYear();},date=>{return date.getFullYear();});// An optimized implementation for this simple case.
	timeYear.every=k=>{return !isFinite(k=Math.floor(k))||!(k>0)?null:timeInterval(date=>{date.setFullYear(Math.floor(date.getFullYear()/k)*k);date.setMonth(0,1);date.setHours(0,0,0,0);},(date,step)=>{date.setFullYear(date.getFullYear()+step*k);});};timeYear.range;const utcYear=timeInterval(date=>{date.setUTCMonth(0,1);date.setUTCHours(0,0,0,0);},(date,step)=>{date.setUTCFullYear(date.getUTCFullYear()+step);},(start,end)=>{return end.getUTCFullYear()-start.getUTCFullYear();},date=>{return date.getUTCFullYear();});// An optimized implementation for this simple case.
	utcYear.every=k=>{return !isFinite(k=Math.floor(k))||!(k>0)?null:timeInterval(date=>{date.setUTCFullYear(Math.floor(date.getUTCFullYear()/k)*k);date.setUTCMonth(0,1);date.setUTCHours(0,0,0,0);},(date,step)=>{date.setUTCFullYear(date.getUTCFullYear()+step*k);});};utcYear.range;function ascending(a,b){return a==null||b==null?NaN:a<b?-1:a>b?1:a>=b?0:NaN;}function descending(a,b){return a==null||b==null?NaN:b<a?-1:b>a?1:b>=a?0:NaN;}function bisector(f){let compare1,compare2,delta;// If an accessor is specified, promote it to a comparator. In this case we
	// can test whether the search value is (self-) comparable. We can’t do this
	// for a comparator (except for specific, known comparators) because we can’t
	// tell if the comparator is symmetric, and an asymmetric comparator can’t be
	// used to test whether a single value is comparable.
	if(f.length!==2){compare1=ascending;compare2=(d,x)=>ascending(f(d),x);delta=(d,x)=>f(d)-x;}else {compare1=f===ascending||f===descending?f:zero$1;compare2=f;delta=f;}function left(a,x,lo=0,hi=a.length){if(lo<hi){if(compare1(x,x)!==0)return hi;do{const mid=lo+hi>>>1;if(compare2(a[mid],x)<0)lo=mid+1;else hi=mid;}while(lo<hi);}return lo;}function right(a,x,lo=0,hi=a.length){if(lo<hi){if(compare1(x,x)!==0)return hi;do{const mid=lo+hi>>>1;if(compare2(a[mid],x)<=0)lo=mid+1;else hi=mid;}while(lo<hi);}return lo;}function center(a,x,lo=0,hi=a.length){const i=left(a,x,lo,hi-1);return i>lo&&delta(a[i-1],x)>-delta(a[i],x)?i-1:i;}return {left,center,right};}function zero$1(){return 0;}function number$2(x){return x===null?NaN:+x;}const ascendingBisect=bisector(ascending);const bisectRight=ascendingBisect.right;bisector(number$2).center;var bisect=bisectRight;class InternMap extends Map{constructor(entries,key=keyof){super();Object.defineProperties(this,{_intern:{value:new Map()},_key:{value:key}});if(entries!=null)for(const[key,value]of entries)this.set(key,value);}get(key){return super.get(intern_get(this,key));}has(key){return super.has(intern_get(this,key));}set(key,value){return super.set(intern_set(this,key),value);}delete(key){return super.delete(intern_delete(this,key));}}function intern_get({_intern,_key},value){const key=_key(value);return _intern.has(key)?_intern.get(key):value;}function intern_set({_intern,_key},value){const key=_key(value);if(_intern.has(key))return _intern.get(key);_intern.set(key,value);return value;}function intern_delete({_intern,_key},value){const key=_key(value);if(_intern.has(key)){value=_intern.get(key);_intern.delete(key);}return value;}function keyof(value){return value!==null&&typeof value==="object"?value.valueOf():value;}const e10=Math.sqrt(50),e5=Math.sqrt(10),e2=Math.sqrt(2);function tickSpec(start,stop,count){const step=(stop-start)/Math.max(0,count),power=Math.floor(Math.log10(step)),error=step/Math.pow(10,power),factor=error>=e10?10:error>=e5?5:error>=e2?2:1;let i1,i2,inc;if(power<0){inc=Math.pow(10,-power)/factor;i1=Math.round(start*inc);i2=Math.round(stop*inc);if(i1/inc<start)++i1;if(i2/inc>stop)--i2;inc=-inc;}else {inc=Math.pow(10,power)*factor;i1=Math.round(start/inc);i2=Math.round(stop/inc);if(i1*inc<start)++i1;if(i2*inc>stop)--i2;}if(i2<i1&&0.5<=count&&count<2)return tickSpec(start,stop,count*2);return [i1,i2,inc];}function ticks(start,stop,count){stop=+stop,start=+start,count=+count;if(!(count>0))return [];if(start===stop)return [start];const reverse=stop<start,[i1,i2,inc]=reverse?tickSpec(stop,start,count):tickSpec(start,stop,count);if(!(i2>=i1))return [];const n=i2-i1+1,ticks=new Array(n);if(reverse){if(inc<0)for(let i=0;i<n;++i)ticks[i]=(i2-i)/-inc;else for(let i=0;i<n;++i)ticks[i]=(i2-i)*inc;}else {if(inc<0)for(let i=0;i<n;++i)ticks[i]=(i1+i)/-inc;else for(let i=0;i<n;++i)ticks[i]=(i1+i)*inc;}return ticks;}function tickIncrement(start,stop,count){stop=+stop,start=+start,count=+count;return tickSpec(start,stop,count)[2];}function tickStep(start,stop,count){stop=+stop,start=+start,count=+count;const reverse=stop<start,inc=reverse?tickIncrement(stop,start,count):tickIncrement(start,stop,count);return (reverse?-1:1)*(inc<0?1/-inc:inc);}function range$1(start,stop,step){start=+start,stop=+stop,step=(n=arguments.length)<2?(stop=start,start=0,1):n<3?1:+step;var i=-1,n=Math.max(0,Math.ceil((stop-start)/step))|0,range=new Array(n);while(++i<n){range[i]=start+i*step;}return range;}function localDate(d){if(0<=d.y&&d.y<100){var date=new Date(-1,d.m,d.d,d.H,d.M,d.S,d.L);date.setFullYear(d.y);return date;}return new Date(d.y,d.m,d.d,d.H,d.M,d.S,d.L);}function utcDate(d){if(0<=d.y&&d.y<100){var date=new Date(Date.UTC(-1,d.m,d.d,d.H,d.M,d.S,d.L));date.setUTCFullYear(d.y);return date;}return new Date(Date.UTC(d.y,d.m,d.d,d.H,d.M,d.S,d.L));}function newDate(y,m,d){return {y:y,m:m,d:d,H:0,M:0,S:0,L:0};}function formatLocale(locale){var locale_dateTime=locale.dateTime,locale_date=locale.date,locale_time=locale.time,locale_periods=locale.periods,locale_weekdays=locale.days,locale_shortWeekdays=locale.shortDays,locale_months=locale.months,locale_shortMonths=locale.shortMonths;var periodRe=formatRe(locale_periods),periodLookup=formatLookup(locale_periods),weekdayRe=formatRe(locale_weekdays),weekdayLookup=formatLookup(locale_weekdays),shortWeekdayRe=formatRe(locale_shortWeekdays),shortWeekdayLookup=formatLookup(locale_shortWeekdays),monthRe=formatRe(locale_months),monthLookup=formatLookup(locale_months),shortMonthRe=formatRe(locale_shortMonths),shortMonthLookup=formatLookup(locale_shortMonths);var formats={"a":formatShortWeekday,"A":formatWeekday,"b":formatShortMonth,"B":formatMonth,"c":null,"d":formatDayOfMonth,"e":formatDayOfMonth,"f":formatMicroseconds,"g":formatYearISO,"G":formatFullYearISO,"H":formatHour24,"I":formatHour12,"j":formatDayOfYear,"L":formatMilliseconds,"m":formatMonthNumber,"M":formatMinutes,"p":formatPeriod,"q":formatQuarter,"Q":formatUnixTimestamp,"s":formatUnixTimestampSeconds,"S":formatSeconds,"u":formatWeekdayNumberMonday,"U":formatWeekNumberSunday,"V":formatWeekNumberISO,"w":formatWeekdayNumberSunday,"W":formatWeekNumberMonday,"x":null,"X":null,"y":formatYear,"Y":formatFullYear,"Z":formatZone,"%":formatLiteralPercent};var utcFormats={"a":formatUTCShortWeekday,"A":formatUTCWeekday,"b":formatUTCShortMonth,"B":formatUTCMonth,"c":null,"d":formatUTCDayOfMonth,"e":formatUTCDayOfMonth,"f":formatUTCMicroseconds,"g":formatUTCYearISO,"G":formatUTCFullYearISO,"H":formatUTCHour24,"I":formatUTCHour12,"j":formatUTCDayOfYear,"L":formatUTCMilliseconds,"m":formatUTCMonthNumber,"M":formatUTCMinutes,"p":formatUTCPeriod,"q":formatUTCQuarter,"Q":formatUnixTimestamp,"s":formatUnixTimestampSeconds,"S":formatUTCSeconds,"u":formatUTCWeekdayNumberMonday,"U":formatUTCWeekNumberSunday,"V":formatUTCWeekNumberISO,"w":formatUTCWeekdayNumberSunday,"W":formatUTCWeekNumberMonday,"x":null,"X":null,"y":formatUTCYear,"Y":formatUTCFullYear,"Z":formatUTCZone,"%":formatLiteralPercent};var parses={"a":parseShortWeekday,"A":parseWeekday,"b":parseShortMonth,"B":parseMonth,"c":parseLocaleDateTime,"d":parseDayOfMonth,"e":parseDayOfMonth,"f":parseMicroseconds,"g":parseYear,"G":parseFullYear,"H":parseHour24,"I":parseHour24,"j":parseDayOfYear,"L":parseMilliseconds,"m":parseMonthNumber,"M":parseMinutes,"p":parsePeriod,"q":parseQuarter,"Q":parseUnixTimestamp,"s":parseUnixTimestampSeconds,"S":parseSeconds,"u":parseWeekdayNumberMonday,"U":parseWeekNumberSunday,"V":parseWeekNumberISO,"w":parseWeekdayNumberSunday,"W":parseWeekNumberMonday,"x":parseLocaleDate,"X":parseLocaleTime,"y":parseYear,"Y":parseFullYear,"Z":parseZone,"%":parseLiteralPercent};// These recursive directive definitions must be deferred.
	formats.x=newFormat(locale_date,formats);formats.X=newFormat(locale_time,formats);formats.c=newFormat(locale_dateTime,formats);utcFormats.x=newFormat(locale_date,utcFormats);utcFormats.X=newFormat(locale_time,utcFormats);utcFormats.c=newFormat(locale_dateTime,utcFormats);function newFormat(specifier,formats){return function(date){var string=[],i=-1,j=0,n=specifier.length,c,pad,format;if(!(date instanceof Date))date=new Date(+date);while(++i<n){if(specifier.charCodeAt(i)===37){string.push(specifier.slice(j,i));if((pad=pads[c=specifier.charAt(++i)])!=null)c=specifier.charAt(++i);else pad=c==="e"?" ":"0";if(format=formats[c])c=format(date,pad);string.push(c);j=i+1;}}string.push(specifier.slice(j,i));return string.join("");};}function newParse(specifier,Z){return function(string){var d=newDate(1900,undefined,1),i=parseSpecifier(d,specifier,string+="",0),week,day;if(i!=string.length)return null;// If a UNIX timestamp is specified, return it.
	if("Q"in d)return new Date(d.Q);if("s"in d)return new Date(d.s*1000+("L"in d?d.L:0));// If this is utcParse, never use the local timezone.
	if(Z&&!("Z"in d))d.Z=0;// The am-pm flag is 0 for AM, and 1 for PM.
	if("p"in d)d.H=d.H%12+d.p*12;// If the month was not specified, inherit from the quarter.
	if(d.m===undefined)d.m="q"in d?d.q:0;// Convert day-of-week and week-of-year to day-of-year.
	if("V"in d){if(d.V<1||d.V>53)return null;if(!("w"in d))d.w=1;if("Z"in d){week=utcDate(newDate(d.y,0,1)),day=week.getUTCDay();week=day>4||day===0?utcMonday.ceil(week):utcMonday(week);week=utcDay.offset(week,(d.V-1)*7);d.y=week.getUTCFullYear();d.m=week.getUTCMonth();d.d=week.getUTCDate()+(d.w+6)%7;}else {week=localDate(newDate(d.y,0,1)),day=week.getDay();week=day>4||day===0?timeMonday.ceil(week):timeMonday(week);week=timeDay.offset(week,(d.V-1)*7);d.y=week.getFullYear();d.m=week.getMonth();d.d=week.getDate()+(d.w+6)%7;}}else if("W"in d||"U"in d){if(!("w"in d))d.w="u"in d?d.u%7:"W"in d?1:0;day="Z"in d?utcDate(newDate(d.y,0,1)).getUTCDay():localDate(newDate(d.y,0,1)).getDay();d.m=0;d.d="W"in d?(d.w+6)%7+d.W*7-(day+5)%7:d.w+d.U*7-(day+6)%7;}// If a time zone is specified, all fields are interpreted as UTC and then
	// offset according to the specified time zone.
	if("Z"in d){d.H+=d.Z/100|0;d.M+=d.Z%100;return utcDate(d);}// Otherwise, all fields are in local time.
	return localDate(d);};}function parseSpecifier(d,specifier,string,j){var i=0,n=specifier.length,m=string.length,c,parse;while(i<n){if(j>=m)return  -1;c=specifier.charCodeAt(i++);if(c===37){c=specifier.charAt(i++);parse=parses[c in pads?specifier.charAt(i++):c];if(!parse||(j=parse(d,string,j))<0)return  -1;}else if(c!=string.charCodeAt(j++)){return  -1;}}return j;}function parsePeriod(d,string,i){var n=periodRe.exec(string.slice(i));return n?(d.p=periodLookup.get(n[0].toLowerCase()),i+n[0].length):-1;}function parseShortWeekday(d,string,i){var n=shortWeekdayRe.exec(string.slice(i));return n?(d.w=shortWeekdayLookup.get(n[0].toLowerCase()),i+n[0].length):-1;}function parseWeekday(d,string,i){var n=weekdayRe.exec(string.slice(i));return n?(d.w=weekdayLookup.get(n[0].toLowerCase()),i+n[0].length):-1;}function parseShortMonth(d,string,i){var n=shortMonthRe.exec(string.slice(i));return n?(d.m=shortMonthLookup.get(n[0].toLowerCase()),i+n[0].length):-1;}function parseMonth(d,string,i){var n=monthRe.exec(string.slice(i));return n?(d.m=monthLookup.get(n[0].toLowerCase()),i+n[0].length):-1;}function parseLocaleDateTime(d,string,i){return parseSpecifier(d,locale_dateTime,string,i);}function parseLocaleDate(d,string,i){return parseSpecifier(d,locale_date,string,i);}function parseLocaleTime(d,string,i){return parseSpecifier(d,locale_time,string,i);}function formatShortWeekday(d){return locale_shortWeekdays[d.getDay()];}function formatWeekday(d){return locale_weekdays[d.getDay()];}function formatShortMonth(d){return locale_shortMonths[d.getMonth()];}function formatMonth(d){return locale_months[d.getMonth()];}function formatPeriod(d){return locale_periods[+(d.getHours()>=12)];}function formatQuarter(d){return 1+~~(d.getMonth()/3);}function formatUTCShortWeekday(d){return locale_shortWeekdays[d.getUTCDay()];}function formatUTCWeekday(d){return locale_weekdays[d.getUTCDay()];}function formatUTCShortMonth(d){return locale_shortMonths[d.getUTCMonth()];}function formatUTCMonth(d){return locale_months[d.getUTCMonth()];}function formatUTCPeriod(d){return locale_periods[+(d.getUTCHours()>=12)];}function formatUTCQuarter(d){return 1+~~(d.getUTCMonth()/3);}return {format:function(specifier){var f=newFormat(specifier+="",formats);f.toString=function(){return specifier;};return f;},parse:function(specifier){var p=newParse(specifier+="",false);p.toString=function(){return specifier;};return p;},utcFormat:function(specifier){var f=newFormat(specifier+="",utcFormats);f.toString=function(){return specifier;};return f;},utcParse:function(specifier){var p=newParse(specifier+="",true);p.toString=function(){return specifier;};return p;}};}var pads={"-":"","_":" ","0":"0"},numberRe=/^\s*\d+/,// note: ignores next directive
	percentRe=/^%/,requoteRe=/[\\^$*+?|[\]().{}]/g;function pad$2(value,fill,width){var sign=value<0?"-":"",string=(sign?-value:value)+"",length=string.length;return sign+(length<width?new Array(width-length+1).join(fill)+string:string);}function requote(s){return s.replace(requoteRe,"\\$&");}function formatRe(names){return new RegExp("^(?:"+names.map(requote).join("|")+")","i");}function formatLookup(names){return new Map(names.map((name,i)=>[name.toLowerCase(),i]));}function parseWeekdayNumberSunday(d,string,i){var n=numberRe.exec(string.slice(i,i+1));return n?(d.w=+n[0],i+n[0].length):-1;}function parseWeekdayNumberMonday(d,string,i){var n=numberRe.exec(string.slice(i,i+1));return n?(d.u=+n[0],i+n[0].length):-1;}function parseWeekNumberSunday(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.U=+n[0],i+n[0].length):-1;}function parseWeekNumberISO(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.V=+n[0],i+n[0].length):-1;}function parseWeekNumberMonday(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.W=+n[0],i+n[0].length):-1;}function parseFullYear(d,string,i){var n=numberRe.exec(string.slice(i,i+4));return n?(d.y=+n[0],i+n[0].length):-1;}function parseYear(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.y=+n[0]+(+n[0]>68?1900:2000),i+n[0].length):-1;}function parseZone(d,string,i){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i,i+6));return n?(d.Z=n[1]?0:-(n[2]+(n[3]||"00")),i+n[0].length):-1;}function parseQuarter(d,string,i){var n=numberRe.exec(string.slice(i,i+1));return n?(d.q=n[0]*3-3,i+n[0].length):-1;}function parseMonthNumber(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.m=n[0]-1,i+n[0].length):-1;}function parseDayOfMonth(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.d=+n[0],i+n[0].length):-1;}function parseDayOfYear(d,string,i){var n=numberRe.exec(string.slice(i,i+3));return n?(d.m=0,d.d=+n[0],i+n[0].length):-1;}function parseHour24(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.H=+n[0],i+n[0].length):-1;}function parseMinutes(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.M=+n[0],i+n[0].length):-1;}function parseSeconds(d,string,i){var n=numberRe.exec(string.slice(i,i+2));return n?(d.S=+n[0],i+n[0].length):-1;}function parseMilliseconds(d,string,i){var n=numberRe.exec(string.slice(i,i+3));return n?(d.L=+n[0],i+n[0].length):-1;}function parseMicroseconds(d,string,i){var n=numberRe.exec(string.slice(i,i+6));return n?(d.L=Math.floor(n[0]/1000),i+n[0].length):-1;}function parseLiteralPercent(d,string,i){var n=percentRe.exec(string.slice(i,i+1));return n?i+n[0].length:-1;}function parseUnixTimestamp(d,string,i){var n=numberRe.exec(string.slice(i));return n?(d.Q=+n[0],i+n[0].length):-1;}function parseUnixTimestampSeconds(d,string,i){var n=numberRe.exec(string.slice(i));return n?(d.s=+n[0],i+n[0].length):-1;}function formatDayOfMonth(d,p){return pad$2(d.getDate(),p,2);}function formatHour24(d,p){return pad$2(d.getHours(),p,2);}function formatHour12(d,p){return pad$2(d.getHours()%12||12,p,2);}function formatDayOfYear(d,p){return pad$2(1+timeDay.count(timeYear(d),d),p,3);}function formatMilliseconds(d,p){return pad$2(d.getMilliseconds(),p,3);}function formatMicroseconds(d,p){return formatMilliseconds(d,p)+"000";}function formatMonthNumber(d,p){return pad$2(d.getMonth()+1,p,2);}function formatMinutes(d,p){return pad$2(d.getMinutes(),p,2);}function formatSeconds(d,p){return pad$2(d.getSeconds(),p,2);}function formatWeekdayNumberMonday(d){var day=d.getDay();return day===0?7:day;}function formatWeekNumberSunday(d,p){return pad$2(timeSunday.count(timeYear(d)-1,d),p,2);}function dISO(d){var day=d.getDay();return day>=4||day===0?timeThursday(d):timeThursday.ceil(d);}function formatWeekNumberISO(d,p){d=dISO(d);return pad$2(timeThursday.count(timeYear(d),d)+(timeYear(d).getDay()===4),p,2);}function formatWeekdayNumberSunday(d){return d.getDay();}function formatWeekNumberMonday(d,p){return pad$2(timeMonday.count(timeYear(d)-1,d),p,2);}function formatYear(d,p){return pad$2(d.getFullYear()%100,p,2);}function formatYearISO(d,p){d=dISO(d);return pad$2(d.getFullYear()%100,p,2);}function formatFullYear(d,p){return pad$2(d.getFullYear()%10000,p,4);}function formatFullYearISO(d,p){var day=d.getDay();d=day>=4||day===0?timeThursday(d):timeThursday.ceil(d);return pad$2(d.getFullYear()%10000,p,4);}function formatZone(d){var z=d.getTimezoneOffset();return (z>0?"-":(z*=-1,"+"))+pad$2(z/60|0,"0",2)+pad$2(z%60,"0",2);}function formatUTCDayOfMonth(d,p){return pad$2(d.getUTCDate(),p,2);}function formatUTCHour24(d,p){return pad$2(d.getUTCHours(),p,2);}function formatUTCHour12(d,p){return pad$2(d.getUTCHours()%12||12,p,2);}function formatUTCDayOfYear(d,p){return pad$2(1+utcDay.count(utcYear(d),d),p,3);}function formatUTCMilliseconds(d,p){return pad$2(d.getUTCMilliseconds(),p,3);}function formatUTCMicroseconds(d,p){return formatUTCMilliseconds(d,p)+"000";}function formatUTCMonthNumber(d,p){return pad$2(d.getUTCMonth()+1,p,2);}function formatUTCMinutes(d,p){return pad$2(d.getUTCMinutes(),p,2);}function formatUTCSeconds(d,p){return pad$2(d.getUTCSeconds(),p,2);}function formatUTCWeekdayNumberMonday(d){var dow=d.getUTCDay();return dow===0?7:dow;}function formatUTCWeekNumberSunday(d,p){return pad$2(utcSunday.count(utcYear(d)-1,d),p,2);}function UTCdISO(d){var day=d.getUTCDay();return day>=4||day===0?utcThursday(d):utcThursday.ceil(d);}function formatUTCWeekNumberISO(d,p){d=UTCdISO(d);return pad$2(utcThursday.count(utcYear(d),d)+(utcYear(d).getUTCDay()===4),p,2);}function formatUTCWeekdayNumberSunday(d){return d.getUTCDay();}function formatUTCWeekNumberMonday(d,p){return pad$2(utcMonday.count(utcYear(d)-1,d),p,2);}function formatUTCYear(d,p){return pad$2(d.getUTCFullYear()%100,p,2);}function formatUTCYearISO(d,p){d=UTCdISO(d);return pad$2(d.getUTCFullYear()%100,p,2);}function formatUTCFullYear(d,p){return pad$2(d.getUTCFullYear()%10000,p,4);}function formatUTCFullYearISO(d,p){var day=d.getUTCDay();d=day>=4||day===0?utcThursday(d):utcThursday.ceil(d);return pad$2(d.getUTCFullYear()%10000,p,4);}function formatUTCZone(){return "+0000";}function formatLiteralPercent(){return "%";}function formatUnixTimestamp(d){return +d;}function formatUnixTimestampSeconds(d){return Math.floor(+d/1000);}function formatter$2(pattern){// eslint-disable-line import/prefer-default-export
	let locale=formatLocale({dateTime:'%x, %X',date:'%-m/%-d/%Y',time:'%-I:%M:%S %p',periods:['AM','PM'],days:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],shortDays:['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],months:['January','February','March','April','May','June','July','August','September','October','November','December'],shortMonths:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']});let d3format=locale.format(pattern);/**
	   * Format a value according to the specified pattern created at construct
	   *
	   * @param  {Date} value   The number to be formatted
	   * @return {String}         [description]
	   * @private
	   */function format(value){return d3format(value);}/**
	   * Format a value according to a specific pattern
	   * that is not the one specified in the constructor
	   *
	   * @param  {String} p   Pattern
	   * @param  {Date} v   Value
	   * @return {String}     Formatted value
	   */format.format=function formatFn(p,v){return locale.format(p)(v);};/**
	   * Set the locale for the formatter
	   *
	   * @param  {Object} args   Locale object for formatting
	   * @return {Undefined}      Returns nothing
	   */format.locale=function localeFn(){locale=formatLocale(...arguments);d3format=locale.format(pattern);return this;};/**
	   * Parse a string to a date according to a pattern
	   *
	   * @param  {String} p   Pattern
	   * @param  {String} v   Value
	   * @return {Date}     Date
	   */format.parse=function parse(p,v){return locale.parse(p)(v);};/**
	   * Returns a parser that parses strings to date according to the pattern
	   *
	   * @param  {String} p   Pattern
	   * @return {Function}   Parser
	   */format.parsePattern=function parsePattern(p){return locale.parse(p);};return format;}/**
	 * @typedef {function} formatter
	 * @returns {any} Returns a formatted value
	 *//**
	 * @typedef {object} FormatterDefinition
	 * @property {string} [formatter] Name of the formatter
	 * @property {string} [type] Type of formatter
	 * @property {string} [format] Format string
	 * @property {DataExtraction|DataFieldExtraction} [data] The data to create formatter from
	 */const formatterRegistry=registryFactory();formatterRegistry('d3-number',formatter$1$1);formatterRegistry('d3-time',formatter$2);/* eslint no-return-assign: 0 */// TODO - decide whether usage of .call() is appropriate when invoking accessors, if yes then arrow functions are not allowed!
	const getFormatter$1=data=>{if(typeof data.formatter==='function'){return data.formatter();}const f=data.formatter||{};return formatterRegistry(f.type||'d3-number')(f.format||'');};const accessors={id:data=>"".concat(data.source,"/").concat(data.key||data.title),key:data=>String(data.key||data.title),tags:data=>data.tags,min:data=>data.min,max:data=>data.max,type:data=>data.type,title:data=>String(data.title),values:data=>data.values,value:v=>v,label:v=>v,formatter:data=>getFormatter$1(data)};/**
	 * Create a new field with default settings
	 * @ignore
	 * @return {Field} Data field
	 */function field(data){let{id=accessors.id,key=accessors.key,min=accessors.min,max=accessors.max,type=accessors.type,tags=accessors.tags,title=accessors.title,values=accessors.values,value=accessors.value,label=accessors.label,formatter=accessors.formatter}=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};/**
	   * @alias Field
	   */const f={/**
	     * Returns this field's id
	     * @returns {string}
	     */id:()=>id(data),/**
	     * Returns this field's key
	     * @returns {string}
	     */key:()=>key(data),/**
	     * Returns the input data
	     * @returns {any}
	     */raw:()=>data,/**
	     * Returns the tags.
	     * @return {Array<string>}
	     */tags:()=>tags(data),/**
	     * Returns this field's type: 'dimension' or 'measure'.
	     * @return {string}
	     */type:()=>type(data),/**
	     * Returns the min value of this field.
	     * @return {number}
	     */min:()=>min(data),/**
	     * Returns the max value of this field.
	     * @return {number}
	     */max:()=>max(data),/**
	     * Returns this field's title.
	     * @return {string}
	     */title:()=>title(data),/**
	     * Returns the values of this field.
	     * @return {Array<DatumExtract>}
	     */items:()=>values(data),/**
	     * Returns a formatter adapted to the content of this field.
	     */formatter:()=>formatter(data),value,label};return f;}function findField$2(query,_ref){let{cache}=_ref;if(typeof query==='number'){return cache.fields[query];}// Find by key first
	for(let i=0;i<cache.fields.length;i++){if(cache.fields[i].key()===query){return cache.fields[i];}}// find by title
	for(let i=0;i<cache.fields.length;i++){if(cache.fields[i].title()===query){return cache.fields[i];}}return null;}const filters$1={numeric:values=>values.filter(v=>typeof v==='number'&&!isNaN(v))};const unfilteredReducers={sum:values=>values.reduce((a,b)=>a+b,0)};// function isPrimitive(x) {
	//   const type = typeof x;
	//   return (type !== 'object' && type !== 'function');
	// }
	/**
	 * [reducers description]
	 * @type {Object}
	 * @private
	 */const reducers={first:values=>values[0],last:values=>values[values.length-1],min:values=>{const filtered=filters$1.numeric(values);return !filtered.length?NaN:Math.min.apply(null,filtered);},max:values=>{const filtered=filters$1.numeric(values);return !filtered.length?NaN:Math.max.apply(null,filtered);},sum:values=>{const filtered=filters$1.numeric(values);return !filtered.length?NaN:filtered.reduce((a,b)=>a+b,0);},avg:values=>{const filtered=filters$1.numeric(values);const len=filtered.length;return !len?NaN:unfilteredReducers.sum(filtered)/len;}};function normalizeProperties(cfg,dataset,dataProperties,main){// console.log('======', cfg, main, dataset);
	const props={};const mainField=main.field||(typeof cfg.field!=='undefined'?dataset.field(cfg.field):null);Object.keys(dataProperties).forEach(key=>{const pConfig=dataProperties[key];const prop=props[key]={};if(['number','string','boolean'].indexOf(typeof pConfig)!==-1){prop.type='primitive';prop.value=pConfig;}else if(typeof pConfig==='function'){prop.type='function';prop.value=pConfig;prop.label=pConfig;prop.field=mainField;}else if(typeof pConfig==='object'){if(pConfig.fields){prop.fields=pConfig.fields.map(ff=>normalizeProperties(cfg,dataset,{main:ff},main).main);}else if(typeof pConfig.field!=='undefined'){prop.type='field';prop.field=dataset.field(pConfig.field);prop.value=prop.field.value;prop.label=prop.field.label;}else if(mainField){prop.value=mainField.value;prop.label=mainField.label;prop.field=mainField;}if(typeof pConfig.filter==='function'){prop.filter=pConfig.filter;}if(typeof pConfig.value!=='undefined'){prop.value=pConfig.value;}if(typeof pConfig.label!=='undefined'){prop.label=pConfig.label;}if(typeof pConfig.reduce==='function'){prop.reduce=pConfig.reduce;}else if(pConfig.reduce){prop.reduce=reducers[pConfig.reduce];}else if(prop.field&&prop.field.reduce){prop.reduce=typeof prop.field.reduce==='string'?reducers[prop.field.reduce]:prop.field.reduce;}if(typeof pConfig.reduceLabel==='function'){prop.reduceLabel=pConfig.reduceLabel;}else if(pConfig.reduceLabel){prop.reduceLabel=reducers[pConfig.reduceLabel];}else if(prop.field&&prop.field.reduceLabel){prop.reduceLabel=typeof prop.field.reduceLabel==='string'?reducers[prop.field.reduceLabel]:prop.field.reduceLabel;}}});return props;}/*
	example of configuration input
	cfg = {
	  field: 'State', // the 'top level' values are extracted from field state
	  value: d => d.qText, // the value of the output
	  props: { // additional data properties ammended to each item
	    a: 3, // constant value
	    b: d => d.qElemNumber, // function will receive the original field value
	    c: {
	      field: 'Country', // reference to another field
	      value: d => d.qText // extract the qText value from the referenced field
	    },
	    d: {
	      value: d => d.qRow //  extract qRow from field 'State'
	    }
	  }
	}

	// output
	[{
	  value: 'CA', source: { field: 'State' },
	  a: { value: 3 },
	  b: { value: 26, source: 'State' },
	  c: { value: 'USA', source: 'Country' },
	  d: { value: 131, source: 'State' }
	},
	...]
	*/function getPropsInfo(cfg,dataset){// console.log('222', cfg);
	const{main}=normalizeProperties(cfg,dataset,{main:{value:cfg.value,label:cfg.label,reduce:cfg.reduce,filter:cfg.filter}},{});const props=normalizeProperties(cfg,dataset,cfg.props||{},main);return {props,main};}function collectItems(items,cfg,formatter,prop){const values=Array(items.length);const labels=Array(items.length);let it;for(let i=0;i<items.length;i++){it=prop?items[i][prop]:items[i];values[i]=it.value;labels[i]=it.label;}const reduce=cfg.reduce;const reduceLabel=cfg.reduceLabel;const v=reduce?reduce(values):values;const b=reduceLabel?reduceLabel(labels,v):formatter?formatter(v):String(v);// eslint-disable-line no-nested-ternary
	// // ret[prop].label = String(propsFormatters[prop](ret[prop].value));
	const ret={value:v,label:b};if(prop&&items[0][prop].source){ret.source=items[0][prop].source;return ret;}if(!prop&&items[0].source){ret.source=items[0].source;return ret;}return ret;}// collect items that have been grouped and reduce per group and property
	function collect(trackedItems,_ref2){let{main,propsArr,props}=_ref2;let dataItems=[];const mainFormatter=main.field.formatter();// || (v => v);
	const propsFormatters={};propsArr.forEach(prop=>{propsFormatters[prop]=props[prop].field?props[prop].field.formatter():v=>v;});dataItems.push(...trackedItems.map(t=>{const ret=collectItems(t.items,main,mainFormatter);propsArr.forEach(prop=>{ret[prop]=collectItems(t.items,props[prop],propsFormatters[prop],prop);});return ret;}));return dataItems;}function track(_ref3){let{cfg,itemData,obj,target,tracker,trackType}=_ref3;const trackId=trackType==='function'?cfg.trackBy(itemData):itemData[cfg.trackBy];let trackedItem=tracker[trackId];if(!trackedItem){trackedItem=tracker[trackId]={items:[],id:trackId};target.push(trackedItem);}trackedItem.items.push(obj);}const ARRAY_MAX_SIZE=10000;function getMax(values){if(values.length<ARRAY_MAX_SIZE){return Math.max(...values);}let max=-Infinity;const len=values.length;for(let i=0;i<len;i++){if(max<values[i]){max=values[i];}}return max;}function getMin(values){if(values.length<ARRAY_MAX_SIZE){return Math.min(...values);}let min=Infinity;const len=values.length;for(let i=0;i<len;i++){if(min>values[i]){min=values[i];}}return min;}const OFFSETS={diverging:stackOffsetDiverging,none:stackOffsetNone,silhouette:stackOffsetSilhouette,expand:stackOffsetExpand,wiggle:stackOffsetWiggle};const ORDERS={ascending:stackOrderAscending,insideout:stackOrderInsideOut,none:stackOrderNone,reverse:stackOrderReverse};function stacked(data,config,ds){const stackIds={};const stackFn=config.stackKey;const valueFn=config.value;const startProp=config.startProp||'start';const endProp=config.endProp||'end';const offset=config.offset||'none';const order=config.order||'none';const valueRef=config.valueRef||'';let maxStackCount=0;let valueFields={};for(let i=0;i<data.items.length;i++){let p=data.items[i];let sourceField=valueRef?p[valueRef]:null;if(sourceField&&sourceField.source){let ff="".concat(sourceField.source.key||'',"/").concat(sourceField.source.field);if(!valueFields[ff]){valueFields[ff]=sourceField.source;}}let sid=stackFn(p);stackIds[sid]=stackIds[sid]||{items:[]};stackIds[sid].items.push(p);maxStackCount=Math.max(maxStackCount,stackIds[sid].items.length);}const keys=Array.apply(null,{length:maxStackCount}).map(Number.call,Number);// eslint-disable-line
	const matrix=Object.keys(stackIds).map(sid=>stackIds[sid].items);const d3Stack=stack().keys(keys).value((s,key)=>s[key]?valueFn(s[key]):0).order(ORDERS[order]).offset(OFFSETS[offset]);let series=d3Stack(matrix);let values=[];for(let i=0;i<series.length;i++){let serie=series[i];for(let s=0;s<serie.length;s++){let range=serie[s];let item=serie[s].data[serie.key];if(!item){continue;}item[startProp]={value:range[0]};item[endProp]={value:range[1]};values.push(range[0],range[1]);}}let stackedFields=Object.keys(valueFields).map(f=>{let dSource=ds(valueFields[f].key);return dSource?dSource.field(valueFields[f].field):null;}).filter(f=>!!f);const field$1=field({title:stackedFields.map(f=>f.title()).join(', '),min:getMin(values),max:getMax(values),type:'measure',formatter:stackedFields[0]?stackedFields[0].formatter:undefined});data.fields.push(field$1);}function extract$1$1(dataConfig){let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let opts=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};let extracted={// items: [],
	// fields: [],
	// source: null,
	// value: null,
	// label: null,
	// children: null,
	// root: null,
	// graph: null
	};const logger=opts.logger;if(Array.isArray(dataConfig)){// if data is an array, assume it's manual data input -> normalize
	extracted.items=dataConfig.map(v=>({value:v,label:String(v)}));}else if(dataConfig){if('collection'in dataConfig){extracted=_objectSpread2$1({},data.collection(dataConfig.collection));}else {const source=data.dataset?data.dataset(dataConfig.source):null;let valueFn=dataConfig.value||(d=>d);let labelFn=dataConfig.label||(d=>d);if(dataConfig.groupBy||dataConfig.mapTo){// DEPRECATION
	logger.warn('Deprecated "data" configuration',dataConfig);extracted.items=[];}else if(dataConfig.hierarchy){extracted.root=source.hierarchy?source.hierarchy(dataConfig.hierarchy):null;extracted.fields=source.fields();}else if(dataConfig.items){extracted.items=dataConfig.skipNormalize?dataConfig.items:dataConfig.items.map(v=>({value:valueFn(v),label:String(labelFn(v))}));}else if(dataConfig.extract){const extractionsConfigs=Array.isArray(dataConfig.extract)?dataConfig.extract:[dataConfig.extract];extracted.items=[];const sourceFields=[];extractionsConfigs.forEach(cfg=>{const s=cfg.source?data.dataset(cfg.source):source;if(!s){return;}extracted.items=[...extracted.items,...s.extract(cfg)];if(typeof cfg.field!=='undefined'){sourceFields.push(s.field(cfg.field));}});if(sourceFields.length){extracted.fields=sourceFields;}if(dataConfig.amend&&Array.isArray(dataConfig.amend)){extracted.items=[...extracted.items,...dataConfig.amend];}}else if(typeof dataConfig.field!=='undefined'&&source){const f=source.field(dataConfig.field);if(f){if(!extracted.fields){extracted.fields=[];}extracted.fields.push(f);if(!('value'in dataConfig)){valueFn=f.value||(v=>v);labelFn=f.label||(v=>v);extracted.value=valueFn;}extracted.items=f.items().map(v=>({value:valueFn(v),label:String(labelFn(v)),source:{field:dataConfig.field}}));// TODO - add source: { key: dataConfig.source, field: dataConfig.field, data: v }
	}}else if(dataConfig.fields){dataConfig.fields.forEach(obj=>{const s=typeof obj==='object'&&obj.source?data.dataset(obj.source):source;if(!s){return;}let f;if(typeof obj==='object'&&typeof obj.field!=='undefined'){f=s.field(obj.field);}else {f=s.field(obj);}if(f){if(!extracted.fields){extracted.fields=[];}extracted.fields.push(f);}});}if(extracted.items&&dataConfig.map){extracted.items=extracted.items.map(dataConfig.map);}}if(dataConfig&&dataConfig.stack){stacked(extracted,dataConfig.stack,data.dataset);}}if(dataConfig&&!Array.isArray(dataConfig)&&typeof dataConfig.filter==='function'&&extracted.items){extracted.items=extracted.items.filter(dataConfig.filter);}if(dataConfig&&!Array.isArray(dataConfig)&&typeof dataConfig.sort==='function'&&extracted.items){extracted.items=extracted.items.sort(dataConfig.sort);}return extracted;}/**
	 * @interface CollectionSettings
	 * @property {string} key Unique key for the collection
	 * @property {DataExtraction} data Data configuration
	 * @example
	 * {
	    key: 'my-collection',
	    data: {
	      extract: [{
	        source: 'Products',
	        field: 'Product',
	        value: d => d.name,
	        label: d => `<${d.name}>`
	        props: {
	          year: { field: 'Year' }
	          num: { field: 'Sales' }
	        }
	      }],
	      filter: d => d.label !== 'Sneakers', // extract everything except Sneakers
	      sort: (a, b) => a.label > b.label ? -1 : 1, // sort descending
	    }
	 * }
	 */function create$p(config,d,opts){let extractor=arguments.length>3&&arguments[3]!==undefined?arguments[3]:extract$1$1;const collections={};(config||[]).forEach(cfg=>{if(!cfg.key){throw new Error('Data collection is missing "key" property');}if(typeof cfg.data==='object'&&'collection'in cfg.data){throw new Error('Data config for collections may not reference other collections');}collections[cfg.key]=()=>extractor(cfg.data,d,opts);});const fn=key=>{let k;let cfg;if(typeof key==='string'){k=key;}else if(typeof key==='object'){k=key.key;cfg=key;}if(!(k in collections)){throw new Error("Unknown data collection: ".concat(k));}if(typeof collections[k]==='function'){collections[k]=collections[k]();}let coll=collections[k];if(cfg){if(cfg.fields&&cfg.fields.filter){let filtered=coll.fields.filter(cfg.fields.filter);if(coll.fields.length!==filtered.length){coll=extend$1$1(coll,{fields:filtered});}}}return coll;};return fn;}function create$o(options,data,deps){let extractor=arguments.length>3&&arguments[3]!==undefined?arguments[3]:extract$1$1;if(options.data){const d=extractor(options.data,data,deps);if(d&&d.fields&&d.fields[0]){// TODO Have some magic to handle and merge formatters from multiple sources
	return d.fields[0].formatter();}}let formatterType;if(options.formatter){formatterType="".concat(options.formatter,"-").concat(options.type||'number');}else {formatterType=options.type||'d3-number';}if(deps.formatter.has(formatterType)){const f=deps.formatter.get(formatterType)(options.format||'');return f;}throw new Error("Formatter of type '".concat(formatterType,"' was not found"));}function collection$1(formattersConfig,data,deps){let fn=arguments.length>3&&arguments[3]!==undefined?arguments[3]:create$o;const formatters={};return {get(def){let key;if(typeof def==='string'&&formattersConfig[def]){key=def;}else if(typeof def==='object'&&'formatter'in def&&formattersConfig[def.formatter]){key=def.formatter;}else if(typeof def==='object'&&'type'in def&&formattersConfig[def.type]){key=def.type;}if(key){formatters[key]=formatters[key]||fn(formattersConfig[key],data,deps);return formatters[key];}return fn(def||{},data,deps);},all(){Object.keys(formattersConfig).forEach(this.get);return formatters;}};}function initRange(domain,range){switch(arguments.length){case 0:break;case 1:this.range(domain);break;default:this.range(range).domain(domain);break;}return this;}const implicit=Symbol("implicit");function ordinal$1(){var index=new InternMap(),domain=[],range=[],unknown=implicit;function scale(d){let i=index.get(d);if(i===undefined){if(unknown!==implicit)return unknown;index.set(d,i=domain.push(d)-1);}return range[i%range.length];}scale.domain=function(_){if(!arguments.length)return domain.slice();domain=[],index=new InternMap();for(const value of _){if(index.has(value))continue;index.set(value,domain.push(value)-1);}return scale;};scale.range=function(_){return arguments.length?(range=Array.from(_),scale):range.slice();};scale.unknown=function(_){return arguments.length?(unknown=_,scale):unknown;};scale.copy=function(){return ordinal$1(domain,range).unknown(unknown);};initRange.apply(scale,arguments);return scale;}function band(){var scale=ordinal$1().unknown(undefined),domain=scale.domain,ordinalRange=scale.range,r0=0,r1=1,step,bandwidth,round=false,paddingInner=0,paddingOuter=0,align=0.5;delete scale.unknown;function rescale(){var n=domain().length,reverse=r1<r0,start=reverse?r1:r0,stop=reverse?r0:r1;step=(stop-start)/Math.max(1,n-paddingInner+paddingOuter*2);if(round)step=Math.floor(step);start+=(stop-start-step*(n-paddingInner))*align;bandwidth=step*(1-paddingInner);if(round)start=Math.round(start),bandwidth=Math.round(bandwidth);var values=range$1(n).map(function(i){return start+step*i;});return ordinalRange(reverse?values.reverse():values);}scale.domain=function(_){return arguments.length?(domain(_),rescale()):domain();};scale.range=function(_){return arguments.length?([r0,r1]=_,r0=+r0,r1=+r1,rescale()):[r0,r1];};scale.rangeRound=function(_){return [r0,r1]=_,r0=+r0,r1=+r1,round=true,rescale();};scale.bandwidth=function(){return bandwidth;};scale.step=function(){return step;};scale.round=function(_){return arguments.length?(round=!!_,rescale()):round;};scale.padding=function(_){return arguments.length?(paddingInner=Math.min(1,paddingOuter=+_),rescale()):paddingInner;};scale.paddingInner=function(_){return arguments.length?(paddingInner=Math.min(1,_),rescale()):paddingInner;};scale.paddingOuter=function(_){return arguments.length?(paddingOuter=+_,rescale()):paddingOuter;};scale.align=function(_){return arguments.length?(align=Math.max(0,Math.min(1,_)),rescale()):align;};scale.copy=function(){return band(domain(),[r0,r1]).round(round).paddingInner(paddingInner).paddingOuter(paddingOuter).align(align);};return initRange.apply(rescale(),arguments);}function define(constructor,factory,prototype){constructor.prototype=factory.prototype=prototype;prototype.constructor=constructor;}function extend$4(parent,definition){var prototype=Object.create(parent.prototype);for(var key in definition)prototype[key]=definition[key];return prototype;}function Color$1(){}var darker=0.7;var brighter=1/darker;var reI="\\s*([+-]?\\d+)\\s*",reN="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",reP="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",reHex=/^#([0-9a-f]{3,8})$/,reRgbInteger=new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`),reRgbPercent=new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`),reRgbaInteger=new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`),reRgbaPercent=new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`),reHslPercent=new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`),reHslaPercent=new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`);var named={aliceblue:0xf0f8ff,antiquewhite:0xfaebd7,aqua:0x00ffff,aquamarine:0x7fffd4,azure:0xf0ffff,beige:0xf5f5dc,bisque:0xffe4c4,black:0x000000,blanchedalmond:0xffebcd,blue:0x0000ff,blueviolet:0x8a2be2,brown:0xa52a2a,burlywood:0xdeb887,cadetblue:0x5f9ea0,chartreuse:0x7fff00,chocolate:0xd2691e,coral:0xff7f50,cornflowerblue:0x6495ed,cornsilk:0xfff8dc,crimson:0xdc143c,cyan:0x00ffff,darkblue:0x00008b,darkcyan:0x008b8b,darkgoldenrod:0xb8860b,darkgray:0xa9a9a9,darkgreen:0x006400,darkgrey:0xa9a9a9,darkkhaki:0xbdb76b,darkmagenta:0x8b008b,darkolivegreen:0x556b2f,darkorange:0xff8c00,darkorchid:0x9932cc,darkred:0x8b0000,darksalmon:0xe9967a,darkseagreen:0x8fbc8f,darkslateblue:0x483d8b,darkslategray:0x2f4f4f,darkslategrey:0x2f4f4f,darkturquoise:0x00ced1,darkviolet:0x9400d3,deeppink:0xff1493,deepskyblue:0x00bfff,dimgray:0x696969,dimgrey:0x696969,dodgerblue:0x1e90ff,firebrick:0xb22222,floralwhite:0xfffaf0,forestgreen:0x228b22,fuchsia:0xff00ff,gainsboro:0xdcdcdc,ghostwhite:0xf8f8ff,gold:0xffd700,goldenrod:0xdaa520,gray:0x808080,green:0x008000,greenyellow:0xadff2f,grey:0x808080,honeydew:0xf0fff0,hotpink:0xff69b4,indianred:0xcd5c5c,indigo:0x4b0082,ivory:0xfffff0,khaki:0xf0e68c,lavender:0xe6e6fa,lavenderblush:0xfff0f5,lawngreen:0x7cfc00,lemonchiffon:0xfffacd,lightblue:0xadd8e6,lightcoral:0xf08080,lightcyan:0xe0ffff,lightgoldenrodyellow:0xfafad2,lightgray:0xd3d3d3,lightgreen:0x90ee90,lightgrey:0xd3d3d3,lightpink:0xffb6c1,lightsalmon:0xffa07a,lightseagreen:0x20b2aa,lightskyblue:0x87cefa,lightslategray:0x778899,lightslategrey:0x778899,lightsteelblue:0xb0c4de,lightyellow:0xffffe0,lime:0x00ff00,limegreen:0x32cd32,linen:0xfaf0e6,magenta:0xff00ff,maroon:0x800000,mediumaquamarine:0x66cdaa,mediumblue:0x0000cd,mediumorchid:0xba55d3,mediumpurple:0x9370db,mediumseagreen:0x3cb371,mediumslateblue:0x7b68ee,mediumspringgreen:0x00fa9a,mediumturquoise:0x48d1cc,mediumvioletred:0xc71585,midnightblue:0x191970,mintcream:0xf5fffa,mistyrose:0xffe4e1,moccasin:0xffe4b5,navajowhite:0xffdead,navy:0x000080,oldlace:0xfdf5e6,olive:0x808000,olivedrab:0x6b8e23,orange:0xffa500,orangered:0xff4500,orchid:0xda70d6,palegoldenrod:0xeee8aa,palegreen:0x98fb98,paleturquoise:0xafeeee,palevioletred:0xdb7093,papayawhip:0xffefd5,peachpuff:0xffdab9,peru:0xcd853f,pink:0xffc0cb,plum:0xdda0dd,powderblue:0xb0e0e6,purple:0x800080,rebeccapurple:0x663399,red:0xff0000,rosybrown:0xbc8f8f,royalblue:0x4169e1,saddlebrown:0x8b4513,salmon:0xfa8072,sandybrown:0xf4a460,seagreen:0x2e8b57,seashell:0xfff5ee,sienna:0xa0522d,silver:0xc0c0c0,skyblue:0x87ceeb,slateblue:0x6a5acd,slategray:0x708090,slategrey:0x708090,snow:0xfffafa,springgreen:0x00ff7f,steelblue:0x4682b4,tan:0xd2b48c,teal:0x008080,thistle:0xd8bfd8,tomato:0xff6347,turquoise:0x40e0d0,violet:0xee82ee,wheat:0xf5deb3,white:0xffffff,whitesmoke:0xf5f5f5,yellow:0xffff00,yellowgreen:0x9acd32};define(Color$1,color,{copy(channels){return Object.assign(new this.constructor(),this,channels);},displayable(){return this.rgb().displayable();},hex:color_formatHex,// Deprecated! Use color.formatHex.
	formatHex:color_formatHex,formatHex8:color_formatHex8,formatHsl:color_formatHsl,formatRgb:color_formatRgb,toString:color_formatRgb});function color_formatHex(){return this.rgb().formatHex();}function color_formatHex8(){return this.rgb().formatHex8();}function color_formatHsl(){return hslConvert(this).formatHsl();}function color_formatRgb(){return this.rgb().formatRgb();}function color(format){var m,l;format=(format+"").trim().toLowerCase();return (m=reHex.exec(format))?(l=m[1].length,m=parseInt(m[1],16),l===6?rgbn(m)// #ff0000
	:l===3?new Rgb(m>>8&0xf|m>>4&0xf0,m>>4&0xf|m&0xf0,(m&0xf)<<4|m&0xf,1)// #f00
	:l===8?rgba$1(m>>24&0xff,m>>16&0xff,m>>8&0xff,(m&0xff)/0xff)// #ff000000
	:l===4?rgba$1(m>>12&0xf|m>>8&0xf0,m>>8&0xf|m>>4&0xf0,m>>4&0xf|m&0xf0,((m&0xf)<<4|m&0xf)/0xff)// #f000
	:null// invalid hex
	):(m=reRgbInteger.exec(format))?new Rgb(m[1],m[2],m[3],1)// rgb(255, 0, 0)
	:(m=reRgbPercent.exec(format))?new Rgb(m[1]*255/100,m[2]*255/100,m[3]*255/100,1)// rgb(100%, 0%, 0%)
	:(m=reRgbaInteger.exec(format))?rgba$1(m[1],m[2],m[3],m[4])// rgba(255, 0, 0, 1)
	:(m=reRgbaPercent.exec(format))?rgba$1(m[1]*255/100,m[2]*255/100,m[3]*255/100,m[4])// rgb(100%, 0%, 0%, 1)
	:(m=reHslPercent.exec(format))?hsla$1(m[1],m[2]/100,m[3]/100,1)// hsl(120, 50%, 50%)
	:(m=reHslaPercent.exec(format))?hsla$1(m[1],m[2]/100,m[3]/100,m[4])// hsla(120, 50%, 50%, 1)
	:named.hasOwnProperty(format)?rgbn(named[format])// eslint-disable-line no-prototype-builtins
	:format==="transparent"?new Rgb(NaN,NaN,NaN,0):null;}function rgbn(n){return new Rgb(n>>16&0xff,n>>8&0xff,n&0xff,1);}function rgba$1(r,g,b,a){if(a<=0)r=g=b=NaN;return new Rgb(r,g,b,a);}function rgbConvert(o){if(!(o instanceof Color$1))o=color(o);if(!o)return new Rgb();o=o.rgb();return new Rgb(o.r,o.g,o.b,o.opacity);}function rgb$1(r,g,b,opacity){return arguments.length===1?rgbConvert(r):new Rgb(r,g,b,opacity==null?1:opacity);}function Rgb(r,g,b,opacity){this.r=+r;this.g=+g;this.b=+b;this.opacity=+opacity;}define(Rgb,rgb$1,extend$4(Color$1,{brighter(k){k=k==null?brighter:Math.pow(brighter,k);return new Rgb(this.r*k,this.g*k,this.b*k,this.opacity);},darker(k){k=k==null?darker:Math.pow(darker,k);return new Rgb(this.r*k,this.g*k,this.b*k,this.opacity);},rgb(){return this;},clamp(){return new Rgb(clampi(this.r),clampi(this.g),clampi(this.b),clampa(this.opacity));},displayable(){return  -0.5<=this.r&&this.r<255.5&&-0.5<=this.g&&this.g<255.5&&-0.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1;},hex:rgb_formatHex,// Deprecated! Use color.formatHex.
	formatHex:rgb_formatHex,formatHex8:rgb_formatHex8,formatRgb:rgb_formatRgb,toString:rgb_formatRgb}));function rgb_formatHex(){return `#${hex$2(this.r)}${hex$2(this.g)}${hex$2(this.b)}`;}function rgb_formatHex8(){return `#${hex$2(this.r)}${hex$2(this.g)}${hex$2(this.b)}${hex$2((isNaN(this.opacity)?1:this.opacity)*255)}`;}function rgb_formatRgb(){const a=clampa(this.opacity);return `${a===1?"rgb(":"rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a===1?")":`, ${a})`}`;}function clampa(opacity){return isNaN(opacity)?1:Math.max(0,Math.min(1,opacity));}function clampi(value){return Math.max(0,Math.min(255,Math.round(value)||0));}function hex$2(value){value=clampi(value);return (value<16?"0":"")+value.toString(16);}function hsla$1(h,s,l,a){if(a<=0)h=s=l=NaN;else if(l<=0||l>=1)h=s=NaN;else if(s<=0)h=NaN;return new Hsl(h,s,l,a);}function hslConvert(o){if(o instanceof Hsl)return new Hsl(o.h,o.s,o.l,o.opacity);if(!(o instanceof Color$1))o=color(o);if(!o)return new Hsl();if(o instanceof Hsl)return o;o=o.rgb();var r=o.r/255,g=o.g/255,b=o.b/255,min=Math.min(r,g,b),max=Math.max(r,g,b),h=NaN,s=max-min,l=(max+min)/2;if(s){if(r===max)h=(g-b)/s+(g<b)*6;else if(g===max)h=(b-r)/s+2;else h=(r-g)/s+4;s/=l<0.5?max+min:2-max-min;h*=60;}else {s=l>0&&l<1?0:h;}return new Hsl(h,s,l,o.opacity);}function hsl$1(h,s,l,opacity){return arguments.length===1?hslConvert(h):new Hsl(h,s,l,opacity==null?1:opacity);}function Hsl(h,s,l,opacity){this.h=+h;this.s=+s;this.l=+l;this.opacity=+opacity;}define(Hsl,hsl$1,extend$4(Color$1,{brighter(k){k=k==null?brighter:Math.pow(brighter,k);return new Hsl(this.h,this.s,this.l*k,this.opacity);},darker(k){k=k==null?darker:Math.pow(darker,k);return new Hsl(this.h,this.s,this.l*k,this.opacity);},rgb(){var h=this.h%360+(this.h<0)*360,s=isNaN(h)||isNaN(this.s)?0:this.s,l=this.l,m2=l+(l<0.5?l:1-l)*s,m1=2*l-m2;return new Rgb(hsl2rgb(h>=240?h-240:h+120,m1,m2),hsl2rgb(h,m1,m2),hsl2rgb(h<120?h+240:h-120,m1,m2),this.opacity);},clamp(){return new Hsl(clamph(this.h),clampt(this.s),clampt(this.l),clampa(this.opacity));},displayable(){return (0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1;},formatHsl(){const a=clampa(this.opacity);return `${a===1?"hsl(":"hsla("}${clamph(this.h)}, ${clampt(this.s)*100}%, ${clampt(this.l)*100}%${a===1?")":`, ${a})`}`;}}));function clamph(value){value=(value||0)%360;return value<0?value+360:value;}function clampt(value){return Math.max(0,Math.min(1,value||0));}/* From FvD 13.37, CSS Color Module Level 3 */function hsl2rgb(h,m1,m2){return (h<60?m1+(m2-m1)*h/60:h<180?m2:h<240?m1+(m2-m1)*(240-h)/60:m1)*255;}var constant$1=x=>()=>x;function linear$1(a,d){return function(t){return a+t*d;};}function exponential(a,b,y){return a=Math.pow(a,y),b=Math.pow(b,y)-a,y=1/y,function(t){return Math.pow(a+t*b,y);};}function gamma(y){return (y=+y)===1?nogamma:function(a,b){return b-a?exponential(a,b,y):constant$1(isNaN(a)?b:a);};}function nogamma(a,b){var d=b-a;return d?linear$1(a,d):constant$1(isNaN(a)?b:a);}var rgb$2=function rgbGamma(y){var color=gamma(y);function rgb(start,end){var r=color((start=rgb$1(start)).r,(end=rgb$1(end)).r),g=color(start.g,end.g),b=color(start.b,end.b),opacity=nogamma(start.opacity,end.opacity);return function(t){start.r=r(t);start.g=g(t);start.b=b(t);start.opacity=opacity(t);return start+"";};}rgb.gamma=rgbGamma;return rgb;}(1);function numberArray(a,b){if(!b)b=[];var n=a?Math.min(b.length,a.length):0,c=b.slice(),i;return function(t){for(i=0;i<n;++i)c[i]=a[i]*(1-t)+b[i]*t;return c;};}function isNumberArray$1(x){return ArrayBuffer.isView(x)&&!(x instanceof DataView);}function genericArray$1(a,b){var nb=b?b.length:0,na=a?Math.min(nb,a.length):0,x=new Array(na),c=new Array(nb),i;for(i=0;i<na;++i)x[i]=interpolate$1(a[i],b[i]);for(;i<nb;++i)c[i]=b[i];return function(t){for(i=0;i<na;++i)c[i]=x[i](t);return c;};}function date(a,b){var d=new Date();return a=+a,b=+b,function(t){return d.setTime(a*(1-t)+b*t),d;};}function number$1(a,b){return a=+a,b=+b,function(t){return a*(1-t)+b*t;};}function object$1(a,b){var i={},c={},k;if(a===null||typeof a!=="object")a={};if(b===null||typeof b!=="object")b={};for(k in b){if(k in a){i[k]=interpolate$1(a[k],b[k]);}else {c[k]=b[k];}}return function(t){for(k in i)c[k]=i[k](t);return c;};}var reA=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,reB=new RegExp(reA.source,"g");function zero(b){return function(){return b;};}function one(b){return function(t){return b(t)+"";};}function string(a,b){var bi=reA.lastIndex=reB.lastIndex=0,// scan index for next number in b
	am,// current match in a
	bm,// current match in b
	bs,// string preceding current number in b, if any
	i=-1,// index in s
	s=[],// string constants and placeholders
	q=[];// number interpolators
	// Coerce inputs to strings.
	a=a+"",b=b+"";// Interpolate pairs of numbers in a & b.
	while((am=reA.exec(a))&&(bm=reB.exec(b))){if((bs=bm.index)>bi){// a string precedes the next number in b
	bs=b.slice(bi,bs);if(s[i])s[i]+=bs;// coalesce with previous string
	else s[++i]=bs;}if((am=am[0])===(bm=bm[0])){// numbers in a & b match
	if(s[i])s[i]+=bm;// coalesce with previous string
	else s[++i]=bm;}else {// interpolate non-matching numbers
	s[++i]=null;q.push({i:i,x:number$1(am,bm)});}bi=reB.lastIndex;}// Add remains of b.
	if(bi<b.length){bs=b.slice(bi);if(s[i])s[i]+=bs;// coalesce with previous string
	else s[++i]=bs;}// Special optimization for only a single match.
	// Otherwise, interpolate each of the numbers and rejoin the string.
	return s.length<2?q[0]?one(q[0].x):zero(b):(b=q.length,function(t){for(var i=0,o;i<b;++i)s[(o=q[i]).i]=o.x(t);return s.join("");});}function interpolate$1(a,b){var t=typeof b,c;return b==null||t==="boolean"?constant$1(b):(t==="number"?number$1:t==="string"?(c=color(b))?(b=c,rgb$2):string:b instanceof color?rgb$2:b instanceof Date?date:isNumberArray$1(b)?numberArray:Array.isArray(b)?genericArray$1:typeof b.valueOf!=="function"&&typeof b.toString!=="function"||isNaN(b)?object$1:number$1)(a,b);}function interpolateRound(a,b){return a=+a,b=+b,function(t){return Math.round(a*(1-t)+b*t);};}function constants$1(x){return function(){return x;};}function number(x){return +x;}var unit=[0,1];function identity(x){return x;}function normalize$1(a,b){return (b-=a=+a)?function(x){return (x-a)/b;}:constants$1(isNaN(b)?NaN:0.5);}function clamper(a,b){var t;if(a>b)t=a,a=b,b=t;return function(x){return Math.max(a,Math.min(b,x));};}// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
	// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].
	function bimap(domain,range,interpolate){var d0=domain[0],d1=domain[1],r0=range[0],r1=range[1];if(d1<d0)d0=normalize$1(d1,d0),r0=interpolate(r1,r0);else d0=normalize$1(d0,d1),r0=interpolate(r0,r1);return function(x){return r0(d0(x));};}function polymap(domain,range,interpolate){var j=Math.min(domain.length,range.length)-1,d=new Array(j),r=new Array(j),i=-1;// Reverse descending domains.
	if(domain[j]<domain[0]){domain=domain.slice().reverse();range=range.slice().reverse();}while(++i<j){d[i]=normalize$1(domain[i],domain[i+1]);r[i]=interpolate(range[i],range[i+1]);}return function(x){var i=bisect(domain,x,1,j)-1;return r[i](d[i](x));};}function copy(source,target){return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown());}function transformer(){var domain=unit,range=unit,interpolate=interpolate$1,transform,untransform,unknown,clamp=identity,piecewise,output,input;function rescale(){var n=Math.min(domain.length,range.length);if(clamp!==identity)clamp=clamper(domain[0],domain[n-1]);piecewise=n>2?polymap:bimap;output=input=null;return scale;}function scale(x){return x==null||isNaN(x=+x)?unknown:(output||(output=piecewise(domain.map(transform),range,interpolate)))(transform(clamp(x)));}scale.invert=function(y){return clamp(untransform((input||(input=piecewise(range,domain.map(transform),number$1)))(y)));};scale.domain=function(_){return arguments.length?(domain=Array.from(_,number),rescale()):domain.slice();};scale.range=function(_){return arguments.length?(range=Array.from(_),rescale()):range.slice();};scale.rangeRound=function(_){return range=Array.from(_),interpolate=interpolateRound,rescale();};scale.clamp=function(_){return arguments.length?(clamp=_?true:identity,rescale()):clamp!==identity;};scale.interpolate=function(_){return arguments.length?(interpolate=_,rescale()):interpolate;};scale.unknown=function(_){return arguments.length?(unknown=_,scale):unknown;};return function(t,u){transform=t,untransform=u;return rescale();};}function continuous(){return transformer()(identity,identity);}function tickFormat(start,stop,count,specifier){var step=tickStep(start,stop,count),precision;specifier=formatSpecifier(specifier==null?",f":specifier);switch(specifier.type){case "s":{var value=Math.max(Math.abs(start),Math.abs(stop));if(specifier.precision==null&&!isNaN(precision=precisionPrefix(step,value)))specifier.precision=precision;return formatPrefix(specifier,value);}case "":case "e":case "g":case "p":case "r":{if(specifier.precision==null&&!isNaN(precision=precisionRound(step,Math.max(Math.abs(start),Math.abs(stop)))))specifier.precision=precision-(specifier.type==="e");break;}case "f":case "%":{if(specifier.precision==null&&!isNaN(precision=precisionFixed(step)))specifier.precision=precision-(specifier.type==="%")*2;break;}}return format(specifier);}function linearish(scale){var domain=scale.domain;scale.ticks=function(count){var d=domain();return ticks(d[0],d[d.length-1],count==null?10:count);};scale.tickFormat=function(count,specifier){var d=domain();return tickFormat(d[0],d[d.length-1],count==null?10:count,specifier);};scale.nice=function(count){if(count==null)count=10;var d=domain();var i0=0;var i1=d.length-1;var start=d[i0];var stop=d[i1];var prestep;var step;var maxIter=10;if(stop<start){step=start,start=stop,stop=step;step=i0,i0=i1,i1=step;}while(maxIter-->0){step=tickIncrement(start,stop,count);if(step===prestep){d[i0]=start;d[i1]=stop;return domain(d);}else if(step>0){start=Math.floor(start/step)*step;stop=Math.ceil(stop/step)*step;}else if(step<0){start=Math.ceil(start*step)/step;stop=Math.floor(stop*step)/step;}else {break;}prestep=step;}return scale;};return scale;}function linear(){var scale=continuous();scale.copy=function(){return copy(scale,linear());};initRange.apply(scale,arguments);return linearish(scale);}function threshold(){var domain=[0.5],range=[0,1],unknown,n=1;function scale(x){return x!=null&&x<=x?range[bisect(domain,x,0,n)]:unknown;}scale.domain=function(_){return arguments.length?(domain=Array.from(_),n=Math.min(domain.length,range.length-1),scale):domain.slice();};scale.range=function(_){return arguments.length?(range=Array.from(_),n=Math.min(domain.length,range.length-1),scale):range.slice();};scale.invertExtent=function(y){var i=range.indexOf(y);return [domain[i-1],domain[i]];};scale.unknown=function(_){return arguments.length?(unknown=_,scale):unknown;};scale.copy=function(){return threshold().domain(domain).range(range).unknown(unknown);};return initRange.apply(scale,arguments);}function applyFormat(formatter){return typeof formatter==='undefined'?t=>t:t=>formatter(t);}function clamp$1(val){return Math.max(0,Math.min(1,val));}function isObject$1(obj){return typeof obj==='object';}function minorTicksGenerator(count,start,end){const r=Math.abs(start-end);const interval=r/(count+1);const ticks=[];for(let i=1;i<=count;i++){const v=i*interval;ticks.push(start<end?start+v:start-v);}return ticks;}function appendMinorTicks(majorTicks,minorCount,scale){if(majorTicks.length===1){return majorTicks;}const ticks=majorTicks.concat([]);for(let i=0;i<majorTicks.length;i++){let start=majorTicks[i];let end=majorTicks[i+1];if(i===0&&start!==scale.start()){// Before and after first major tick
	ticks.push(...minorTicksGenerator(minorCount,start,end));start-=end-start;end=majorTicks[i];ticks.push(...minorTicksGenerator(minorCount,start,end));}else if(i===majorTicks.length-1&&end!==scale.end()){// After last major tick
	end=start+(start-majorTicks[i-1]);ticks.push(...minorTicksGenerator(minorCount,start,end));}else {ticks.push(...minorTicksGenerator(minorCount,start,end));}}return ticks.filter(t=>t>=scale.min()&&t<=scale.max());}/**
	 * Generate ticks based on a distance, for each 100th unit, one additional tick may be added
	 * @private
	 * @param  {Number} distance       Distance between each tick
	 * @param  {Number} scale         The scale instance
	 * @param  {Number} [minorCount=0]     Number of tick added between each distance
	 * @param  {Number} [unitDivider=100]   Number to divide distance with
	 * @return {Array}               Array of ticks
	 */function looseDistanceBasedGenerator(_ref){let{distance,scale,minorCount=0,unitDivider=100,formatter=undefined}=_ref;const step=!notNumber(unitDivider)&&!notNumber(distance)?Math.max(distance/unitDivider,2):2;const count=Math.min(1000,Math.round(step));// safe guard against huge numbers
	let majorTicks=scale.ticks(count);if(majorTicks.length<=1){majorTicks=scale.ticks(count+1);}const ticks=minorCount>0?appendMinorTicks(majorTicks,minorCount,scale):majorTicks;ticks.sort((a,b)=>a-b);const ticksFormatted=ticks.map(applyFormat(formatter));return ticks.map((tick,i)=>{const position=scale(tick);return {position,start:position,end:position,label:ticksFormatted[i],value:tick,isMinor:majorTicks.indexOf(tick)===-1};});}/**
	 * Generate ticks based on a distance, for each 100th unit, one additional tick may be added.
	 * Will attempt to round the bounds of domain to even values and generate ticks hitting the domain bounds.
	 * @private
	 * @param  {Number} distance       Distance between each tick
	 * @param  {Number} scale         The scale instance
	 * @param  {Number} [minorCount=0]     Number of tick added between each distance
	 * @param  {Number} [unitDivider=100]   Number to divide distance with
	 * @return {Array}               Array of ticks
	 */function tightDistanceBasedGenerator(_ref2){let{distance,scale,minorCount=0,unitDivider=100,formatter=undefined}=_ref2;const step=!notNumber(unitDivider)&&!notNumber(distance)?Math.max(distance/unitDivider,2):2;const count=Math.min(1000,Math.round(step));// safe guard against huge numbers
	const n=count>10?10:count;scale.nice(n);const majorTicks=scale.ticks(count);const ticks=minorCount>0?appendMinorTicks(majorTicks,minorCount,scale):majorTicks;ticks.sort((a,b)=>a-b);const ticksFormatted=ticks.map(applyFormat(formatter));return ticks.map((tick,i)=>{const position=scale(tick);return {position,start:position,end:position,label:ticksFormatted[i],value:tick,isMinor:majorTicks.indexOf(tick)===-1};});}function ticksByCount(_ref3){let{count,minorCount,scale,formatter}=_ref3;return scale.ticks((count-1)*minorCount+count).map((tick,i)=>{const position=scale(tick);return {position,start:position,end:position,label:formatter(tick),isMinor:i%(minorCount+1)!==0,value:tick};});}function ticksByValue(_ref4){let{values,scale,formatter=v=>v}=_ref4;return values.sort((a,b)=>(isObject$1(a)?a.value:a)-(isObject$1(b)?b.value:b)).filter((v,i,ary)=>{const val=isObject$1(v)?v.value:v;return val<=scale.max()&&val>=scale.min()&&ary.indexOf(v)===i;}).map(v=>{const isObj=isObject$1(v);const value=isObj?v.value:v;const position=scale(value);return {position,value,label:isObj&&typeof v.label!=='undefined'?v.label:formatter(value),isMinor:isObj?!!v.isMinor:false,start:isObj&&!isNaN(v.start)?clamp$1(scale(v.start)):position,// TODOHandle end < start?
	end:isObj&&!isNaN(v.end)?clamp$1(scale(v.end)):position// TODO Handle start > end?
	};});}function forceTicksAtBounds(ticks,scale,formatter){const ticksP=ticks.map(t=>t.position);const range=scale.range();if(ticksP.indexOf(range[0])===-1){ticks.splice(0,0,{position:range[0],start:range[0],end:range[0],label:formatter(scale.start()),isMinor:false,value:scale.start()});}else if(ticks[0]&&ticks[0].isMinor){ticks[0].isMinor=false;// Convert to major tick
	}const lastTick=ticks[ticks.length-1];if(ticksP.indexOf(range[1])===-1){ticks.push({position:range[1],start:range[1],end:range[1],label:formatter(scale.end()),isMinor:false,value:scale.end()});}else if(lastTick&&lastTick.isMinor){lastTick.isMinor=false;// Convert to major tick
	}}function generateContinuousTicks(_ref5){let{settings,scale,distance,formatter=val=>val}=_ref5;let ticks;const minorCount=settings.minorTicks&&!notNumber(settings.minorTicks.count)?Math.min(100,settings.minorTicks.count):0;if(Array.isArray(settings.ticks.values)){const values=settings.ticks.values.filter(v=>typeof v==='object'?!notNumber(v.value):!notNumber(v));ticks=ticksByValue({values,scale:scale.copy(),formatter});}else if(!notNumber(settings.ticks.count)){const count=Math.min(1000,settings.ticks.count);ticks=ticksByCount({count,minorCount,scale:scale.copy(),formatter});}else {const tickGen=settings.ticks.tight?tightDistanceBasedGenerator:looseDistanceBasedGenerator;ticks=tickGen({distance,minorCount,unitDivider:settings.ticks.distance,scale,formatter});if(settings.ticks.forceBounds){forceTicksAtBounds(ticks,scale,formatter);}}return ticks;}function generateDiscreteTicks(_ref6){let{scale}=_ref6;const domain=scale.domain();const values=domain;const dataItems=scale.data().items;const labels=scale.labels?scale.labels():values;const bandwidth=scale.bandwidth();return values.map((d,i)=>{const start=scale(d);return {position:start+bandwidth/2,label:"".concat(labels[i]),data:dataItems?dataItems[i]:undefined,start,end:start+bandwidth};});}function resolveSettings$2(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let defaultSettings=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let context=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const stngs={};Object.keys(defaultSettings).forEach(key=>{const type=typeof settings[key];if(type==='function'){stngs[key]=settings[key](context);}else if(type==='undefined'){stngs[key]=defaultSettings[key];}else {stngs[key]=settings[key];}});return stngs;}const DEFAULT_SETTINGS$8={min:NaN,max:NaN,expand:NaN,include:[],invert:false};const DEFAULT_TICKS_SETTINGS$1={tight:false,forceBounds:false,values:undefined,count:NaN,distance:100};const DEFAULT_MINORTICKS_SETTINGS={count:NaN};/**
	 * @typedef {object} ScaleLinear
	 * @property {string} [type='linear']
	 * @property {number} [expand] - Expand the output range
	 * @property {boolean} [invert=false] - Invert the output range
	 * @property {number[]} [include] - Include specified numbers in the output range
	 * @property {object} [ticks]
	 * @property {boolean} [ticks.tight = false]
	 * @property {boolean} [ticks.forceBounds = false]
	 * @property {number} [ticks.distance = 100]  - Approximate distance between each tick
	 * @property {number[]|object[]} [ticks.values] - If set, ticks are no longer generated but instead equal to this set
	 * @property {number} [ticks.count]
	 * @property {object} [minorTicks]
	 * @property {number} [minorTicks.count = 3]
	 * @property {number} [min] - Set an explicit minimum value
	 * @property {number} [max] - Set an explicit maximum value
	 */function getMinMax(settings,fields){const min=+settings.min;const max=+settings.max;let fieldMin=0;let fieldMax=1;if(fields&&fields[0]){const minValues=fields.map(m=>m.min()).filter(v=>!isNaN(v));const maxValues=fields.map(m=>m.max()).filter(v=>!isNaN(v));fieldMin=minValues.length?Math.min(...minValues):Number.NaN;fieldMax=maxValues.length?Math.max(...maxValues):Number.NaN;if(isNaN(fieldMin)||isNaN(fieldMax)){fieldMin=-1;fieldMax=1;}else if(fieldMin===fieldMax&&fieldMin===0){fieldMin=-1;fieldMax=1;}else if(fieldMin===fieldMax&&fieldMin){fieldMin-=Math.abs(fieldMin*0.1);fieldMax+=Math.abs(fieldMax*0.1);}else if(!isNaN(settings.expand)){const range=fieldMax-fieldMin;fieldMin-=range*settings.expand;fieldMax+=range*settings.expand;}if(Array.isArray(settings.include)){const i=settings.include.filter(n=>!isNaN(n));fieldMin=Math.min(...i,fieldMin);fieldMax=Math.max(...i,fieldMax);}}return {mini:!isNaN(min)?min:fieldMin,maxi:!isNaN(max)?max:fieldMax};}function initNormScale(normScale,scale){if(normScale.instance){return;}normScale.instance=scale.copy();normScale.instance.domain([scale.start(),scale.end()]);normScale.instance.clamp(true);normScale.instance.range(normScale.invert?[1,0]:[0,1]);}/**
	 * @alias scaleLinear
	 * @private
	 * @param { object } settings
	 * @param { field[] } [fields]
	 * @return { linear }
	 */function scaleLinear(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const d3Scale=linear();const normScale={instance:null,invert:false};const ctx={data,resources};const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$8,ctx);stgns.ticks=resolveSettings$2(settings.ticks,DEFAULT_TICKS_SETTINGS$1,ctx);stgns.minorTicks=resolveSettings$2(settings.minorTicks,DEFAULT_MINORTICKS_SETTINGS,ctx);let tickCache;/**
	   * @alias linear
	   * @private
	   * @param { Object } value
	   * @return { number }
	   */function fn(v){if(notNumber(v)){return NaN;}return d3Scale(v);}fn.data=()=>data;/**
	   * {@link https://github.com/d3/d3-scale#continuous_invert }
	   * @param { number } value The inverted value
	   * @return { number } The inverted scaled value
	   */fn.invert=function invert(value){return d3Scale.invert(value);};/**
	   * {@link https://github.com/d3/d3-scale#continuous_rangeRound }
	   * @param { number[] } values Range values
	   * @return { linear } The instance this method was called on
	   */fn.rangeRound=function rangeRound(values){d3Scale.rangeRound(values);return fn;};/**
	   * {@link https://github.com/d3/d3-scale#continuous_clamp }
	   * @param { boolean } [ value=true ] TRUE if clamping should be enabled
	   * @return { linear } The instance this method was called on
	   */fn.clamp=function clamp(){let value=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;d3Scale.clamp(value);return fn;};/**
	   * Get cached ticks (if any)
	   * @return { number | undefined }
	   */fn.cachedTicks=function fnCachedTicks(){return tickCache;};/**
	   * Clear the tick cache
	   * @return {number | undefined}
	   */fn.clearTicksCache=function fnClearTicks(){tickCache=undefined;return this;};/**
	   * {@link https://github.com/d3/d3-scale#continuous_ticks }
	   * @param { Object } input Number of ticks to generate or an object passed to tick generator
	   * @return { number[] | Object } Array of ticks or any type the custom tick generator returns
	   */fn.ticks=function ticks(input){if(input!==null&&typeof input==='object'){input.settings=input.settings||{};// TODO Discontinue support for custom ticks settings as argument
	input.settings=extend$1$1(true,{},stgns,input.settings);input.scale=fn;tickCache=generateContinuousTicks(input);return tickCache;}tickCache=d3Scale.ticks(input);return tickCache;};/**
	   * {@link https://github.com/d3/d3-scale#continuous_nice }
	   * @param { number } count
	   * @return { linear } The instance this method was called on
	   */fn.nice=function nice(count){d3Scale.nice(count);return fn;};// TODO Support this?
	fn.tickFormat=function tickFormat(count,format){return d3Scale.tickFormat(count,format);};// TODO Support this?
	fn.interpolate=function interpolate(func){d3Scale.interpolate(func);return fn;};/**
	   * @param { number[] } [values] Set or Get domain values
	   * @return { linear | Number[] } The instance this method was called on if a parameter is provided, otherwise the current domain is returned
	   */fn.domain=function domain(values){if(arguments.length){d3Scale.domain(values);if(normScale.instance){normScale.instance.domain([fn.start(),fn.end()]);}return fn;}return d3Scale.domain();};/**
	   * @param { number[] } [values] Set or Get range values
	   * @return { linear | number[] } The instance this method was called on if a parameter is provided, otherwise the current range is returned
	   */fn.range=function range(values){if(arguments.length){d3Scale.range(values);return fn;}return d3Scale.range();};/**
	   * Get the first value of the domain
	   * @return { number }
	   */fn.start=function start(){return fn.domain()[0];};/**
	   * Get the last value of the domain
	   * @return { number }
	   */fn.end=function end(){return fn.domain()[this.domain().length-1];};/**
	   * Get the minimum value of the domain
	   * @return { number }
	   */fn.min=function min(){return Math.min(this.start(),this.end());};/**
	   * Get the maximum value of the domain
	   * @return { number }
	   */fn.max=function max(){return Math.max(this.start(),this.end());};/**
	   * Divides the domain and range into uniform segments, based on start and end value
	   * @param  { number } segments The number of segments
	   * @return { function } The instance this method was called on
	   * @example
	   * let s = linear();
	   * s.domain([0, 10]);
	   * s.range([0, 1]);
	   * s.classify( 2 );
	   * s.domain(); // [10, 5, 5, 0]
	   * s.range(); // [0.75, 0.75, 0.25, 0.25]
	   */fn.classify=function classify(segments){let valueRange=(fn.start()-fn.end())/segments,domain=[fn.end()],range=[],samplePos=valueRange/2;for(let i=0;i<segments;i++){let lastVal=domain[domain.length-1]||0,calIntervalPos=lastVal+valueRange,calSamplePos=lastVal+samplePos,sampleColValue=fn(calSamplePos);domain.push(...[calIntervalPos,calIntervalPos]);range.push(...[sampleColValue,sampleColValue]);}domain.pop();fn.domain(domain);fn.range(range);return fn;};fn.copy=function copy(){const cop=scaleLinear(settings,data,resources);cop.domain(fn.domain());cop.range(fn.range());cop.clamp(d3Scale.clamp());return cop;};/**
	   * @param {number} d - A domain value
	   * @return {number} A normalized range output given in range 0-1
	   * @example
	   * const scale = scaleLinear().domain([0, 10]).range([0, 10000]);
	   * scale.norm(5); // Returns 0.5
	   * scale(5); // Returns 5000
	   *
	   * scale.domain([0, 2, 10]);
	   * scale.norm(5); // Returns 0.5
	   */fn.norm=function norm(d){initNormScale(normScale,fn);return normScale.instance(d);};/**
	   * @param {number} d - A normalized value in range 0-1
	   * @return {number} A corresponding domain value
	   * @example
	   * const scale = scaleLinear().domain([0, 10]).range([0, 10000]);
	   * scale.normInvert(0.5); // Returns 5
	   * scale.invert(5000); // Returns 5
	   */fn.normInvert=function norm(t){initNormScale(normScale,fn);return normScale.instance.invert(t);};const{mini,maxi}=getMinMax(stgns,data?data.fields:[]);fn.domain([mini,maxi]);fn.range(stgns.invert?[1,0]:[0,1]);normScale.invert=stgns.invert;return fn;}const DEFAULT_SETTINGS$7={padding:0,paddingInner:NaN,paddingOuter:NaN,align:0.5,invert:false,maxPxStep:NaN,range:[0,1]};/**
	 * @typedef {object} ScaleBand
	 * @property {string} [type='band']
	 * @property {number} [padding=0] - Sets both inner and outer padding to the same value
	 * @property {number} [paddingInner=0] - Inner padding
	 * @property {number} [paddingOuter=0] - Outer padding
	 * @property {number} [align=0.5] -  Control how the outer padding should be distributed, where 0.5 would distribute the padding equally on both sides
	 * @property {boolean} [invert=false] - Invert the output range
	 * @property {number} [maxPxStep] - Explicitly limit the bandwidth to a pixel value
	 * @property {function} [label] - Callback label function, applied on each datum
	 * @property {function} [value] - Callback value function, applied on each datum
	 * @property {number[]|function} [range=[0, 1]] - Set range explicitly (ignored when maxPxStep takes effect)
	 *//**
	 * @alias scaleBand
	 * @memberof picasso
	 * @private
	 * @param { Object } settings
	 * @param { fields[] } [fields]
	 * @param { dataset } [dataset]
	 * @return { band }
	 */function scaleBand(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const ctx={data,resources};const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$7,ctx);const items=data.items||[];const domainToDataMapping={};const values=[];const labels=[];// I would like to define this outside of scaleBand but it cause the documentation to be in the wrong order
	function augmentScaleBand(band,fsettings){band.data=()=>data;band.datum=domainValue=>items[domainToDataMapping[domainValue]];/**
	     * Get the first value of the domain
	     * @return { number }
	     */band.start=function start(){return band.domain()[0];};/**
	     * Get the last value of the domain
	     * @return { number }
	     */band.end=function end(){return band.domain()[band.domain().length-1];};band.labels=()=>labels;/**
	     * Generate discrete ticks
	     * @return {Object[]} Array of ticks
	     */band.ticks=function ticks(){let input=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};input.scale=band;return generateDiscreteTicks(input,fsettings.trackBy||'label');};}/**
	   * An augmented {@link https://github.com/d3/d3-scale#_band|d3 band scale}
	   * @alias band
	   * @private
	   * @kind function
	   * @param { Object } value
	   * @return { number }
	   */const band$1=band();augmentScaleBand(band$1,settings);/**
	   * if required creates a new scale with a restricted range
	   * so that step size is at most maxPxStep
	   * otherwise it returns itself
	   * @param { number } size
	   * @return { band }
	   */band$1.pxScale=function pxScale(size){const max=stgns.maxPxStep;if(isNaN(max)){return band$1;}const n=band$1.domain().length;const sizeRelativeToStep=Math.max(1,n-band$1.paddingInner()+2*band$1.paddingOuter());if(sizeRelativeToStep*max>=size){return band$1;}const newBand=band$1.copy();newBand.type=band$1.type;augmentScaleBand(newBand,settings);const t=sizeRelativeToStep*max/size;const offset=(1-t)*band$1.align();newBand.range(stgns.invert?[t+offset,offset]:[offset,t+offset]);return newBand;};const valueFn=typeof settings.value==='function'?settings.value:d=>d.datum.value;const labelFn=typeof settings.label==='function'?settings.label:d=>d.datum.label;for(let i=0;i<items.length;i++){const arg=extend$1$1({datum:items[i]},ctx);const v=valueFn(arg,i);if(values.indexOf(v)===-1){values.push(v);labels.push(labelFn(arg,i));domainToDataMapping[v]=i;}}band$1.domain(values);band$1.range(stgns.invert?stgns.range.slice().reverse():stgns.range);band$1.padding(isNaN(stgns.padding)?0:stgns.padding);if(!isNaN(stgns.paddingInner)){band$1.paddingInner(stgns.paddingInner);}if(!isNaN(stgns.paddingOuter)){band$1.paddingOuter(stgns.paddingOuter);}band$1.align(isNaN(stgns.align)?0.5:stgns.align);return band$1;}const DEFAULT_TICKS_SETTINGS={depth:0};function keyGen(node,valueFn,ctx){return node.ancestors().map(a=>valueFn(extend$1$1({datum:a.data},ctx))).reverse().slice(1)// Delete root node
	.toString();}function flattenTree$1(rootNode,settings,ctx){const ticksDepth=settings.ticks.depth;const valueFn=settings.value;const labelFn=settings.label;const values=[];const labels=[];const items={};const ticks=[];let expando=0;if(!rootNode){return {values,labels,items,ticks};}rootNode.eachAfter(node=>{if(node.depth>0){const key=keyGen(node,valueFn,ctx);const leaves=node.leaves()||[node];// If leaf node returns itself
	const value=valueFn(extend$1$1({datum:node.data},ctx));const label=labelFn(extend$1$1({datum:node.data},ctx));const isBranch=Array.isArray(node.children);const item={key,count:leaves.length,value,label,leftEdge:keyGen(leaves[0],valueFn,ctx),rightEdge:keyGen(leaves[Math.max(leaves.length-1,0)],valueFn,ctx),node// isTick: ticksDepth === null ? !isBranch : node.depth === ticksDepth
	};if(isBranch){values.push("SPACER_".concat(expando,"_SPACER"));expando++;}else {values.push(key);labels.push(label);}if(ticksDepth<=0&&!isBranch||node.depth===ticksDepth){ticks.push(item);}items[key]=item;}});const spill=rootNode.height-1;if(spill>0){values.splice(-spill);}return {values,labels,items,ticks};}/**
	 * @typedef {object} scale-hBand.settings
	 * @private
	 * @property {number} [padding=0] - Exposes {@link https://github.com/d3/d3-scale#band_padding}
	 * @property {boolean} [paddingOuter=0] - Exposes {@link https://github.com/d3/d3-scale#band_paddingOuter}
	 * @property {number[]} [paddingInner=0] - Exposes {@link https://github.com/d3/d3-scale#band_paddingInner}
	 * @property {object} [align=0.5] - Exposes {@link https://github.com/d3/d3-scale#band_align}
	 * @property {boolean} [invert=false] - Invert the output range
	 *//**
	 * Hierarchical band scale, that is an augmented band scale, that takes hierarchical data as input
	 * @alias scaleHierarchicalBand
	 * @private
	 * @param { Object } settings
	 * @param { fields[] } [fields]
	 * @param { dataset } [dataset] - With a root property that is an instance of D3.js Hierarchy
	 * @return { h-band }
	 */function scaleHierarchicalBand(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const ctx={data,resources};const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$7,ctx);stgns.ticks=resolveSettings$2(settings.ticks,DEFAULT_TICKS_SETTINGS,ctx);stgns.value=typeof settings.value==='function'?settings.value:d=>d.datum.value;stgns.label=typeof settings.label==='function'?settings.label:d=>d.datum.value;let bandInstance=scaleBand(stgns);const{values,labels,items,ticks}=flattenTree$1(data.root,stgns,ctx);/**
	   * @alias h-band
	   * @private
	   * @kind function
	   * @param { Object[] } value - Array where each value is a reference to a node, going from depth 1 to n.
	   * @return { number }
	   */const hBand=function fn(val){const strVal=String(val);const item=items[strVal];if(item){return bandInstance(stgns.invert?item.rightEdge:item.leftEdge);}return bandInstance(strVal);};extend$1$1(true,hBand,bandInstance);/**
	   * Wrapped {@link https://github.com/d3/d3-scale#band_bandwidth}
	   * @param { Object[] } [val] - Array where each value is a reference to a node, going from depth 1 to n. If omitted, bandwidth for the leaf nodes is return.
	   * @return { number }
	   */hBand.bandwidth=function bandwidth(val){const item=items[String(val)];const bw=bandInstance.bandwidth();if(item&&!item.isLeaf){const left=hBand(item.leftEdge);const right=hBand(item.rightEdge);return Math.abs(left-right)+bw;}return bw;};/**
	   * Wrapped {@link https://github.com/d3/d3-scale#band_step}
	   * @param { Object[] } [val] - Array where each value is a reference to a node, going from depth 1 to n. If omitted, step size for the leaf nodes is return.
	   * @return { number }
	   */hBand.step=function step(val){const item=items[String(val)];const leafCount=item?item.count:1;let stepSize=bandInstance.step();stepSize*=leafCount;return stepSize;};/**
	   * @return { dataset }
	   */hBand.data=()=>data;/**
	   * Return datum for a given node
	   * @param { Object[] } val - Array where each value is a reference to a node, going from depth 1 to n.
	   * @return { Object } The datum
	   */hBand.datum=val=>{const item=items[String(val)];if(item){return item.node.data;}return null;};hBand.copy=()=>scaleHierarchicalBand(settings,data,resources);/**
	   * @return { Object[] } Labels for each leaf node
	   */hBand.labels=()=>labels;/**
	   * Generate discrete ticks
	   * @return { Object[] } Ticks for each leaf node
	   */hBand.ticks=()=>// eslint-disable-line arrow-body-style
	ticks.map(item=>{const start=hBand(item.key);const bandwidth=hBand.bandwidth(item.key);return {position:start+bandwidth/2,label:item.label,data:item.node.data,start,end:start+bandwidth};});const orgPxScale=bandInstance.pxScale;hBand.pxScale=function pxScale(size){bandInstance=orgPxScale(size);return hBand;};hBand.domain(values);return hBand;}const minAccessor=v=>v.min();const maxAccessor=v=>v.max();/**
	 * Calculate the min/max value based on various inputs.
	 *
	 * Provided min/max setting takes presedence over all other inputs. If not provided, the respective values are calculated
	 * from the given arr input, where each item in the array is expected to have a min/max accessor.
	 *
	 * @private
	 * @param {object} [settings]
	 * @param {number} [settings.min] The minimum value. Defaults to 0 if not provided.
	 * @param {number} [settings.max] The maximum value. Defaults to 1 if not provided.
	 * @param {object} [arr]
	 * @returns { object[] } An array containing the min and max values.
	 *
	 * @example
	 * minmax(); // [0, 1]
	 *
	 * minmax({}, [
	 * { min: () => 13, max: () => 15 },
	 * { min: () => NaN, max: () => 17 },
	 * ]); // [13, 17]
	 *
	 * minmax({ min: -5, max: 4 }, [
	 * { min: () => -20, max: () => 15 },
	 * ]); // [-5, 4]
	 */function minmax(settings,arr){// const definedMin = settings && typeof settings.min !== 'undefined';
	// const definedMax = settings && typeof settings.max !== 'undefined';
	const definedMin=settings&&!isNaN(settings.min);const definedMax=settings&&!isNaN(settings.max);let min=definedMin?+settings.min:0;let max=definedMax?+settings.max:1;if(arr&&arr.length){if(!definedMin){const arrMin=arr.map(minAccessor).filter(isNumber);min=arrMin.length?Math.min(...arrMin):min;}if(!definedMax){const arrMax=arr.map(maxAccessor).filter(isNumber);max=arrMax.length?Math.max(...arrMax):max;}}return [min,max];}const DEFAULT_SETTINGS$6={domain:[],range:[],invert:false,min:NaN,max:NaN};function generateDomain$1(range,min,max){const len=range.length;if(len===2){return [min,max];}const domain=[];const part=(max-min)/(len-1);domain.push(min);for(let i=1;i<len-1;i++){domain.push(min+part*i);}domain.push(max);return domain;}/**
	 * @typedef {object} ScaleSequentialColor
	 * @property {string} [type='sequential-color']
	 * @property {string[]} [range] - CSS color values of the output range
	 * @property {boolean} [invert=false] - Invert range
	 * @property {number} [min] - Set an explicit minimum value
	 * @property {number} [max] - Set an explicit maximum value
	 *//**
	 * @alias scaleSequentialColor
	 * @private
	 * @param { Object } [settings] Settings for this scale. If both range and domain are specified, they have to fulfill range.length === domain.length, otherwise they will be overriden.
	 * @param { number[] } [settings.domain] Numeric values indicating stop limits between start and end values.
	 * @param { color[] } [settings.range] CSS color values indicating stop colors between start and end values.
	 * @param { field[] } [fields] Fields to dynamically calculate the domain extent.
	 * @return { sequentialColor }
	 *
	 * @example
	 * picasso.scaleSequentialColor({
	 *  range: ['red', '#fc6', 'green'],
	 *  domain: [-40, 0, 100]
	 * });
	 */function scaleSequentialColor(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const s=scaleLinear(settings,data,resources).clamp(true).interpolate(rgb$2);const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$6,{data,resources});const isDomain=Array.isArray(stgns.domain)&&stgns.domain.length;const isRange=Array.isArray(stgns.range)&&stgns.range.length;/**
	   * @alias sequentialColor
	   * @private
	   * @kind function
	   * @param { Object } v Object containing a 'value' property
	   * @return { string } The blended color
	   */const fn=s;extend$1$1(true,fn,s);const[min,max]=minmax(stgns,data?data.fields:[]);const num=isDomain?stgns.domain.length:-1;const DEFAULT_COLORS=resources.theme?resources.theme.palette('sequential',num>0?num:2):[];const range=isRange?stgns.range:DEFAULT_COLORS;fn.range(stgns.invert?range.slice().reverse():range.slice());fn.domain(isDomain?stgns.domain:generateDomain$1(fn.range(),min,max));return fn;}// const DEFAULT_COLORS = ['rgb(180,221,212)', 'rgb(34, 83, 90)'];
	const DEFAULT_SETTINGS$5={domain:[],range:[],invert:false,min:NaN,max:NaN,nice:false};function generateDomain(range,min,max){const len=range.length;if(len===2){return [min+(max-min)/2];}const domain=[];const part=(max-min)/len;for(let i=1;i<len;i++){domain.push(min+part*i);}return domain;}function getBreaks(domain){const ret=[];for(let i=0;i<domain.length-1;i++){ret.push((domain[i]+domain[i+1])/2);}return ret;}function generateRange(domain,colors,min,max){min=domain[0];max=domain&&domain.length>=2?domain[domain.length-1]:max;const seq=scaleSequentialColor().domain([min,max]).range(colors);const values=[min,...getBreaks(domain),max];return values.map(v=>seq(v));}function generateNiceDomain(range,min,max){const numPoints=range.length===2?10:Math.max(1,range.length);const lin=linear().domain([min,max]).nice(numPoints);const domain=lin.ticks(numPoints);if(!range||!range.length){return domain;}// remove values from endpoints
	const num=Math.max(0,range.length-1);while(domain.length>num){if(domain[0]-min<=max-domain[domain.length-1]){domain.shift();}else {domain.pop();}}return domain;}/**
	 * @typedef {object} ScaleThresholdColor
	 * @property {string} [type='threshold-color']
	 * @property {number[]} [domain] Values defining the thresholds
	 * @property {string[]} [range] - CSS color values of the output range
	 * @property {boolean} [invert=false] - Invert range
	 * @property {number} [min] - Set an explicit minimum value
	 * @property {number} [max] - Set an explicit maximum value
	 * @property {boolean} [nice=false] If set to true, will generate 'nice' domain values. Ignored if domain is set.
	 *//**
	 * @alias scaleThresholdColor
	 * @private
	 * @param { object } [settings] Settings for this scale. If both domain and range are specified, they have to fulfill domain.length === range.length + 1,  otherwise they will be overriden.
	 * @param { number[] } [settings.domain] Values defining the thresholds.
	 * @param { color[] } [settings.range] CSS color values of the output range.
	 * @param { boolean } [settings.nice=false] If set to true, will generate 'nice' domain values. Ignored if domain is set.
	 * @param { number } [settings.min] Minimum value to generate domain extent from. Ignored if domain is set.
	 * @param { number } [settings.max] Maximum value to generate domain extend from. Ignored if domain is set.
	 * @param { field[] } [fields] Fields to dynamically calculate the domain extent from. Ignored if min/max are set.
	 * @return { thresholdColor }
	 *
	 * @example
	 * let t = threshold({
	 *   range: ['black', 'white'],
	 *   domain: [25,50,75],
	 *   max: 100,
	 *   min: 0
	 * });
	 * t.domain(); // [25,50,75]
	 * t.range(); // Generates from colors and domain: ['rgb(0,0,0)','rgb(85,85,85)','rgb(170,170,170)','rgb(255,255,255)']
	 */function scaleThresholdColor(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const d3Scale=threshold();const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$5,{data,resources});const isDomain=Array.isArray(stgns.domain)&&stgns.domain.length;const isRange=Array.isArray(stgns.range)&&stgns.range.length;/**
	   * @alias thresholdColor
	   * @private
	   * @param { object } v Object literal containing a 'value' property.
	   * @return { string } A CSS color from the scale's range.
	   */function fn(v){if(notNumber(v)){return NaN;}return d3Scale(v);}Object.keys(d3Scale).forEach(key=>fn[key]=d3Scale[key]);const fields=data.fields;const[min,max]=minmax(stgns,fields);const num=isDomain?stgns.domain.length:-1;const DEFAULT_COLORS=resources.theme?resources.theme.palette('sequential',num>0?num:2):[];let range=isRange?stgns.range:DEFAULT_COLORS;let domain=[];if(isDomain){domain=stgns.domain;}else if(stgns.nice){domain=generateNiceDomain(range,min,max);}else {domain=[min+(max-min)/2];}if(range.length>domain.length+1){// Generate limits from range
	domain=generateDomain(range,min,max);}else if(range.length<domain.length+1){// Generate additional colors
	range=generateRange(domain,range,min,max);}fn.data=()=>data;fn.range(stgns.invert?range.slice().reverse():range);fn.domain(domain);return fn;}const DEFAULT_SETTINGS$4={domain:[],range:[]};/**
	 * @alias scaleOrdinal
	 * @private
	 * @param { Object } settings
	 * @param { field[] } [fields]
	 * @param { dataset } data
	 * @return { ordinal }
	 */function ordinal(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};/**
	   * An augmented {@link https://github.com/d3/d3-scale#_ordinal|d3 ordinal scale}
	   * @private
	   * @alias ordinal
	   * @param { Object }
	   * @return { number }
	   */const fn=ordinal$1();const ctx={data,resources};const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$4,ctx);const valueFn=typeof settings.value==='function'?settings.value:d=>d.datum.value;const labelFn=typeof settings.label==='function'?settings.label:d=>d.datum.label;const items=data.items||[];const domainToDataMapping={};const values=[];const labels=[];for(let i=0;i<items.length;i++){const arg=extend$1$1({datum:items[i]},ctx);const v=valueFn(arg,i);if(values.indexOf(v)===-1){values.push(v);labels.push(labelFn(arg,i));domainToDataMapping[v]=i;}}fn.data=()=>data;fn.labels=()=>labels;fn.label=domainValue=>labels[values.indexOf(domainValue)];fn.datum=domainValue=>items[domainToDataMapping[domainValue]];fn.range(stgns.range);if(Array.isArray(stgns.domain)&&stgns.domain.length){fn.domain(stgns.domain);}else {fn.domain(values);}return fn;}const DEFAULT_SETTINGS$3={domain:[],range:[],unknown:undefined};const DEFAULT_EXPLICIT_SETTINGS={domain:[],range:[],override:false};/**
	 * @typedef {object} ScaleCategoricalColor
	 * @property {string} [type='categorical-color']
	 * @property {string[]} [range=false] - CSS color values of the output range
	 * @property {string} [unknown] - Value to return when input value is unknown
	 * @property {object} [explicit] - Explicitly bind values to an output
	 * @property {object[]} [explicit.domain[]] - Values to bind
	 * @property {string[]} [explicit.range[]] - Output range
	 *//**
	 * An ordinal scale with the output range set to default colors, as defined by *scaleCategorical.range*
	 * @alias scaleCategorical
	 * @private
	 * @param { Object } settings
	 * @param { field[] } [fields]
	 * @param { dataset } [dataset]
	 * @return { ordinal }
	 */function scaleCategorical(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let data=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let resources=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const s=ordinal(settings,data,resources);const theme=resources.theme;const stgns=resolveSettings$2(settings,DEFAULT_SETTINGS$3,{data,resources});stgns.explicit=resolveSettings$2(settings.explicit,DEFAULT_EXPLICIT_SETTINGS,{data,resources});let range;if(!Array.isArray(stgns.range)||stgns.range.length===0){range=theme?theme.palette('categorical',s.domain().length).slice():[];}else {range=stgns.range.slice();}if(stgns.unknown){s.unknown(stgns.unknown);}else if(theme&&theme.palette('unknown')){let un=theme.palette('unknown');s.unknown(un[0]);}if(Array.isArray(stgns.explicit.domain)&&stgns.explicit.domain.length){const domain=s.domain().slice();const explicitDomain=stgns.explicit.domain;const explicitRange=Array.isArray(stgns.explicit.range)?stgns.explicit.range:[];// duplicate range values to cover entire domain
	const numCopies=Math.floor(domain.length/range.length);for(let i=1;i<numCopies+1;i*=2){range=range.concat(range);}if(stgns.explicit.override){for(let i=0;i<explicitDomain.length;i++){const index=domain.indexOf(explicitDomain[i]);if(index>-1){range[index]=explicitRange[i];}}}else {// inject explicit colors
	const order=explicitDomain.map((d,i)=>[domain.indexOf(d),d,explicitRange[i]]).sort((a,b)=>a[0]-b[0]);order.forEach(v=>{const idx=domain.indexOf(v[1]);if(idx!==-1){range.splice(idx,0,v[2]);}});}// cutoff excess range values
	range.length=domain.length;}s.range(range);return s;}/**
	 * Definition for creating a scale. Additional properties, specific for a type of scale, can be added as key/value pairs
	 * @typedef {object} ScaleDefinition
	 * @property {string} [type] Type of scale
	 * @property {DataExtraction|DataFieldExtraction} [data] Data configuration
	 *//**
	 * Scale instance
	 * @typedef {object} Scale
	 * @interface
	 * @property {string} type Type of scale
	 */const scaleRegistry=registryFactory();scaleRegistry('linear',scaleLinear);scaleRegistry('band',scaleBand);scaleRegistry('h-band',scaleHierarchicalBand);scaleRegistry('sequential-color',scaleSequentialColor);scaleRegistry('threshold-color',scaleThresholdColor);scaleRegistry('categorical-color',scaleCategorical);function getTypeFromMeta(fields){const types=fields.map(field=>field.type()==='dimension'?'band':'linear');return types.indexOf('linear')!==-1?'linear':'band';}function deduceScaleTypeFromData(data){if(data.root){return 'h-band';}if(data.fields&&data.fields[0]){return getTypeFromMeta(data.fields);}return 'linear';}function create$n(options,d,deps){let dataSourceConfig=options.data;if(options.source){// DEPRECATION
	deps.logger.warn('Deprecated: Scale data source configuration');dataSourceConfig={extract:[]};(Array.isArray(options.source)?options.source:[options.source]).forEach(source=>{dataSourceConfig.extract.push({field:source});});}const data=extract$1$1(dataSourceConfig,d,deps);let type=options.type||deduceScaleTypeFromData(data);let s;if(type==='color'){if(data.fields&&data.fields[0]&&data.fields[0].type()==='dimension'){type='categorical-color';}else {type='sequential-color';}}if(deps.scale.has(type)){s=deps.scale.get(type);s=s(options,data,{theme:deps.theme,logger:deps.logger});s.type=type;}return s;}function collection(scalesConfig,data,deps){let fn=arguments.length>3&&arguments[3]!==undefined?arguments[3]:create$n;const scales={};return {get(def){let key;if(typeof def==='string'&&scalesConfig[def]){key=def;}else if(typeof def==='object'&&'scale'in def&&scalesConfig[def.scale]){key=def.scale;}if(key){scales[key]=scales[key]||fn(scalesConfig[key],data,deps);return scales[key];}return fn(def,data,deps);},all(){Object.keys(scalesConfig).forEach(this.get);return scales;}};}/**
	 * Utility functions
	 */var util$1={};util$1.isObject=function isObject(arg){return typeof arg==='object'&&arg!==null;};util$1.isNumber=function isNumber(arg){return typeof arg==='number';};util$1.isUndefined=function isUndefined(arg){return arg===void 0;};util$1.isFunction=function isFunction(arg){return typeof arg==='function';};/**
	 * EventEmitter class
	 */function EventEmitter$1(){EventEmitter$1.init.call(this);}var nodeEventEmitter=EventEmitter$1;// Backwards-compat with node 0.10.x
	EventEmitter$1.EventEmitter=EventEmitter$1;EventEmitter$1.prototype._events=undefined;EventEmitter$1.prototype._maxListeners=undefined;// By default EventEmitters will print a warning if more than 10 listeners are
	// added to it. This is a useful default which helps finding memory leaks.
	EventEmitter$1.defaultMaxListeners=10;EventEmitter$1.init=function(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined;};// Obviously not all Emitters should be limited to 10. This function allows
	// that to be increased. Set to zero for unlimited.
	EventEmitter$1.prototype.setMaxListeners=function(n){if(!util$1.isNumber(n)||n<0||isNaN(n))throw TypeError('n must be a positive number');this._maxListeners=n;return this;};EventEmitter$1.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};// If there is no 'error' event listener then throw.
	if(type==='error'&&!this._events.error){er=arguments[1];if(er instanceof Error){throw er;// Unhandled 'error' event
	}else {throw Error('Uncaught, unspecified "error" event.');}}handler=this._events[type];if(util$1.isUndefined(handler))return false;if(util$1.isFunction(handler)){switch(arguments.length){// fast cases
	case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;// slower
	default:len=arguments.length;args=new Array(len-1);for(i=1;i<len;i++)args[i-1]=arguments[i];handler.apply(this,args);}}else if(util$1.isObject(handler)){len=arguments.length;args=new Array(len-1);for(i=1;i<len;i++)args[i-1]=arguments[i];listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args);}return true;};EventEmitter$1.prototype.addListener=function(type,listener){var m;if(!util$1.isFunction(listener))throw TypeError('listener must be a function');if(!this._events)this._events={};// To avoid recursion in the case that type === "newListener"! Before
	// adding it to the listeners, first emit "newListener".
	if(this._events.newListener)this.emit('newListener',type,util$1.isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])// Optimize the case of one listener. Don't need the extra array object.
	this._events[type]=listener;else if(util$1.isObject(this._events[type]))// If we've already got an array, just append.
	this._events[type].push(listener);else// Adding the second element, need to change to array.
	this._events[type]=[this._events[type],listener];// Check for listener leak
	if(util$1.isObject(this._events[type])&&!this._events[type].warned){var m;if(!util$1.isUndefined(this._maxListeners)){m=this._maxListeners;}else {m=EventEmitter$1.defaultMaxListeners;}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;if(util$1.isFunction(console.error)){console.error('(node) warning: possible EventEmitter memory '+'leak detected. %d listeners added. '+'Use emitter.setMaxListeners() to increase limit.',this._events[type].length);}if(util$1.isFunction(console.trace))console.trace();}}return this;};EventEmitter$1.prototype.on=EventEmitter$1.prototype.addListener;EventEmitter$1.prototype.once=function(type,listener){if(!util$1.isFunction(listener))throw TypeError('listener must be a function');var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments);}}g.listener=listener;this.on(type,g);return this;};// emits a 'removeListener' event iff the listener was removed
	EventEmitter$1.prototype.removeListener=function(type,listener){var list,position,length,i;if(!util$1.isFunction(listener))throw TypeError('listener must be a function');if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||util$1.isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit('removeListener',type,listener);}else if(util$1.isObject(list)){for(i=length;i-->0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break;}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type];}else {list.splice(position,1);}if(this._events.removeListener)this.emit('removeListener',type,listener);}return this;};EventEmitter$1.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;// not listening for removeListener, no need to emit
	if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this;}// emit removeListener for all listeners on all events
	if(arguments.length===0){for(key in this._events){if(key==='removeListener')continue;this.removeAllListeners(key);}this.removeAllListeners('removeListener');this._events={};return this;}listeners=this._events[type];if(util$1.isFunction(listeners)){this.removeListener(type,listeners);}else if(Array.isArray(listeners)){// LIFO order
	while(listeners.length)this.removeListener(type,listeners[listeners.length-1]);}delete this._events[type];return this;};EventEmitter$1.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(util$1.isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret;};EventEmitter$1.listenerCount=function(emitter,type){var ret;if(!emitter._events||!emitter._events[type])ret=0;else if(util$1.isFunction(emitter._events[type]))ret=1;else ret=emitter._events[type].length;return ret;};var EventEmitter={/**
	   * Function used to add event handling to objects passed in.
	   * @private
	   * @param {Object} obj Object instance that will get event handling.
	   */mixin(obj){Object.keys(nodeEventEmitter.prototype).forEach(key=>{obj[key]=nodeEventEmitter.prototype[key];});nodeEventEmitter.init(obj);return obj;}};function scrollApi(){let min=0;let max=0;let start=0;let viewSize=0;start=start||min;/**
	   * The scroll api
	   * @private
	   * @alias scroll
	   */const s={/**
	     * Move the current scroll
	     * @param {number} value
	     * @emits update
	     */move(value){this.moveTo(start+value);},/**
	     * Change the current scroll to a specific value
	     * @param {number} value
	     * @emits update
	     */moveTo(value){const newStart=Math.max(min,Math.min(max-viewSize,value));if(start!==newStart){start=newStart;s.emit('update');}},/**
	     * Update scroll settings
	     * @param {number} [settings.min]
	     * @param {number} [settings.max]
	     * @param {number} [settings.viewSize]
	     * @emits update
	     */update(settings){let triggerUpdate=false;({min=min,max=max}=settings);if(settings.viewSize!==undefined&&settings.viewSize!==viewSize){viewSize=settings.viewSize;triggerUpdate=true;}// update scroll to be within the new bounds
	const newStart=Math.max(min,Math.min(max-viewSize,start));if(start!==newStart){start=newStart;triggerUpdate=true;}if(triggerUpdate){s.emit('update');}},/**
	     * Get the current scroll state
	     * @return {object} with min, max, start & viewSize
	     */getState(){return {min,max,start,viewSize};}};EventEmitter.mixin(s);return s;}function createOrUpdate(options,oldApi){const min=options.min||0;const max=options.max||0;const viewSize=options.viewSize||0;const s=oldApi||scrollApi();s.update({min,max,viewSize});return s;}function builder(obj,oldScrollApis){const scrollApis={};for(const n in obj){if(Object.prototype.hasOwnProperty.call(obj,n)){scrollApis[n]=createOrUpdate(obj[n],oldScrollApis?oldScrollApis[n]:null);}}return scrollApis;}function getOrCreateScrollApi(v,scrollApis){if(!scrollApis[v]){scrollApis[v]=scrollApi();}return scrollApis[v];}function lessThanOrEqual(value,limit){return value<=limit;}function lessThan(value,limit){return value<limit;}function index(boundaries,point,after){let i=0;while(i<boundaries.length&&point>boundaries[i]){++i;}if(boundaries[i]===point&&after){++i;}return i;}function contains(boundaries,point,minCondition,maxCondition){const len=boundaries.length;for(let i=1;i<len;i+=2){if(minCondition(boundaries[i-1],point)&&maxCondition(point,boundaries[i])){return true;}}return false;}function rangeCollection(){let config=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let maxCondition;let minCondition;let boundaries=[];function fn(){}fn.configure=function(){let c=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{includeMax=true,includeMin=true}=c;maxCondition=includeMax?lessThanOrEqual:lessThan;minCondition=includeMin?lessThanOrEqual:lessThan;};fn.add=_ref=>{let{min,max}=_ref;const i0=index(boundaries,min);const i1=index(boundaries,max,true);const args=[i0,i1-i0];if(i0%2===0){args.push(min);}if(i1%2===0){args.push(max);}const before=boundaries.join(',');boundaries.splice(...args);const after=boundaries.join(',');return before!==after;};fn.remove=_ref2=>{let{min,max}=_ref2;const i0=index(boundaries,min);const i1=index(boundaries,max,true);const args=[i0,i1-i0];if(i0%2===1){args.push(min);}if(i1%2===1){args.push(max);}const before=boundaries.join(',');boundaries.splice(...args);const after=boundaries.join(',');return before!==after;};fn.set=range=>{const before=boundaries.join(',');boundaries=[];if(Array.isArray(range)){range.forEach(fn.add);}else {fn.add(range);}const after=boundaries.join(',');return before!==after;};fn.clear=()=>{const before=boundaries.length>0;boundaries=[];return before;};fn.containsValue=value=>contains(boundaries,value,minCondition,maxCondition);fn.containsRange=_ref3=>{let{min,max}=_ref3;const i0=index(boundaries,min,true);const i1=index(boundaries,max);return i0===i1&&i1%2===1;};fn.toggle=range=>{if(fn.containsRange(range)){return fn.remove(range);}return fn.add(range);};fn.ranges=()=>{const collection=[];for(let i=1;i<boundaries.length;i+=2){collection.push({min:boundaries[i-1],max:boundaries[i]});}return collection;};fn.configure(config);return fn;}function valueCollection(){let values=[];function vc(){}vc.add=value=>{if(values.indexOf(value)===-1){values.push(value);return true;}return false;};vc.remove=value=>{const idx=values.indexOf(value);if(idx!==-1){values.splice(idx,1);return true;}return false;};vc.contains=value=>values.indexOf(value)!==-1;vc.values=()=>values.slice();vc.clear=()=>values=[];vc.toString=()=>values.join(';');return vc;}/**
	 * @typedef {object} BrushConfig
	 * @property {Array<BrushConfig~Ranges>} [ranges] - Range configurations
	 *//**
	 * @typedef {object}
	 * @alias BrushConfig~Ranges
	 */const DEFAULT_RANGE_CONFIG={/**
	   * An identifier that represents the data source of the value
	   * @type {string=}
	   */key:undefined,/**
	   * Whether or not the minimum value of a range should be included when determining if a value is brushed.
	   * @type {boolean=} */includeMin:true,/**
	   * Whether or not the maximum value of a range should be included when determining if a value is brushed.
	   * @type {boolean=} */includeMax:true};function add$1(_ref){let{items,collection,vc}=_ref;const changedMap={};const changed=[];let key;let values;for(let i=0,num=items.length;i<num;i++){key=items[i].key;if(!collection[key]){collection[key]=vc();}values=items[i].values||[items[i].value];for(let vi=0;vi<values.length;vi++){if(collection[key].add(values[vi])){changedMap[key]=changedMap[key]||[];changedMap[key].push(values[vi]);}}}const keys=Object.keys(changedMap);for(let i=0,num=keys.length;i<num;i++){key=keys[i];changed.push({id:key,values:changedMap[key]});}return changed;}function remove$1(_ref2){let{items,collection}=_ref2;const changedMap={};const changed=[];let key;let values;for(let i=0,num=items.length;i<num;i++){key=items[i].key;if(!collection[key]){continue;}values=items[i].values||[items[i].value];for(let vi=0;vi<values.length;vi++){if(collection[key].remove(values[vi])){changedMap[key]=changedMap[key]||[];changedMap[key].push(values[vi]);}}}const keys=Object.keys(changedMap);for(let i=0,num=keys.length;i<num;i++){key=keys[i];changed.push({id:key,values:changedMap[key]});}return changed;}function collectUnique(items){const filteredSet={};let key;let values;for(let i=0,num=items.length;i<num;i++){key=items[i].key;values=items[i].values||[items[i].value];if(!filteredSet[key]){filteredSet[key]=[];}for(let vi=0;vi<values.length;vi++){const idx=filteredSet[key].indexOf(values[vi]);if(idx===-1){filteredSet[key].push(values[vi]);}}}return filteredSet;}function createValueCollection(_ref3){let{key,collection,obj,fn,value}=_ref3;if(!collection[key]){collection[key]=fn();}obj[key]=obj[key]||[];obj[key].push(value);collection[key].add(value);}function toggle(_ref4){let{items,values,vc}=_ref4;const addedMap={};const removedMap={};const added=[];const removed=[];const filteredSet=collectUnique(items);let key;let value;let fs;const setKeys=Object.keys(filteredSet);for(let i=0,num=setKeys.length;i<num;i++){key=setKeys[i];fs=filteredSet[key];for(let k=0,len=fs.length;k<len;k++){value=fs[k];if(!values[key]||!values[key].contains(value)){createValueCollection({key,value,collection:values,obj:addedMap,fn:vc});}else if(values[key]&&values[key].contains(value)){removedMap[key]=removedMap[key]||[];removedMap[key].push(value);values[key].remove(value);}}}const addedKeys=Object.keys(addedMap);for(let i=0,num=addedKeys.length;i<num;i++){key=addedKeys[i];added.push({id:key,values:addedMap[key]});}const removedKeys=Object.keys(removedMap);for(let i=0,num=removedKeys.length;i<num;i++){key=removedKeys[i];removed.push({id:key,values:removedMap[key]});}return [added,removed];}function diff$1(old,current){const changed=[];const keys=Object.keys(old);let key;let changedValues;const filterFn=v=>current[key].indexOf(v)===-1;for(let i=0,num=keys.length;i<num;i++){key=keys[i];if(!current[key]){changed.push({id:key,values:old[key]});}else {changedValues=old[key].filter(filterFn);if(changedValues.length){changed.push({id:key,values:changedValues});}}}return changed;}function set(_ref5){let{items,vCollection,vc}=_ref5;const addedMap={};const filteredSet=collectUnique(items);let added=[];let removed=[];let key;const oldMap={};const vcKeys=Object.keys(vCollection);for(let i=0,num=vcKeys.length;i<num;i++){key=vcKeys[i];oldMap[key]=vCollection[key].values().slice();delete vCollection[key];}const createValueCollectionFn=value=>{if(!vCollection[key]||!vCollection[key].contains(value)){createValueCollection({key,value,collection:vCollection,obj:addedMap,fn:vc});}};const fsKeys=Object.keys(filteredSet);for(let i=0,num=fsKeys.length;i<num;i++){key=fsKeys[i];filteredSet[key].forEach(createValueCollectionFn);}removed=diff$1(oldMap,addedMap);added=diff$1(addedMap,oldMap);return [added,removed];}function applyAliases(items,aliases){if(!Object.keys(aliases).length){return items;}const len=items.length;const its=Array(len);for(let i=0;i<len;i++){its[i]=items[i].key in aliases?extend$1$1({},items[i],{key:aliases[items[i].key]}):items[i];}return its;}function intercept(handlers,items,aliases){const its=applyAliases(items,aliases);return handlers&&handlers.length?handlers.reduce((value,interceptor)=>interceptor(value),its):its;}function toCamelCase(s){return s.replace(/(-[a-z])/g,$1=>$1.toUpperCase().replace('-',''));}function toSnakeCase(s){return s.replace(/([A-Z])/g,$1=>"-".concat($1.toLowerCase()));}function updateRange(items,action,_ref6){let{ranges,interceptors,rc,aliases,rangeConfig}=_ref6;const inter="".concat(action,"Ranges");const its=intercept(interceptors[inter],items,aliases);let changed=false;its.forEach(item=>{const key=item.key;if(!ranges[key]){ranges[key]=rc(rangeConfig.sources[key]||rangeConfig.default);}if(action==='set'){changed=ranges[key][action](item.ranges||item.range)||changed;}else {const rangeValues=item.ranges||[item.range];for(let i=0;i<rangeValues.length;i++){changed=ranges[key][action](rangeValues[i])||changed;}}});return changed;}function brush(){let{vc=valueCollection,rc=rangeCollection}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let activated=false;let ranges={};let values={};let aliases={};let rangeConfig={sources:{},default:extend$1$1({},DEFAULT_RANGE_CONFIG)};const interceptors={addValues:[],removeValues:[],toggleValues:[],setValues:[],addRanges:[],setRanges:[],removeRanges:[],toggleRanges:[]};const getState=()=>{const state={values:{},ranges:{}};Object.keys(values).forEach(key=>{state.values[key]=values[key].values();});Object.keys(ranges).forEach(key=>{state.ranges[key]=ranges[key].ranges();});return state;};const links={ls:[],clear(){this.ls.forEach(b=>b.clear());},start(){this.ls.forEach(b=>b.start());},end(){this.ls.forEach(b=>b.end());},update(){const s=getState();this.ls.forEach(b=>b._state(s));},updateValues(){const s=getState();this.ls.forEach(b=>b._state({values:s.values}));},updateRanges(){const s=getState();this.ls.forEach(b=>b._state({ranges:s.ranges}));}};/**
	   * A brush context
	   * @alias Brush
	   * @interface
	   */const fn={};/**
	   * Triggered when this brush is activated
	   * @event Brush#start
	   * @type {string}
	   *//**
	   * Triggered when this brush is updated
	   * @event Brush#update
	   * @type {string}
	   * @param {Array<object>} added - The added items
	   * @param {Array<object>} removed - The removed items
	   *//**
	   * Triggered when this brush is deactivated
	   * @event Brush#end
	   * @type {string}
	   *//**
	   * Configure the brush instance.
	   *
	   * @param {BrushConfig} config
	   * @example
	   * brushInstance.configure({
	   *   ranges: [
	   *     { key: 'some key', includeMax: false },
	   *     { includeMax: true, includeMin: true },
	   *   ]
	   * })
	   */fn.configure=function(){let config=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};if(Array.isArray(config.ranges)&&config.ranges.length){rangeConfig={sources:{},default:extend$1$1({},DEFAULT_RANGE_CONFIG)};config.ranges.forEach(cfg=>{const c={};Object.keys(DEFAULT_RANGE_CONFIG).filter(attr=>attr!=='key').forEach(attr=>{c[attr]=typeof cfg[attr]!=='undefined'?cfg[attr]:DEFAULT_RANGE_CONFIG[attr];});if(typeof cfg.key!=='undefined'){rangeConfig.sources[cfg.key]=c;}else {rangeConfig.default=c;}});Object.keys(ranges).forEach(key=>ranges[key].configure(rangeConfig.sources[key]||rangeConfig.default));// TODO only emit update if config has changed
	fn.emit('update',[],[]);}};/**
	   * Link this brush to another brush instance.
	   *
	   * When linked, the `target` will receive updates whenever this brush changes.
	   * @param {Brush} target - The brush instance to link to
	   */fn.link=target=>{if(fn===target){throw new Error("Can't link to self");}links.ls.push(target);target._state(getState());};fn._state=s=>{if(!s){return getState();}if(s.values){const arr=[];Object.keys(s.values).forEach(key=>{if(!values[key]||s.values[key].join(';')!==values[key].toString()){arr.push({key,values:s.values[key]});}});Object.keys(values).forEach(key=>{if(!s.values[key]){arr.push({key,values:[]});}});if(arr.length){fn.setValues(arr);}}if(s.ranges){const arr=[];Object.keys(s.ranges).forEach(key=>{if(!ranges[key]||s.ranges[key].join(';')!==ranges[key].toString()){arr.push({key,ranges:s.ranges[key]});}});Object.keys(ranges).forEach(key=>{if(!s.ranges[key]){arr.push({key,ranges:[]});}});if(arr.length){fn.setRanges(arr);}}return undefined;};/**
	   * Starts this brush context
	   *
	   * Starts this brush context and emits a 'start' event if it is not already started.
	   * @param {...any} args - arguments to be passed to 'start' listeners
	   * @emits Brush#start
	   */fn.start=function(){if(!activated){activated=true;for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}fn.emit('start',...args);links.start();}};/**
	   * Ends this brush context
	   *
	   * Ends this brush context and emits an 'end' event if it is not already ended.
	   * @param {...any} args - arguments to be passed to 'end' listeners
	   * @emits Brush#end
	   */fn.end=function(){if(!activated){return;}activated=false;ranges={};values={};for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++){args[_key2]=arguments[_key2];}fn.emit('end',...args);links.end();};/**
	   * Checks if this brush is activated
	   *
	   * Returns true if started, false otherwise
	   * @return {boolean}
	   */fn.isActive=()=>activated;/**
	   * Clears this brush context
	   */fn.clear=()=>{const removed=fn.brushes().filter(b=>b.type==='value'&&b.brush.values().length).map(b=>({id:b.id,values:b.brush.values()}));const hasChanged=Object.keys(ranges).length>0||removed.length;ranges={};values={};if(hasChanged){fn.emit('update',[],removed);// TODO - do not emit update if state hasn't changed
	links.clear();}};/**
	   * Returns all brushes within this context
	   * @return {object}
	   */fn.brushes=()=>{let result=[];result=result.concat(Object.keys(ranges).map(key=>({type:'range',id:key,brush:ranges[key]})));result=result.concat(Object.keys(values).map(key=>({type:'value',id:key,brush:values[key]})));return result;};/**
	   * Adds a primitive value to this brush context
	   *
	   * If this brush context is not started, a 'start' event is emitted.
	   * If the state of the brush changes, ie. if the added value does not already exist, an 'update' event is emitted.
	   *
	   * @param {string} key  An identifier that represents the data source of the value
	   * @param {string|number} value The value to add
	   * @emits Brush#start
	   * @emits Brush#update
	   * @example
	   * brush.addValue('countries', 'Sweden');
	   * brush.addValue('/qHyperCube/qDimensionInfo/0', 3);
	   */fn.addValue=(key,value)=>{fn.addValues([{key,value}]);};/**
	   * @param {object[]} items Items to add
	   */fn.addValues=items=>{const its=intercept(interceptors.addValues,items,aliases);const added=add$1({vc,collection:values,items:its});fn.emit('add-values',its);if(added.length){if(!activated){activated=true;fn.emit('start');}fn.emit('update',added,[]);links.updateValues();}};/**
	   * @param {object[]} items Items to set
	   */fn.setValues=items=>{const its=intercept(interceptors.setValues,items,aliases);const changed=set({items:its,vCollection:values,vc});fn.emit('set-values',its);if(changed[0].length>0||changed[1].length>0){if(!activated){activated=true;fn.emit('start');}fn.emit('update',changed[0],changed[1]);links.updateValues();}};/**
	   * Removes a primitive values from this brush context
	   *
	   * If the state of the brush changes, ie. if the removed value does exist, an 'update' event is emitted.
	   *
	   * @param  {string} key  An identifier that represents the data source of the value
	   * @param  {string|number} value The value to remove
	   * @example
	   * brush.removeValue('countries', 'Sweden');
	   */fn.removeValue=(key,value)=>{fn.removeValues([{key,value}]);};/**
	   * @param {object[]} items Items to remove
	   */fn.removeValues=items=>{const its=intercept(interceptors.removeValues,items,aliases);const removed=remove$1({collection:values,items:its});fn.emit('remove-values',its);if(removed.length){fn.emit('update',[],removed);links.updateValues();// TODO - emit 'end' event if there are no remaining active brushes
	}};/**
	   * Add and remove values in a single operation
	   * almost the same as calling addValues and removeValues but only triggers one 'update' event
	   *
	   * If the state of the brush changes, an 'update' event is emitted.
	   *
	   * @param {object[]} addItems Items to add
	   * @param {object[]} removeItems Items to remove
	   */fn.addAndRemoveValues=(addItems,removeItems)=>{const addIts=intercept(interceptors.addValues,addItems,aliases);const removeIts=intercept(interceptors.removeValues,removeItems,aliases);const added=add$1({vc,collection:values,items:addIts});const removed=remove$1({collection:values,items:removeIts});fn.emit('add-values',addIts);fn.emit('remove-values',removeIts);if(added.length||removed.length){if(!activated){activated=true;fn.emit('start');}fn.emit('update',added,removed);links.updateValues();}};/**
	   * Toggles a primitive value in this brush context
	   *
	   * If the given value exists in this brush context, it will be removed. If it does not exist it will be added.
	   *
	   * @param  {string} key  An identifier that represents the data source of the value
	   * @param  {string|number} value The value to toggle
	   * @example
	   * brush.toggleValue('countries', 'Sweden');
	   */fn.toggleValue=(key,value)=>{fn.toggleValues([{key,value}]);};/**
	   * @param {object[]} items Items to toggle
	   */fn.toggleValues=items=>{const its=intercept(interceptors.toggleValues,items,aliases);const toggled=toggle({items:its,values,vc});fn.emit('toggle-values',its);if(toggled[0].length>0||toggled[1].length>0){if(!activated){activated=true;fn.emit('start');}fn.emit('update',toggled[0],toggled[1]);links.updateValues();}};/**
	   * Checks if a certain value exists in this brush context
	   *
	   * Returns true if the values exists for the provided key, returns false otherwise.
	   *
	   * @param  {string} key  An identifier that represents the data source of the value
	   * @param  {string|number} value The value to check for
	   * @return {boolean}
	   * @example
	   * brush.addValue('countries', 'Sweden');
	   * brush.containsValue('countries', 'Sweden'); // true
	   * brush.toggleValue('countries', 'Sweden'); // remove 'Sweden'
	   * brush.containsValue('countries', 'Sweden'); // false
	   */fn.containsValue=(key,value)=>{let k=aliases[key]||key;if(!values[k]){return false;}return values[k].contains(value);};/**
	   * Adds a numeric range to this brush context
	   *
	   * @param {string} key - An identifier that represents the data source of the range
	   * @param {object} range - The range to add to this brush
	   * @param {number} range.min - Min value of the range
	   * @param {number} range.max - Max value of the range
	   * @example
	   * brush.addRange('Sales', { min: 20, max: 50 });
	   */fn.addRange=(key,range)=>{fn.addRanges([{key,range}]);};/**
	   * @see {brush.addRange}
	   * @param {object[]} items - Items containing the ranges to remove
	   * @param {string} items[].key
	   * @param {object} items[].range
	   */fn.addRanges=items=>{const changed=updateRange(items,'add',{ranges,rc,interceptors,aliases,rangeConfig});if(!changed){return;}if(!activated){activated=true;fn.emit('start');}fn.emit('update',[],[]);links.updateRanges();};/**
	   * Removes a numeric range from this brush context
	   *
	   * @param {string} key - An identifier that represents the data source of the range
	   * @param {object} range - The range to remove from this brush
	   * @param {number} range.min - Min value of the range
	   * @param {number} range.max - Max value of the range
	   */fn.removeRange=(key,range)=>{fn.removeRanges([{key,range}]);};/**
	   * @see {brush.removeRange}
	   * @param {object[]} items - Items containing the ranges to remove
	   */fn.removeRanges=items=>{const changed=updateRange(items,'remove',{ranges,rc,interceptors,aliases,rangeConfig});if(!changed){return;}if(!activated){activated=true;fn.emit('start');}fn.emit('update',[],[]);links.updateRanges();};/**
	   * Sets a numeric range to this brush context
	   *
	   * Overwrites any active ranges identified by `key`
	   *
	   * @param {string} key - An identifier that represents the data source of the range
	   * @param {object} range - The range to set on this brush
	   * @param {number} range.min - Min value of the range
	   * @param {number} range.max - Max value of the range
	   */fn.setRange=(key,range)=>{fn.setRanges([{key,range}]);};/**
	   * @see {brush.setRange}
	   * @param {object[]} items - Items containing the ranges to set
	   */fn.setRanges=items=>{const changed=updateRange(items,'set',{ranges,rc,interceptors,aliases,rangeConfig});if(!changed){return;}if(!activated){activated=true;fn.emit('start');}fn.emit('update',[],[]);links.updateRanges();};/**
	   * Toggles a numeric range in this brush context
	   *
	   * Removes the range if it's already contained within the given identifier,
	   * otherwise the given range is added to the brush.
	   *
	   * @param {string} key - An identifier that represents the data source of the range
	   * @param {object} range - The range to toggle in this brush
	   * @param {number} range.min - Min value of the range
	   * @param {number} range.max - Max value of the range
	   */fn.toggleRange=(key,range)=>{fn.toggleRanges([{key,range}]);};/**
	   * @see {brush.toggleRange}
	   * @param {object[]} items - Items containing the ranges to toggle
	   */fn.toggleRanges=items=>{const changed=updateRange(items,'toggle',{ranges,rc,interceptors,aliases,rangeConfig});if(!changed){return;}if(!activated){activated=true;fn.emit('start');}fn.emit('update',[],[]);links.updateRanges();};/**
	   * Checks if a value is contained within a range in this brush context
	   *
	   * Returns true if the values exists for the provided key, returns false otherwise.
	   *
	   * @param  {string} key - An identifier that represents the data source of the value
	   * @param  {number} value - The value to check for
	   * @return {boolean}
	   * @example
	   * brush.addRange('Sales', { min: 10, max: 50 });
	   * brush.containsRangeValue('Sales', 30); // true
	   * brush.containsRangeValue('Sales', 5); // false
	   */fn.containsRangeValue=(key,value)=>{let k=aliases[key]||key;if(!ranges[k]){return false;}return ranges[k].containsValue(value);};/**
	   * Checks if a range segment is contained within this brush context
	   *
	   * Returns true if the range segment exists for the provided key, returns false otherwise.
	   *
	   * @param {string} key - An identifier that represents the data source of the value
	   * @param {object} range - The range to check for
	   * @param {number} range.min - Min value of the range
	   * @param {number} range.max - Max value of the range
	   * @return {boolean}
	   * @example
	   * brush.addRange('Sales', { min: 10, max: 50 });
	   * brush.containsRange('Sales', { min: 15, max: 20 }); // true - the range segment is fully contained within [10, 50]
	   * brush.containsRange('Sales', { min: 5, max: 20 }); // false - part of the range segment is outside [10, 50]
	   * brush.containsRange('Sales', { min: 30, max: 80 }); // false - part of the range segment is outside [10, 50]
	   */fn.containsRange=(key,range)=>{let k=aliases[key]||key;if(!ranges[k]){return false;}return ranges[k].containsRange(range);};fn.containsMappedData=(d,props,mode)=>{let status=[];const keys=Object.keys(d);let key;let item;let source;let value;for(let i=0,num=keys.length;i<num;i++){key=keys[i];if(key==='value'){item=d;status[i]={key:'',i,bool:false};}else if(key==='source'){continue;}else {item=d[key];status[i]={key,i,bool:false};}source=item.source&&item.source.field;if(typeof source==='undefined'){continue;}if(typeof item.source.key!=='undefined'){source="".concat(item.source.key,"/").concat(source);}if(source in aliases){source=aliases[source];}value=item.value;if(ranges[source]){status[i].bool=Array.isArray(value)?ranges[source].containsRange({min:value[0],max:value[1]}):ranges[source].containsValue(value);}else if(values[source]&&values[source].contains(value)){status[i].bool=true;}}if(props){status=status.filter(b=>props.indexOf(b.key)!==-1);if(mode==='and'){return !!status.length&&!status.some(s=>s.bool===false);}if(mode==='xor'){return !!status.length&&status.some(s=>s.bool)&&status.some(s=>s.bool===false);}// !mode || mode === 'or'
	return status.some(s=>s.bool);}return status.some(s=>s.bool);};/**
	   * Adds an event interceptor
	   *
	   * @param {string} name Name of the event to intercept
	   * @param {function} ic Handler to call before event is triggered
	   * @example
	   * brush.intercept('add-values', items => {
	   *  console.log('about to add the following items', items);
	   *  return items;
	   * });
	   */fn.intercept=(name,ic)=>{const s=toCamelCase(name);if(!interceptors[s]){return;}interceptors[s].push(ic);};/**
	   * Removes an interceptor
	   *
	   * @param {string} name Name of the event to intercept
	   * @param {function} ic Handler to remove
	   */fn.removeInterceptor=(name,ic)=>{const s=toCamelCase(name);if(!interceptors[s]){return;}const idx=interceptors[s].indexOf(ic);if(idx!==-1){interceptors[s].splice(idx,1);}};/**
	   * Removes all interceptors
	   *
	   * @param {string} [name] Name of the event to remove interceptors for. If not provided, removes all interceptors.
	   */fn.removeAllInterceptors=name=>{const toRemove=[];if(name){const s=toCamelCase(name);if(interceptors[s]&&interceptors[s].length){toRemove.push({name,handlers:interceptors[s]});}}else {Object.keys(interceptors).forEach(n=>{if(interceptors[n].length){toRemove.push({name:toSnakeCase(n),handlers:interceptors[n]});}});}toRemove.forEach(ic=>{const interceptorHandlers=ic.handlers.slice();interceptorHandlers.forEach(handler=>fn.removeInterceptor(ic.name,handler));});};/**
	   * Adds an alias to the given key
	   *
	   * @param {string} key - Value to be replaced
	   * @param {string} alias - Value to replace key with
	   * @example
	   * brush.addKeyAlias('BadFieldName', 'Region');
	   * brush.addValue('BadFieldName', 'Sweden'); // 'BadFieldName' will be stored as 'Region'
	   * brush.containsValue('Region', 'Sweden'); // true
	   * brush.containsValue('BadFieldName', 'Sweden'); // true
	   */fn.addKeyAlias=(key,alias)=>{aliases[key]=alias;};/**
	   * Removes an alias
	   *
	   * This will only remove the key to alias mapping for new manipulations of the brush,
	   * no changes will be made to the current state of this brush.
	   *
	   * @param {string} key - Value to remove as alias
	   * @example
	   * brush.removeKeyAlias('BadFieldName');
	   */fn.removeKeyAlias=key=>{delete aliases[key];};EventEmitter.mixin(fn);return fn;}registryFactory();function cubicIn(t){return t*t*t;}function cubicOut(t){return --t*t*t+1;}function cubicInOut(t){return ((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2;}/* eslint-disable no-cond-assign */const colorKeys=['stroke','fill','color','backgroundColor','thumbColor'];function constant(x){return ()=>x;}function isNumberArray(x){return ArrayBuffer.isView(x)&&!(x instanceof DataView);}function genericArray(a,b){const nb=b?b.length:0;const na=a?Math.min(nb,a.length):0;const x=new Array(na);const c=new Array(nb);let i;for(i=0;i<na;++i){x[i]=value(a[i],b[i]);}for(;i<nb;++i){c[i]=b[i];}return function interplolate(t){for(i=0;i<na;++i){c[i]=x[i](t);}return c;};}function value(a,b,k){const t=typeof b;let c;return b==null||t==='boolean'?constant(b):(t==='number'?number$1:t==='string'?(c=color(b))&&colorKeys.includes(k)?(b=c,rgb$2):string:b instanceof color?rgb$2:b instanceof Date?date:isNumberArray(b)?numberArray:Array.isArray(b)?genericArray:typeof b.valueOf!=='function'&&typeof b.toString!=='function'||isNaN(b)?object:number$1)(a,b);}function object(a,b){const i={};const c={};let k;if(a===null||typeof a!=='object'){a={};}if(b===null||typeof b!=='object'){b={};}for(k in b){if(k in a){i[k]=value(a[k],b[k],k);}else {c[k]=b[k];}}return function interplolate(t){// eslint-disable-next-line guard-for-in
	for(k in i){c[k]=i[k](t);}return c;};}/* globals window */function nodeId(node,i){if(node.data){return node.data.value;}if(node.type==='text'){return node.text;}return i;}function findCommonPointsFromTwoLines(oldLine,currentLine){const oldPoints=oldLine.points.filter(point=>!point.dummy);const currentPoints=currentLine.points.filter(point=>!point.dummy);const currentPointsValues=currentPoints.map(point=>point.data.major.value);const commonPointsValues=oldPoints.filter(point=>currentPointsValues.includes(point.data.major.value)).map(point=>point.data.major.value);const oldCommonPoints=oldPoints.filter(point=>commonPointsValues.includes(point.data.major.value));const currentCommonPoints=currentPoints.filter(point=>commonPointsValues.includes(point.data.major.value));return {old:oldCommonPoints,current:currentCommonPoints};}function tween(_ref,_ref2,config,chartStorage){let{old,current}=_ref;let{renderer}=_ref2;let ticker;let toBeUpdated=[];let entered={nodes:[],ips:[]};let exited={nodes:[],ips:[]};let updated={nodes:[],ips:[]};let stages=[];let targetScene=null;const trackBy=config.trackBy||nodeId;const tweener={start(){let ids={};old.forEach((node,i)=>{let id=trackBy(node,i);ids[id]=node;});current.forEach((node,i)=>{let id=trackBy(node,i);if(ids[id]){if(node.type==='path'&&node.points&&node.points.length>0&&node.data.source.key!=='trend'){const common=findCommonPointsFromTwoLines(ids[id],node);updated.ips.push(object(extend$1$1({},ids[id],{points:common.old}),extend$1$1({},node,{points:common.current})));toBeUpdated.push(extend$1$1({},ids[id],{commonPoints:common.old}));}else {updated.ips.push(object(ids[id],node));toBeUpdated.push(ids[id]);}updated.nodes.push(node);ids[id]=false;}else {entered.nodes.push(node);entered.ips.push(object(extend$1$1({},node,{r:0.001,opacity:0}),node));}});Object.keys(ids).forEach(key=>{if(ids[key]){exited.nodes.push(ids[key]);exited.ips.push(object(ids[key],extend$1$1({},ids[key],{r:0.0001,opacity:0})));}});// Obsolete nodes exiting
	stages.push({name:'exiting',easing:cubicIn,duration:200,tweens:exited.ips,nodes:[...toBeUpdated]});// Existing nodes updating
	stages.push({name:'updating',easing:cubicInOut,duration:400,tweens:updated.ips,nodes:[]});// New nodes entering
	stages.push({name:'entering',easing:cubicOut,duration:200,tweens:entered.ips,nodes:[...updated.nodes]});if(config.isMainComponent){var _config$isMainCompone;const filterFn=(_config$isMainCompone=config.isMainComponent)===null||_config$isMainCompone===void 0?void 0:_config$isMainCompone.filterFn;const nUpdatingNodes=filterFn?toBeUpdated.filter(filterFn).length:toBeUpdated.length;const{isInit,shouldBeRemoved}=chartStorage.getValue('animations.updatingStageMeta');if(isInit===false){chartStorage.setValue('animations.updatingStageMeta.shouldBeRemoved',nUpdatingNodes===0);chartStorage.setValue('animations.updatingStageMeta.isInit',true);}else {chartStorage.setValue('animations.updatingStageMeta.shouldBeRemoved',shouldBeRemoved&&nUpdatingNodes===0);}}// console.log(stages);
	if(stages.length){targetScene=renderer.getScene(current);stages[0].started=Date.now();if(typeof window!=='undefined'){ticker=window.requestAnimationFrame(tweener.tick);}}},tick(){let currentStage=stages[0];if(!currentStage){tweener.stop();}if(!currentStage.started){currentStage.started=Date.now();}let t=(Date.now()-currentStage.started)/currentStage.duration;let currentNodes=[];let tweenedNodes=currentStage.tweens.map(ip=>ip(currentStage.easing(Math.min(1,t))));const{adjustTweenedNodes}=config;if(adjustTweenedNodes){adjustTweenedNodes(tweenedNodes);}currentNodes.push(...tweenedNodes);currentNodes.push(...currentStage.nodes);renderer.render(currentNodes);if(t>=1){stages.shift();const{isInit,shouldBeRemoved}=chartStorage.getValue('animations.updatingStageMeta');if(!stages.length){if(isInit===true){chartStorage.setValue('animations.updatingStageMeta.isInit',false);}tweener.stop();}else if(stages[0].name==='updating'&&shouldBeRemoved){stages.shift();}}if(ticker){ticker=window.requestAnimationFrame(tweener.tick);}},stop(){if(ticker){window.cancelAnimationFrame(ticker);ticker=false;}},inProgress(){return !!ticker;},get targetScene(){return targetScene;}};return tweener;}const GLOBAL_DEFAULTS={fontFamily:'Arial',fontSize:'13px',color:'#595959',backgroundColor:'#ffffff',stroke:'#000000',strokeWidth:0,$fill:'#333333'};const REF_RX=/^\$/;function isPrimitive(x){const type=typeof x;return type!=='object'&&type!=='function'&&type!=='undefined';}/**
	 * Callback function
	 * @callback datumAccessor
	 * @param {DatumExtract} d datum
	 * @example
	 * (d) => Math.min(0, d.value);
	 *//**
	 * @typedef {object} DatumConfig
	 * @property {string} [scale] - Name of a scale
	 * @property {datumAccessor} [fn]
	 * @property {string} [ref] - A reference to a DatumExtract property
	 * @example
	 * // Implicitly resolve the datum by passing a referenced data through the scale
	 * {
	 *  scale: '<name-of-scale>',
	 *  ref: '<data-property>'
	 * }
	 *
	 * // or explicitly resolve the datum using callback function
	 * {
	 *  fn: (d) => Math.min(0, d.datum.x.value);
	 * }
	 *//**
	 * Custom type that is either a string, DatumConfig or a datumAccessor
	 * @typedef {string|DatumConfig|datumAccessor} DatumString
	 *//**
	 * Custom type that is either a number, DatumConfig or a datumAccessor
	 * @typedef {number|DatumConfig|datumAccessor} DatumNumber
	 *//**
	 * Custom type that is either a boolean, DatumConfig or a datumAccessor
	 * @typedef {boolean|DatumConfig|datumAccessor} DatumBoolean
	 *//**
	 * Normalizes property settings
	 *
	 * @ignore
	 * @export
	 * @param {any} settings
	 * @param {any} defaults
	 * @param {any} chart
	 * @returns {any}
	 */function normalizeSettings(settings,defaults,chart){const composition=extend$1$1({},settings);const defs=extend$1$1({},defaults);Object.keys(composition).forEach(key=>{defs[key]={};const v=composition[key];const vType=typeof v;if(typeof v==='function'){defs[key].fn=v;}else if(isPrimitive(v)){let defaultValue=defaults[key];if(typeof defaultValue==='string'&&REF_RX.test(defaultValue)){defaultValue=GLOBAL_DEFAULTS[defaultValue];}const defaultType=typeof defaultValue;if(defaultType==='undefined'){// if property has no default, assign provided value
	defs[key]=v;}else {// assign provided value if it's of same type as default, otherwise use default
	defs[key]=defaultType===vType?v:defaultValue;}}else if(v&&typeof v==='object'){if(typeof v.fn==='function'){defs[key].fn=v.fn;}if(typeof v.scale!=='undefined'){defs[key].scale=chart.scale(v.scale);}if(typeof v.ref==='string'){defs[key].ref=v.ref;}}});Object.keys(defaults).forEach(key=>{if(key in composition){// don't process same props again
	return;}const v=defaults[key];const defaultType=typeof v;if(defaultType==='string'&&REF_RX.test(v)){defs[key]=GLOBAL_DEFAULTS[v];}else {defs[key]=v;}});return defs;}function resolveForItem(context,normalized,idx){const ret={};const keys=Object.keys(normalized);const len=keys.length;const fallbackData=context.datum;const datum=context.datum;for(let i=0;i<len;i++){const key=keys[i];const normalizedProp=normalized[key];const exists=typeof datum==='object'&&typeof normalizedProp!=='undefined';const hasExplicitDataProp=exists&&typeof normalizedProp.ref==='string';const hasImplicitDataProp=exists&&key in datum;const propData=hasExplicitDataProp?datum[normalizedProp.ref]:hasImplicitDataProp?datum[key]:fallbackData;// eslint-disable-line
	if(isPrimitive(normalizedProp)){ret[key]=normalizedProp;}else if(exists&&normalizedProp.fn){// callback function
	if(normalizedProp.scale){context.scale=normalizedProp.scale;}ret[key]=normalizedProp.fn.call(null,context,idx);}else if(exists&&normalizedProp.scale&&propData){ret[key]=normalizedProp.scale(propData.value);if(normalizedProp.scale.bandwidth){ret[key]+=normalizedProp.scale.bandwidth()/2;}}else if(hasExplicitDataProp&&propData){ret[key]=propData.value;}else if(normalizedProp.fn){ret[key]=normalizedProp.fn.call(null,context,idx);}else {ret[key]=normalizedProp;}}return ret;}function updateScaleSize(object,path,size){const o=object[path];if(o&&o.scale&&o.scale.pxScale){o.scale=o.scale.pxScale(size);}else if(o&&o.pxScale){object[path]=o.pxScale(size);}}function scaleWithSize(scale,size){return scale.pxScale?scale.pxScale(size):scale;}const externals={normalizeSettings,resolveForItem,updateScaleSize};function settingsResolver(resources){let deps=arguments.length>1&&arguments[1]!==undefined?arguments[1]:externals;let cache={};function resolve(_ref){let{data,settings,defaults={},scaled}=_ref;const norm=cache.norm=deps.normalizeSettings(settings,defaults,resources.chart);const res={scale:resources.chart.scale,formatter:resources.chart.formatter};if(scaled){Object.keys(scaled).forEach(key=>{if(norm[key]){deps.updateScaleSize(norm,key,scaled[key]);}});}const resolved=[];if(data&&Array.isArray(data.items)){let context;for(let i=0,len=data.items.length;i<len;i++){context={datum:data.items[i],data,resources:res};let obj=deps.resolveForItem(context,cache.norm,i);obj.data=data.items[i];resolved.push(obj);}}else {const context={data,resources:res};let obj=deps.resolveForItem(context,cache.norm,-1);return {settings:cache.norm,item:obj};}return {settings:cache.norm,items:resolved};}return {resolve};}/**
	 * Flatten the array of nodes by removing any containers as they do not support styling, thus unable to brush them.
	 * @param {array} nodes
	 * @ignore
	 */function reduceToLeafNodes(){let nodes=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];return nodes.reduce((ary,node)=>{if(Array.isArray(node.children)){ary.push(...reduceToLeafNodes(node.children));return ary;}ary.push(node);return ary;},[]);}function styler(obj,_ref){let{context,data,style,filter,mode}=_ref;const brusher=obj.chart.brush(context);const dataProps=data;const active=style.active||{};const inactive=style.inactive||{};const styleProps=[];Object.keys(active).forEach(key=>{styleProps.push(key);});Object.keys(inactive).forEach(key=>{if(styleProps.indexOf(key)===-1){styleProps.push(key);}});const activeNodes=[];let globalActivation=false;// track when we need to loop through all nodes, not just the active ones
	const getNodes=()=>{let nodes=reduceToLeafNodes(obj.nodes);if(typeof filter==='function'){nodes=nodes.filter(filter);}return nodes;};const update=()=>{// TODO - render nodes only once, i.e. don't render for each brush, update nodes for all brushes and then render
	const nodes=getNodes();const len=nodes.length;let nodeData;let globalChanged=false;const evaluatedDataProps=typeof dataProps==='function'?dataProps({brush:brusher}):dataProps;// To calculate active nodes
	for(let i=0;i<len;i++){// TODO - update only added and removed nodes
	nodeData=nodes[i].data;if(!nodeData){continue;}if(!nodes[i].__style){nodes[i].__style={};styleProps.forEach(s=>{nodes[i].__style[s]=nodes[i][s];// store original value
	});}const isActive=brusher.containsMappedData(nodeData,evaluatedDataProps,mode);const activeIdx=activeNodes.indexOf(nodes[i]);let changed=false;if(isActive&&activeIdx===-1){// activated
	activeNodes.push(nodes[i]);changed=true;}else if(!isActive&&activeIdx!==-1){// was active
	activeNodes.splice(activeIdx,1);changed=true;}nodes[i].needToUpdate=changed||globalActivation;nodes[i].isActive=isActive;}// To calculate style
	for(let i=0;i<len;i++){// TODO - update only added and removed nodes
	nodeData=nodes[i].data;if(!nodeData){continue;}if(nodes[i].needToUpdate){const original=extend$1$1({},nodes[i],nodes[i].__style);const isActive=nodes[i].isActive;styleProps.forEach(s=>{if(isActive&&s in active){nodes[i][s]=typeof active[s]==='function'?active[s].call(null,original,activeNodes):active[s];}else if(!isActive&&s in inactive){nodes[i][s]=typeof inactive[s]==='function'?inactive[s].call(null,original,activeNodes):inactive[s];}else {nodes[i][s]=nodes[i].__style[s];}});globalChanged=true;}delete nodes[i].needToUpdate;}globalActivation=false;return globalChanged;};const onStart=function(){let opts=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{suppressRender:false};const{suppressRender}=opts;const nodes=getNodes();const len=nodes.length;for(let i=0;i<len;i++){if(!nodes[i].data){continue;}nodes[i].__style=nodes[i].__style||{};styleProps.forEach(s=>{nodes[i].__style[s]=nodes[i][s];// store original value
	if(s in inactive){nodes[i][s]=typeof inactive[s]==='function'?inactive[s].call(null,nodes[i]):inactive[s];}});}globalActivation=true;activeNodes.length=0;if(!suppressRender){obj.renderer.render(obj.nodes);}};const onEnd=function(){let opts=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{suppressRender:false};const{suppressRender}=opts;const nodes=getNodes();const len=nodes.length;for(let i=0;i<len;i++){if(nodes[i].__style){Object.keys(nodes[i].__style).forEach(s=>{nodes[i][s]=nodes[i].__style[s];});nodes[i].__style=undefined;}}activeNodes.length=0;if(!suppressRender){obj.renderer.render(obj.nodes);}};const onUpdate=()=>{const changed=update();if(changed){const renderedNodes=typeof obj.config.sortNodes==='function'?obj.config.sortNodes(obj):obj.nodes;if(typeof obj.config.customRender==='function'){obj.config.customRender({render:obj.renderer.render,nodes:renderedNodes});}else {obj.renderer.render(renderedNodes);}}};const externalUpdate=()=>{activeNodes.length=0;globalActivation=true;update();};brusher.on('start',onStart);brusher.on('end',onEnd);brusher.on('update',onUpdate);function cleanUp(){brusher.removeListener('start',onStart);brusher.removeListener('end',onEnd);brusher.removeListener('update',onUpdate);}return {isActive(){return brusher.isActive();},update:externalUpdate,cleanUp};}function brushDataPoints(_ref2){let{dataPoints,action,chart,trigger}=_ref2;if(!trigger){return;}const dataProps=trigger.data||[''];let rangeBrush={items:[],actionFn:'toggleRanges'};let valueBrush={items:[],actionFn:'toggleValues'};if(['add','remove','set','toggle'].indexOf(action)!==-1){rangeBrush.actionFn="".concat(action,"Ranges");valueBrush.actionFn="".concat(action,"Values");}for(let i=0;i<dataPoints.length;i++){const dataPoint=dataPoints[i];if(!dataPoint){continue;}dataProps.forEach(p=>{let d=dataPoint&&!p?dataPoint:dataPoint[p];if(d){let it={key:d.source.field};if(typeof d.source.key!=='undefined'){it.key="".concat(d.source.key,"/").concat(d.source.field);}if(Array.isArray(d.value)){it.range={min:d.value[0],max:d.value[1]};rangeBrush.items.push(it);}else {it.value=d.value;valueBrush.items.push(it);}}});}trigger.contexts.forEach(c=>{if(rangeBrush.items.length){chart.brush(c)[rangeBrush.actionFn](rangeBrush.items);}else {chart.brush(c)[valueBrush.actionFn](valueBrush.items);// call action even if there are items to potentially clear what is currently in the brush
	}});}function brushFromSceneNodes(_ref3){let{nodes,action,chart,trigger}=_ref3;const dataPoints=[];for(let i=0;i<nodes.length;i++){const node=nodes[i];let nodeData=node.data;if(nodeData!==null){dataPoints.push(nodeData);}}brushDataPoints({dataPoints,action,chart,trigger});}function resolveEvent(_ref4){let{collisions,t,config,action}=_ref4;let brushCollisions=[];let resolved=false;if(collisions.length>0){brushCollisions=collisions;resolved=true;if(t.propagation==='stop'){brushCollisions=[collisions[collisions.length-1]];}}const nodes=brushCollisions.map(c=>c.node);brushFromSceneNodes({nodes,action,chart:config.chart,data:config.data,trigger:t});return resolved;}function touchSingleContactPoint(e,rect){if(e.changedTouches.length!==1){return null;}return {x:e.changedTouches[0].clientX-rect.left,y:e.changedTouches[0].clientY-rect.top};}function singleContactPoint(e,rect){return {x:e.clientX-rect.left,y:e.clientY-rect.top};}function resolveCollisions(e,t,renderer){const rect=renderer.element().getBoundingClientRect();let p=isTouchEvent(e)?touchSingleContactPoint(e,rect):singleContactPoint(e,rect);if(p===null||p.x<0||p.y<0||p.x>rect.width||p.y>rect.height){// TODO include radius in this check?
	return [];}if(t.touchRadius>0&&isTouchEvent(e)){p={cx:p.x,cy:p.y,r:t.touchRadius// TODO Use touch event radius/width value (Need to handle dpi scaling as well)
	};}else if(t.mouseRadius>0&&!isTouchEvent(e)){p={cx:p.x,cy:p.y,r:t.mouseRadius};}return renderer.itemsAt(p);}function resolveAction(action,e,def){if(action){if(typeof action==='function'){return action(e);}return action;}return def;}function resolveTapEvent(_ref5){let{e,t,config}=_ref5;const collisions=resolveCollisions(e,t,config.renderer);return resolveEvent({collisions,t,config,action:resolveAction(t.action,e,'toggle')});}function resolveOverEvent(_ref6){let{e,t,config}=_ref6;const collisions=resolveCollisions(e,t,config.renderer);return resolveEvent({collisions,t,config,action:resolveAction(t.action,e,'set')});}/**
	 * A list of supported attributes in lower camelCase notation mapped to corresponding kebab-case notation.
	 * The kebab-case notations are a sub-set of SVG attributes (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute).
	 * @ignore
	 * @private
	 */const mappedAttributes={fill:'fill',stroke:'stroke',opacity:'opacity',strokeWidth:'stroke-width',strokeLinejoin:'stroke-linejoin',fontFamily:'font-family',fontSize:'font-size',fontStyle:'font-style',textDecoration:'text-decoration',fontWeight:'font-weight',baseline:'dominant-baseline',// Special case where we have defined our own attribute name
	dominantBaseline:'dominant-baseline',anchor:'text-anchor',// Special case where we have defined our own attribute name
	textAnchor:'text-anchor',maxWidth:'maxWidth',transform:'transform',strokeDasharray:'stroke-dasharray',id:'id'};/**
	 * Takes a target object and assign each supported attribute from a source object to that target.
	 * Each supported attributes is converted to a mapped kebab-case notation.
	 * @ignore
	 * @private
	 * @param {object} target - Target object on which to assign mapped attribute values
	 * @param {object} source - Source object
	 */function assignMappedAttribute(target,source){Object.keys(mappedAttributes).forEach(key=>{const sourceValue=source[key];if(typeof sourceValue!=='undefined'){const mappedKey=mappedAttributes[key];target[mappedKey]=sourceValue;}});}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolCircle
	 */function circle(options){return {type:'circle',fill:'black',cx:options.x,cy:options.y,r:options.size/2};}function pointsToPath(points){let close=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;let d='';for(let i=0;i<points.length;i++){const p=points[i];if(i===0){d+="M".concat(p.x," ").concat(p.y);}else {d+="L".concat(p.x," ").concat(p.y);}d+=' ';}if(close){d+='Z';}return d;}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolDiamond
	 */function diamond(options){const size=options.size;const left=options.x-size/2;const top=options.y-size/2;const points=[{x:left,y:top+size/2},{x:left+size/2,y:top},{x:left+size,y:top+size/2},{x:left+size/2,y:top+size},{x:left,y:top+size/2}];return {type:'path',fill:'black',d:pointsToPath(points)};}function generateCrossPoints(x,y,size,barWidth){const r=size/2;const innerLeft=x-barWidth/2;const innerTop=y-barWidth/2;const left=x-r;const top=y-r;return [{x:innerLeft,y:innerTop},// Top
	{x:innerLeft,y:top},{x:innerLeft+barWidth,y:top},{x:innerLeft+barWidth,y:innerTop},// Right
	{x:left+size,y:innerTop},{x:left+size,y:innerTop+barWidth},{x:innerLeft+barWidth,y:innerTop+barWidth},// Bottom
	{x:innerLeft+barWidth,y:top+size},{x:innerLeft,y:top+size},{x:innerLeft,y:innerTop+barWidth},// Left
	{x:left,y:innerTop+barWidth},{x:left,y:innerTop}];}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolCross
	 * @property {number} [width] - Width of the diagonals
	 */function cross(options){const x=options.x;const y=options.y;const r=options.size/2;const width=isNaN(options.width)?r/2:options.width;const barWidth=Math.min(width,r);const points=generateCrossPoints(x,y,options.size,barWidth);return {type:'path',fill:'black',d:pointsToPath(points)};}/**
	 * Get x1, y1, x2, y2 point from angle
	 * Source: {@link https://codepen.io/NV/pen/jcnmK}
	 * @private
	 *
	 * @param  {number} angle Radians
	 * @return {object}       Point with x1, y2, x2, y2.
	 */function angleToPoints(angle){let segment=Math.floor(angle/Math.PI*2)+2;let diagonal=(0.5*segment+0.25)*Math.PI;let op=Math.cos(Math.abs(diagonal-angle))*Math.sqrt(2);let x=op*Math.cos(angle);let y=op*Math.sin(angle);return {x1:x<0?1:0,y1:y<0?1:0,x2:x>=0?x:x+1,y2:y>=0?y:y+1};}/**
	 * Turns degrees into radians
	 * @private
	 *
	 * @param  {number} degrees Degrees
	 * @return {number}         Radians
	 */function toRadians(d){return -d/180*Math.PI;}/**
	 * Get x1, y1, x2, y2 point from degree
	 * @private
	 *
	 * @param  {number} d Degree
	 * @return {object}   Point with x1, y2, x2, y2.
	 */function degreesToPoints(d){return angleToPoints(toRadians(d));}function add(v1,v2){return {x:v1.x+v2.x,y:v1.y+v2.y};}function sub(v1,v2){return {x:v1.x-v2.x,y:v1.y-v2.y};}function scalarMultiply(v,s){return {x:v.x*s,y:v.y*s};}function distanceX(v1,v2){return v1.x-v2.x;}function distanceY(v1,v2){return v1.y-v2.y;}function sqrDistance(v1,v2){return distanceX(v1,v2)**2+distanceY(v1,v2)**2;}function distance(v1,v2){return Math.sqrt(sqrDistance(v1,v2));}function dot(v1,v2){return v1.x*v2.x+v1.y*v2.y;}function projectOnto(v1,v2){const m=dot(v1,v2)/dot(v2,v2)||1;return {x:v2.x*m,y:v2.y*m};}function rotate(v,radians){let origin=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{x:0,y:0};const cos=Math.cos(radians);const sin=Math.sin(radians);const t1=sub(v,origin);const t2={x:cos*t1.x-sin*t1.y,y:sin*t1.x+cos*t1.y};return add(t2,origin);}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolSaltire
	 * @property {number} [width] - Width of the diagonals
	 */function saltire(options){const radians=toRadians(45);const r=options.size/2;const width=isNaN(options.width)?r/2:options.width;const barWidth=Math.min(width,r);let adjustedSize=options.size;// Adjust for the barwidth and rotation angle, so that the visual part is always inside the symbol area
	const h=Math.sin(Math.asin(-radians))*(barWidth/2);const c=r/Math.sin(-radians);adjustedSize+=(c-r)*2;adjustedSize-=h*2;const centroid={x:options.x,y:options.y};const points=generateCrossPoints(options.x,options.y,adjustedSize,barWidth).map(p=>rotate(p,radians,centroid));return {type:'path',fill:'black',d:pointsToPath(points)};}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolSquare
	 */function square(options){const size=options.size;return {type:'rect',fill:'black',x:options.x-size/2,y:options.y-size/2,width:size,height:size};}const DIRECTION_TO_ANGLE={up:0,down:180,left:90,right:-90};/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolTriangle
	 * @property {string} [direction='up'] - Direction of the triangle ('up'|'down'|'left'|'right')
	 */function triangle(options){const size=options.size;const p={x:options.x,y:options.y};const directionAngle=DIRECTION_TO_ANGLE[options.direction]||0;const halfSize=size/2;const left=options.x-halfSize;const top=options.y-halfSize;let points=[{x:left,y:top+size},{x:left+halfSize,y:top},{x:left+size,y:top+size},{x:left,y:top+size}];const radians=toRadians(directionAngle);points=points.map(pp=>rotate(pp,radians,p));return {type:'path',fill:'black',d:pointsToPath(points)};}function createRectCollider(_ref){let{x,y,size}=_ref;const r=size/2;return {type:'rect',x:x-r,y:y-r,width:size,height:size};}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolLine
	 * @property {string} [direction='horizontal'] - Direction of line ('horizontal'|'vertical').
	 */function line$1(options){const isVertical=options.direction==='vertical';const r=options.size/2;const x=options.x;const y=options.y;return {type:'line',stroke:'black',strokeWidth:1,x1:x-(isVertical?0:r),y1:y-(isVertical?r:0),x2:x+(isVertical?0:r),y2:y+(isVertical?r:0),collider:createRectCollider(options)// TODO Use visual collider?
	};}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolStar
	 * @property {number} [points=5] - Number of points on the star
	 * @property {number} [startAngle=90] - Start drawing angle
	 * @property {number} [innerRadius=size/2] - Size of the star core. My not exceed size of symbol.
	 */function star(options){const size=options.size;const points=[];const outerRadius=size/2;const drawPoints=options.points||5;const innerRadius=Math.min(options.innerRadius||size/2,size)/2;const startAngle=isNaN(options.startAngle)?90:options.startAngle;const angle=360/drawPoints;for(let i=1;i<=drawPoints;i++){const pAngle=angle*i+startAngle;const radians=toRadians(pAngle);const innerRadians=toRadians(pAngle+angle/2);const y=Math.sin(radians);const x=Math.cos(radians);const iy=Math.sin(innerRadians);const ix=Math.cos(innerRadians);points.push({x:options.x+x*outerRadius,y:options.y+y*outerRadius});points.push({x:options.x+ix*innerRadius,y:options.y+iy*innerRadius});}return {type:'path',fill:'black',d:pointsToPath(points)};}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolPolygon
	 * @property {object} [sides=6] - Number of sides on the regular polygon
	 * @property {object} [startAngle=0] - Start drawing angle
	 */function nPolygon(options){const points=[];const radius=options.size/2;const drawPoints=Math.max(isNaN(options.sides)?6:options.sides,3);const angle=360/drawPoints;const startAngle=isNaN(options.startAngle)?0:options.startAngle;for(let i=1;i<=drawPoints;i++){const radians=toRadians(angle*i+startAngle);const y=Math.sin(radians);const x=Math.cos(radians);points.push({x:options.x+x*radius,y:options.y+y*radius});}return {type:'path',fill:'black',d:pointsToPath(points)};}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolBar
	 * @property {string} [direction='horizontal'] - Direction of bar ('horizontal'|'vertical').
	 */function bar(options){const p={x:options.x,y:options.y};const isVertical=options.direction==='vertical';const r=options.size/2;const width=r/2;const halfWidth=width/2;let points=[{x:p.x-r,y:p.y+halfWidth},{x:p.x-r,y:p.y-halfWidth},{x:p.x+r,y:p.y-halfWidth},{x:p.x+r,y:p.y+halfWidth}];if(isVertical){const radians=toRadians(90);points=points.map(pp=>rotate(pp,radians,p));}const rect=pointsToRect(points);rect.type='rect';rect.fill='black';return rect;}/**
	 * @private
	 * @extends Symbol
	 * @typedef {object} SymbolRect
	 */function rect(options){const{x,y,size}=options;const width=typeof options.width==='undefined'?size:options.width;const height=typeof options.height==='undefined'?size:options.height;return {type:'rect',fill:'black',x:x-width/2,y:y-height/2,width,height};}const parentReg=registryFactory();parentReg.add('circle',circle);parentReg.add('diamond',diamond);parentReg.add('saltire',saltire);parentReg.add('square',square);parentReg.add('triangle',triangle);parentReg.add('line',line$1);parentReg.add('star',star);parentReg.add('n-polygon',nPolygon);parentReg.add('cross',cross);parentReg.add('bar',bar);parentReg.add('rect',rect);function applyOpts(obj){let opts=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};Object.keys(opts).forEach(key=>{if(typeof mappedAttributes[key]!=='undefined'&&key!=='transform'){obj[key]=opts[key];}});}/**
	 * Factory function for symbols.
	 * Options object is passed to symbols function.
	 * @private
	 * @param {SymbolRect|SymbolBar|SymbolCircle|SymbolCross|SymbolDiamond|SymbolLine|SymbolPolygon|SymbolSaltire|SymbolSquare|SymbolStar|SymbolTriangle} options - Options definition may contain any of the supported display-object attributes
	 * @returns {object} A node definition
	 */const create$m=function(){let reg=arguments.length>0&&arguments[0]!==undefined?arguments[0]:parentReg;return function(){let options=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};// TODO handle reserverd properties x, y, size, data, etc..
	const fn=reg.get(options.type);if(fn){const s=fn(options);applyOpts(s,options);if(typeof options.data!=='undefined'){s.data=options.data;}return s;}return fn;};};/**
	 * Mandatory symbol config
	 * @private
	 * @typedef {object} Symbol
	 * @property {object} options - Options definition may contain any of the supported display-object attributes
	 * @property {string} options.type - Type of symbol
	 * @property {number} options.x - x-coordinate
	 * @property {number} options.y - y-coordinate
	 * @property {number} options.size
	 * @property {object} [options.data]
	 *//**
	 * Initilize a new dock configuration
	 * @private
	 * @param {object} [settings] - Settings object
	 * @returns {object} A dock configuration instance
	 * @example
	 * let instance = create({
	 *  dock: 'left',
	 *  displayOrder: 2,
	 *  prioOrder: 1,
	 *  preferredSize: 33,
	 *  minimumLayoutMode: 'L',
	 *  show: true
	 * });
	 */function create$l(){let settings=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let callbackContext=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let{dock='center',displayOrder=0,prioOrder=0,preferredSize=0,minimumLayoutMode,show=true}=settings;// avoid empty string dock
	dock=dock||'center';/**
	   * @private
	   * @alias dockConfig
	   * @interface
	   */const dockConfig={/**
	     * Returns the preferred size of a component.
	     * The return value of the function can either be a number representing the required size in the dock direction
	     * or an object with a `size` and `edgeBleed` property.
	     * @param {object} [inner]
	     * @param {object} [outer]
	     * @returns {number|object} Returns the computed preferred size
	     * @example
	     * dockConfig.computePreferredSize(() => 150); // Require a size of 150 in the dock direction
	     *
	     * dockConfig.computePreferredSize(() => ({
	     *  size: 150,
	     *  edgeBleed: {
	     *    left: 50,
	     *    right: 50
	     *  }
	     * })); // Require a size of 150 in the dock direction and a bleed size of 50 to the left and right dock direction
	     */computePreferredSize(_ref){let{inner,outer,children}=_ref;if(typeof preferredSize==='function'){return preferredSize({inner,outer,children,dock:this.dock()},callbackContext);}return preferredSize;},/**
	     * Set the dock direction, supported values are left | right | top | bottom. Any other value will be interpreted as center dock.
	     * @param {string} [val=''] - Dock direction
	     * @returns {this} The current context
	     * @example
	     * dockConfig.dock('left');
	     */dock(val){if(typeof val!=='undefined'){dock=val;return this;}return typeof dock==='function'?dock(callbackContext):dock;},/**
	     * The `displayOrder` property is used by the layout engine to lay out components.
	     * Components are interpreted in the ascending order of the `displayOrder` value. The layout engine apply the value in two ways,
	     * the first is the order in which components are rendererd. The second is the area components are laid out in
	     * when they have a direction, i.e. docked to either top, bottom, left or right.
	     *
	     * If docked at the same area, the component with a higher `displayOrder` will be rendered
	     * on top of the component with a lower `displayOrder`. It can be seen as defining a z-index.
	     * A lower `displayOrder` also means that a component will be laid out first in a given direction,
	     * i.e. laid out closer to the central area (non-directional area) then a component with a higher `displayOrder`.
	     * It can in this case be seen as the x-index or y-index.
	     * @param {number} [val=0] - The display order
	     * @returns {this|number} The current context or display order
	     * @example
	     * dockConfig.displayOrder(99);
	     */displayOrder(val){if(typeof val!=='undefined'){displayOrder=val;return this;}return typeof displayOrder==='function'?displayOrder(callbackContext):displayOrder;},/**
	     * The `prioOrder` property is used to define the order in which components are added to the layout engine,
	     * this is done before any components are laid out. When there is not enough space to add any more components
	     * to a given area, all components not all ready added, are then discarded. The `prioOrder` is interpreted
	     * in the ascending order. Such that a lower value is added to the layout engine first.
	     * @param {number} [val=0] - The prio order
	     * @returns {this|number} The current context or prio order
	     * @example
	     * dockConfig.prioOrder(-1);
	     */prioOrder(val){if(typeof val!=='undefined'){prioOrder=val;return this;}return typeof prioOrder==='function'?prioOrder(callbackContext):prioOrder;},/**
	     * Ger or set the minimumLayoutMode
	     * @param {string|object} [val] - The minimum layout mode
	     * @returns {string|object|this} If no parameter is passed the current context is returned, else the current layout mode.
	     * @example
	     * dockConfig.minimumLayoutMode('L');
	     * dockConfig.minimumLayoutMode({ width: 'S', height: 'L' });
	     */minimumLayoutMode(val){if(typeof val!=='undefined'){minimumLayoutMode=val;return this;}return typeof minimumLayoutMode==='function'?minimumLayoutMode(callbackContext):minimumLayoutMode;},/**
	     * Set the component visibility. If false the component is not added to the layout engine.
	     * @param {boolean} [val=true] - Toggle visibility
	     * @returns {this|boolean} The current context or show
	     */show(val){if(typeof val!=='undefined'){show=val;return this;}return typeof show==='function'?show(callbackContext):show;}};return dockConfig;}const isReservedProperty=prop=>['on','preferredSize','created','beforeMount','mounted','resize','beforeUpdate','updated','beforeRender','render','beforeUnmount','beforeDestroy','destroyed','defaultSettings','data','settings','formatter','scale','chart','dockConfig','mediator','style','resolver','registries','_DO_NOT_USE_getInfo','symbol','isVisible'].some(name=>name===prop);function prepareContext(ctx,definition,opts){const{require=[]}=definition;const mediatorSettings=definition.mediator||{};const{settings,formatter,scale,data,renderer,chart,dockConfig,mediator,instance,rect,style,registries,resolver,update,_DO_NOT_USE_getInfo,symbol,isVisible}=opts;ctx.emit=()=>{};if(isVisible){ctx.isVisible=isVisible;}// TODO add setters and log warnings / errors to console
	Object.defineProperty(ctx,'settings',{get:settings});Object.defineProperty(ctx,'data',{get:data});Object.defineProperty(ctx,'formatter',{get:formatter});Object.defineProperty(ctx,'scale',{get:scale});Object.defineProperty(ctx,'mediator',{get:mediator});Object.defineProperty(ctx,'style',{get:style});Object.defineProperty(ctx,'registries',{get:registries});if(rect){Object.defineProperty(ctx,'rect',{get:rect});}// TODO _DO_NOT_USE_getInfo is a temporary solution to expose info from a component
	// It should replace ASAP with a proper solution.
	// The only component activaly in need of it is the legend-cat
	if(_DO_NOT_USE_getInfo){ctx._DO_NOT_USE_getInfo=_DO_NOT_USE_getInfo;}Object.keys(definition).forEach(key=>{if(!isReservedProperty(key)){// Add non-lifecycle methods to the context
	if(typeof definition[key]==='function'){ctx[key]=definition[key].bind(ctx);}else {ctx[key]=definition[key];}}});// Add properties to context
	require.forEach(req=>{if(req==='renderer'){Object.defineProperty(ctx,'renderer',{get:renderer});}else if(req==='chart'){Object.defineProperty(ctx,'chart',{get:chart});}else if(req==='dockConfig'){Object.defineProperty(ctx,'dockConfig',{get:dockConfig});}else if(req==='instance'){Object.defineProperty(ctx,'instance',{get:instance});}else if(req==='update'&&update){Object.defineProperty(ctx,'update',{get:update});}else if(req==='resolver'){Object.defineProperty(ctx,'resolver',{get:resolver});}else if(req==='symbol'){Object.defineProperty(ctx,'symbol',{get:symbol});}});Object.keys(mediatorSettings).forEach(eventName=>{ctx.mediator.on(eventName,mediatorSettings[eventName].bind(ctx));});}function createDockDefinition(settings,preferredSize,logger){const getLayoutProperty=propName=>{if(settings[propName]){logger.warn("Deprecation Warning the ".concat(propName," property should be moved into layout: {} property"));// eslint-disable-line no-console
	return settings[propName];}return settings.layout?settings.layout[propName]:undefined;};const def={};def.displayOrder=getLayoutProperty('displayOrder');def.dock=getLayoutProperty('dock');def.prioOrder=getLayoutProperty('prioOrder');def.minimumLayoutMode=getLayoutProperty('minimumLayoutMode');// move layout properties to layout object
	settings.layout=settings.layout||{};settings.layout.displayOrder=typeof def.displayOrder!=='undefined'?def.displayOrder:settings.layout.displayOrder;settings.layout.prioOrder=typeof def.prioOrder!=='undefined'?def.prioOrder:settings.layout.prioOrder;settings.layout.dock=def.dock||settings.layout.dock;settings.layout.minimumLayoutMode=def.minimumLayoutMode||settings.layout.minimumLayoutMode;// not directly a dock layout property
	def.show=settings.show;def.preferredSize=preferredSize;return def;}function setUpEmitter(ctx,emitter,settings){// Object.defineProperty(ctx, 'emitter', )
	Object.keys(settings.on||{}).forEach(event=>{ctx.eventListeners=ctx.eventListeners||[];const listener=settings.on[event].bind(ctx);ctx.eventListeners.push({event,listener});emitter.on(event,listener);});ctx.emit=function(name){for(var _len=arguments.length,event=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){event[_key-1]=arguments[_key];}return emitter.emit(name,...event);};}function tearDownEmitter(ctx,emitter){if(ctx.eventListeners){ctx.eventListeners.forEach(_ref=>{let{event,listener}=_ref;emitter.removeListener(event,listener);});ctx.eventListeners.length=0;}ctx.emit=()=>{};}// First render
	// preferredSize -> resize -> beforeRender -> render -> mounted
	// Normal update
	// beforeUpdate -> preferredSize -> resize -> beforeRender -> render -> updated
	// Update without relayout
	// beforeUpdate -> beforeRender -> render -> updated
	// TODO support es6 classes
	function componentFactory(definition){let context=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};const{defaultSettings={},_DO_NOT_USE_getInfo=()=>({})}=definition;const{chart,container,mediator,registries,theme,renderer// Used by tests
	}=context;const emitter=EventEmitter.mixin({});let config=context.settings||{};let settings=extend$1$1(true,{},defaultSettings,config);let data=[];let scale;let formatter;let element;let size;let style;let resolver=settingsResolver({chart});let isVisible=false;const brushArgs={nodes:[],chart,config:settings.brush||{},renderer:null};const brushTriggers={tap:[],over:[]};const brushStylers=[];const definitionContext={};const instanceContext=extend$1$1({},config);// Create a callback that calls lifecycle functions in the definition and config (if they exist).
	function createCallback(method){let defaultMethod=arguments.length>1&&arguments[1]!==undefined?arguments[1]:()=>{};let canBeValue=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;return function cb(){const inDefinition=typeof definition[method]!=='undefined';const inConfig=typeof config[method]!=='undefined';let returnValue;for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++){args[_key2]=arguments[_key2];}if(inDefinition){if(typeof definition[method]==='function'){returnValue=definition[method].call(definitionContext,...args);}else if(canBeValue){returnValue=definition[method];}}if(inConfig){if(typeof config[method]==='function'){returnValue=config[method].call(instanceContext,...args);}else if(canBeValue){returnValue=config[method];}}if(!inDefinition&&!inConfig){returnValue=defaultMethod.call(definitionContext,...args);}return returnValue;};}const preferredSize=createCallback('preferredSize',()=>0,true);const resize=createCallback('resize',_ref2=>{let{inner}=_ref2;return inner;});const created=createCallback('created');const beforeMount=createCallback('beforeMount');const mounted=createCallback('mounted');const beforeUnmount=createCallback('beforeUnmount');const beforeUpdate=createCallback('beforeUpdate');const updated=createCallback('updated');const beforeRender=createCallback('beforeRender');const beforeDestroy=createCallback('beforeDestroy');const destroyed=createCallback('destroyed');const render=definition.render;// Do not allow overriding of this function
	const addBrushStylers=()=>{if(settings.brush){(settings.brush.consume||[]).forEach(b=>{if(b.context&&b.style){brushStylers.push(styler(brushArgs,b));}});}};const addBrushTriggers=()=>{if(settings.brush){(settings.brush.trigger||[]).forEach(t=>{if(t.on==='over'){brushTriggers.over.push(t);}else {brushTriggers.tap.push(t);}});}};Object.defineProperty(brushArgs,'data',{get:()=>data});const rendString=settings.renderer||definition.renderer;const rend=rendString?renderer||registries.renderer(rendString)():renderer||registries.renderer()();if(typeof rend.settings==='function'){rend.settings(settings.rendererSettings);}brushArgs.renderer=rend;const dockConfigCallbackContext={resources:chart.logger?{logger:chart.logger()}:{}};let dockConfig=create$l(createDockDefinition(settings,preferredSize,chart.logger()),dockConfigCallbackContext);const appendComponentMeta=node=>{node.key=settings.key;node.element=rend.element();};const fn=()=>{};fn.dockConfig=()=>dockConfig;// Set new settings - will trigger mapping of data and creation of scale / formatter.
	fn.set=function(){let opts=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};if(opts.settings){config=opts.settings;settings=extend$1$1(true,{},defaultSettings,opts.settings);dockConfig=create$l(createDockDefinition(settings,preferredSize,chart.logger()),dockConfigCallbackContext);brushArgs.config=settings.brush||{};}if(settings.scale){scale=chart.scale(settings.scale);}if(settings.data){const{rendererSettings}=settings;const progressive=typeof(rendererSettings===null||rendererSettings===void 0?void 0:rendererSettings.progressive)==='function'&&rendererSettings.progressive();const extracted=extract$1$1(settings.data,{dataset:chart.dataset,collection:chart.dataCollection},{logger:chart.logger()},chart.dataCollection);if(!progressive){data=extracted;}else if(progressive.isFirst){data=extracted;if(data.items){data.items=[...extracted.items];}}else if(data.items){data.items=[...data.items,...(extracted.items||[])];}}else if(scale){data=scale.data();}else {data=[];}if(typeof settings.formatter==='string'){formatter=chart.formatter(settings.formatter);}else if(typeof settings.formatter==='object'){formatter=chart.formatter(settings.formatter);}else if(scale&&scale.data().fields){formatter=scale.data().fields[0].formatter();}style=theme.style(settings.style||{});};fn.resize=function(){let inner=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let outer=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};const newSize=resize({inner,outer});if(newSize){size=rend.size(newSize);}else {size=rend.size(inner);}instanceContext.rect=extend$1$1(true,{computedPhysical:size.computedPhysical,computedOuter:outer.computed||outer,computedInner:inner.computed||inner},inner);size=extend$1$1(true,{computedOuter:outer.computed||outer,computedInner:inner.computed||inner},size);};fn.getRect=()=>instanceContext.rect;const getRenderArgs=()=>{const renderArgs=rend.renderArgs?rend.renderArgs.slice(0):[];const{rendererSettings}=settings;let d=data;const progressive=typeof(rendererSettings===null||rendererSettings===void 0?void 0:rendererSettings.progressive)==='function'&&rendererSettings.progressive();if(data.items&&progressive){d=_objectSpread2$1(_objectSpread2$1({},data),{},{items:data.items.slice(progressive.start,progressive.end)});}renderArgs.push({data:d});return renderArgs;};fn.beforeMount=beforeMount;fn.beforeRender=()=>{beforeRender({size});};let currentNodes;let preComputedRect;function updateBrushNodes(nodes){const{rendererSettings}=settings;const progressive=typeof(rendererSettings===null||rendererSettings===void 0?void 0:rendererSettings.progressive)==='function'&&rendererSettings.progressive();if(!progressive){brushArgs.nodes=nodes;}else if(progressive.isFirst){brushArgs.nodes=[...(nodes||[])];}else if(brushArgs.nodes){brushArgs.nodes=[...brushArgs.nodes,...(nodes||[])];}}fn.render=()=>{const nodes=render.call(definitionContext,...getRenderArgs());updateBrushNodes(nodes);rend.render(nodes);currentNodes=nodes;preComputedRect=instanceContext.rect.computed;};fn.hide=()=>{fn.unmount();rend.size({x:0,y:0,width:0,height:0});rend.clear();};fn.beforeUpdate=()=>{beforeUpdate({settings,data});};let currentTween;fn.update=()=>{if(currentTween){currentTween.stop();}const{rendererSettings,brush,animations}=settings;if(typeof(rendererSettings===null||rendererSettings===void 0?void 0:rendererSettings.transform)==='function'&&rendererSettings.transform()){rend.render();currentNodes=null;return;}const nodes=render.call(definitionContext,...getRenderArgs());updateBrushNodes(nodes);// Reset brush stylers and triggers
	brushStylers.forEach(b=>b.cleanUp());brushStylers.length=0;brushTriggers.tap=[];brushTriggers.over=[];if(brush){addBrushStylers();addBrushTriggers();}brushStylers.forEach(bs=>{if(bs.isActive()){bs.update();}});if(currentNodes&&animations&&(typeof animations.enabled==='function'?animations.enabled():animations.enabled)){/* The issue: as soon as animation begins, the layout changes immediately to a new layout while the displaying nodes' positions are still calculated relative to the old layout.
	      This makes the nodes "jump" at the beginning of the animations. To fix this, we can compesate for the layout changes by adjusting the relative positions of the displaying nodes.
	      For example, if the new layout of the point component (the central area) jumps 10px to the left compared to the old layout, we shift the points 10px to the right, making the absolute positions of the points stay the same. */if(animations.compensateForLayoutChanges){animations.compensateForLayoutChanges({currentNodes,currentRect:instanceContext.rect.computed,previousRect:preComputedRect});}currentTween=tween({old:currentNodes,current:nodes},{renderer:rend},animations,chart.storage);currentTween.start();}else {rend.render(nodes);}currentNodes=nodes;preComputedRect=instanceContext.rect.computed;if(rend.setKey&&typeof config.key==='string'){rend.setKey(config.key);}};fn.updated=updated;fn.destroy=()=>{fn.unmount();beforeDestroy(element);rend.destroy();destroyed();element=null;};/**
	   * Update active nodes. For now this can be used as a way update and apply brushing on nodes.
	   * Ex: if a component have changed the nodes since its initial render.
	   * @param {Nodes[]} nodes
	   * @deprecated
	   * @ignore
	   */const updateNodes=nodes=>{brushArgs.nodes=nodes;brushStylers.forEach(bs=>{if(bs.isActive()){bs.update();}});rend.render(nodes);};// Set contexts, note that the definition and instance need different contexts (for example if they have different 'require' props)
	prepareContext(definitionContext,definition,{settings:()=>settings,data:()=>data,scale:()=>scale,formatter:()=>formatter,renderer:()=>rend,chart:()=>chart,dockConfig:()=>dockConfig,mediator:()=>mediator,instance:()=>instanceContext,rect:()=>instanceContext.rect,style:()=>style,update:()=>updateNodes,registries:()=>registries,resolver:()=>resolver,symbol:()=>create$m(registries.symbol)});/**
	   * Component instance
	   * @typedef {object} Component
	   * @property {string} type Type of component
	   * @property {string} key Key of the component
	   */prepareContext(instanceContext,config,{settings:()=>settings,data:()=>data,scale:()=>scale,formatter:()=>formatter,renderer:()=>rend,chart:()=>chart,dockConfig:()=>dockConfig,mediator:()=>mediator,style:()=>style,_DO_NOT_USE_getInfo:_DO_NOT_USE_getInfo.bind(definitionContext),isVisible:()=>isVisible});fn.getBrushedShapes=function getBrushedShapes(brushCtx,mode,props){const shapes=[];if(settings.brush&&settings.brush.consume){const brusher=chart.brush(brushCtx);const sceneNodes=rend.findShapes('*');settings.brush.consume.filter(t=>t.context===brushCtx).forEach(consume=>{for(let i=0;i<sceneNodes.length;i++){const node=sceneNodes[i];if(node.data&&brusher.containsMappedData(node.data,props||consume.data,mode)){appendComponentMeta(node);shapes.push(node);sceneNodes.splice(i,1);i--;}}});}return shapes;};fn.findShapes=selector=>{var _currentTween;const shapes=((_currentTween=currentTween)!==null&&_currentTween!==void 0&&_currentTween.inProgress()?currentTween.targetScene:rend).findShapes(selector);for(let i=0,num=shapes.length;i<num;i++){appendComponentMeta(shapes[i]);}return shapes;};fn.shapesAt=function(shape){let opts=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};const items=rend.itemsAt(shape);let shapes;if(opts&&opts.propagation==='stop'&&items.length>0){shapes=[items.pop().node];}else {shapes=items.map(i=>i.node);}for(let i=0,num=shapes.length;i<num;i++){appendComponentMeta(shapes[i]);}return shapes;};fn.brushFromShapes=function(shapes){let trigger=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};trigger.contexts=Array.isArray(trigger.contexts)?trigger.contexts:[];const action=trigger.action||'toggle';brushFromSceneNodes({nodes:shapes,action,trigger,chart,data:brushArgs.data});};fn.mount=()=>{element=rend.element&&rend.element()?element:rend.appendTo(container);if(rend.setKey&&typeof config.key==='string'){rend.setKey(config.key);}if(settings.brush){addBrushStylers();addBrushTriggers();}setUpEmitter(instanceContext,emitter,config);setUpEmitter(definitionContext,emitter,definition);isVisible=true;};fn.mounted=()=>mounted(element);fn.unmount=()=>{[instanceContext,definitionContext].forEach(ctx=>{tearDownEmitter(ctx,emitter);});brushTriggers.tap=[];brushTriggers.over=[];brushStylers.forEach(bs=>{bs.cleanUp();});brushStylers.length=0;beforeUnmount();isVisible=false;};fn.onBrushTap=e=>{brushTriggers.tap.forEach(t=>{if(resolveTapEvent({e,t,config:brushArgs})&&t.globalPropagation==='stop'){chart.toggleBrushing(true);}});};fn.onBrushOver=e=>{brushTriggers.over.forEach(t=>{if(resolveOverEvent({e,t,config:brushArgs})&&t.globalPropagation==='stop'){chart.toggleBrushing(true);}});};/**
	   * Expose definition on instance
	   * @private
	   * @experimental
	   */fn.def=definitionContext;/**
	   * Expose instanceCtx on "instance"
	   * @private
	   * @experimental
	   */fn.ctx=instanceContext;fn.renderer=()=>rend;fn.set({settings:config});created();return fn;}function mediator(){const instance={};EventEmitter.mixin(instance);return instance;}// getValue({ person: { name: 'John Doe' } }, 'person.name');
	// => 'John Doe'
	//  getValue({ person: { name: undefined } }, 'person.name', 'John Doe');
	// => 'John Doe'
	function getValue(object,path,fallback){if(object===undefined||path===undefined){return fallback;}const steps=path.split('.');let scoped=object;for(let i=0;i<steps.length;++i){const step=steps[i];if(scoped[step]===undefined){return fallback;}scoped=scoped[step];}return scoped;}// const object = { person: { name: undefined };
	// setValue(object, 'person.name', 'John Doe');
	// console.log(object.person.name);
	// => 'John Doe'
	function setValue(object,path,value){if(object===undefined||path===undefined){return;}const steps=path.split('.');const propertyName=steps[steps.length-1];let scoped=object;for(let i=0;i<steps.length-1;++i){const step=steps[i];if(scoped[step]===undefined){scoped[step]=Number.isNaN(+steps[i+1])?{}:[];}scoped=scoped[step];}if(value===undefined){delete scoped[propertyName];return;}scoped[propertyName]=value;}function createStorage(source){const content=extend$1$1(true,{},source);const api={getAll:()=>content,getValue:(reference,fallback)=>getValue(content,reference,fallback),setValue:(reference,value)=>setValue(content,reference,value)};return api;}const EPSILON$3=1e-12;function closestPointToLine(start,end,p){const startToPoint=sub(p,start);const startToEnd=sub(end,start);const pointOnLine=add(projectOnto(startToPoint,startToEnd),start);return pointOnLine;}function isPointOnLine(start,end,p){return distance(start,p)+distance(end,p)-distance(start,end)<EPSILON$3;}/**
	 * Check if rectangle a is located inside rectangle b or if they are the same rectangle.
	 * @param {Rect} a - An rect containing (x,y) coordinates, width and height. The origin is assumed to be top left.
	 * @param {Rect} b - An rect containing (x,y) coordinates, width and height. The origin is assumed to be top left.
	 * @ignore
	 */function rectContainsRect(a,b){return a.x>=b.x&&a.x+a.width<=b.x+b.width&&a.y>=b.y&&a.y+a.height<=b.y+b.height;}/* eslint no-use-before-define: ["error", { "functions": false }] */function lineHasNoLength(line){return line.x1===line.x2&&line.y1===line.y2;}function rectHasNoSize(rect){return rect.width<=0||rect.height<=0;}function circleHasNoSize(circle){return circle.r<=0;}function toFewEdges(polygon){return polygon.edges.length<=2;}// Only when the polygon1's bounds is not inside the polygon2's bounds
	function testPolygonPolygonSubCase(polygon1,polygon2){let intersects=false;for(let i=0,len=polygon2.edges.length;i<len;i++){intersects=testPolygonLine(polygon1,pointsToLine(polygon2.edges[i]));if(intersects===true){return true;}}return false;}// Only when the geopolygon's bounds is not inside the polygon's bounds
	function testGeoPolygonPolygonCase1(geopolygon,polygon){let intersects=false;for(let i=0,len=polygon.edges.length;i<len;i++){intersects=testGeoPolygonLine(geopolygon,pointsToLine(polygon.edges[i]));if(intersects===true){return true;}}return false;}// Only when the geopolygon's bounds is inside the polygon's bounds
	function testGeoPolygonPolygonCase2(geopolygon,polygon){let intersects=false;const{numPolygons,polygons}=geopolygon;for(let n=0;n<numPolygons;n++){intersects=testPolygonPolygon(polygon,polygons[n]);if(intersects===true){return true;}}return false;}// Only when the geopolygon1's bounds is not inside the geopolygon2's bounds
	function testGeoPolygonGeoPolygonSubCase(geopolygon1,geopolygon2){let intersects=false;const{numPolygons,polygons}=geopolygon2;for(let n=0;n<numPolygons;n++){let polygon=polygons[n];intersects=testGeoPolygonPolygon(geopolygon1,polygon);if(intersects===true){return true;}}return false;}/**
	 * Test if a Circle contains a point. If so, returns true and false otherwise.
	 * Circle muse have a radius greater then 0.
	 * @private
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @param {object} point
	 * @param {number} point.x - x-coordinate
	 * @param {number} point.y - y-coordinate
	 * @return {boolean} true if circle contains point
	 */function testCirclePoint(circle,point){if(circleHasNoSize(circle)){return false;}const center={x:circle.cx,y:circle.cy};const sqrDist=sqrDistance(center,point);if(sqrDist<=circle.r**2){return true;}return false;}/**
	 * Test if a Circle collide with a rectangle. If so, returns true and false otherwise.
	 * Circle muse have a radius greater then 0.
	 * Rectangle must have a width and height greather then 0.
	 * @private
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @return {boolean} true if circle collide with rectangle
	 */function testCircleRect(circle,rect){if(rectHasNoSize(rect)||circleHasNoSize(circle)){return false;}const rX=rect.width/2;const rY=rect.height/2;const rcX=rect.x+rX;const rcY=rect.y+rY;const r=circle.r;const cx=circle.cx;const cy=circle.cy;const dX=Math.abs(cx-rcX);const dY=Math.abs(cy-rcY);if(dX>rX+r||dY>rY+r){return false;}if(dX<=rX||dY<=rY){return true;}const sqrDist=(dX-rX)**2+(dY-rY)**2;return sqrDist<=r**2;}/**
	 * Test if a Circle collide with a line segment. If so, returns true and false otherwise.
	 * Circle muse have a radius greater then 0.
	 * Line must have a length greater then 0.
	 * @private
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @return {boolean} true if circle collide with line
	 */function testCircleLine(circle,line){if(circleHasNoSize(circle)||lineHasNoLength(line)){return false;}const[p1,p2]=lineToPoints(line);if(testCirclePoint(circle,p1)||testCirclePoint(circle,p2)){return true;}const center={x:circle.cx,y:circle.cy};const pointOnLine=closestPointToLine(p1,p2,center);const dist=sqrDistance(pointOnLine,center);return dist<=circle.r**2&&isPointOnLine(p1,p2,pointOnLine);}/**
	 * Test if a Circle collide with another Circle. If so, returns true and false otherwise.
	 * Both circles muse have a radius greater then 0.
	 * @private
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @return {boolean} true if circle collide with circle
	 */function testCircleCircle(circle1,circle2){if(circleHasNoSize(circle1)||circleHasNoSize(circle2)){return false;}const dx=circle1.cx-circle2.cx;const dy=circle1.cy-circle2.cy;const sqrDist=dx**2+dy**2;if(sqrDist<=(circle1.r+circle2.r)**2){return true;}return false;}/**
	 * Test if a Circle collide with Polygon. If so, returns true and false otherwise.
	 * Circle muse have a radius greater then 0.
	 * Polygon must contain at least 2 vertices
	 * @private
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @param {object} polygon
	 * @param {Array} polygon.vertices - Array of vertices
	 * @param {object} polygon.vertices.vertex
	 * @param {number} polygon.vertices.vertex.x - x-coordinate
	 * @param {number} polygon.vertices.vertex.y - y-coordinate
	 * @param {Array} polygon.edges - Array of edges
	 * @param {Array} polygon.edges.edge - Array of points
	 * @param {object} polygon.edges.edge.point
	 * @param {number} polygon.edges.edge.point.x - x-coordinate
	 * @param {number} polygon.edges.edge.point.y - y-coordinate
	 * @return {boolean} true if circle collide with polygon
	 */function testCirclePolygon(circle,polygon){// TODO handle polygon that is a straight line, current impl will interrept it is a true, if radius is extended onto any of the edges
	if(toFewEdges(polygon)||circleHasNoSize(circle)){return false;}const center={x:circle.cx,y:circle.cy};if(testPolygonPoint(polygon,center)){return true;}const num=polygon.edges.length;for(let i=0;i<num;i++){const edge=pointsToLine(polygon.edges[i]);if(testCircleLine(circle,edge)){return true;}}return false;}/**
	 * Test if a Polygon contains a Point. If so, returns true and false otherwise.
	 * Polygon must contain at least 2 vertices
	 * @private
	 * @param {object} polygon
	 * @param {Array} polygon.vertices - Array of vertices
	 * @param {object} polygon.vertices.vertex
	 * @param {number} polygon.vertices.vertex.x - x-coordinate
	 * @param {number} polygon.vertices.vertex.y - y-coordinate
	 * @param {Array} polygon.edges - Array of edges
	 * @param {Array} polygon.edges.edge - Array of points
	 * @param {object} polygon.edges.edge.point
	 * @param {number} polygon.edges.edge.point.x - x-coordinate
	 * @param {number} polygon.edges.edge.point.y - y-coordinate
	 * @param {object} point
	 * @param {number} point.x - x-coordinate
	 * @param {number} point.y - y-coordinate
	 * @return {boolean} true if polygon conatins point
	 */function testPolygonPoint(polygon,point){// TODO handle polygon that is a straight line, current impl gives a non-deterministic output, that is depending on number of vertices
	if(toFewEdges(polygon)||!testRectPoint(polygon.boundingRect(),point)){return false;}const{x,y}=point;const vertices=polygon.vertices;let inside;let l;let j;let i;let tx;for(inside=false,i=-1,l=vertices.length,j=l-1;++i<l;j=i){if(vertices[i].x===x&&vertices[i].y===y){// polygon vertice
	return true;}if(vertices[i].y===vertices[j].y&&vertices[i].y===y&&(x-vertices[i].x)*(x-vertices[j].x)<=0){// on horizontal edge of polygon
	return true;}if(vertices[i].y<y&&y<=vertices[j].y||vertices[j].y<y&&y<=vertices[i].y){tx=(vertices[j].x-vertices[i].x)*(y-vertices[i].y)/(vertices[j].y-vertices[i].y)+vertices[i].x;if(x===tx){// on polygon edge
	return true;}if(x<tx){inside=!inside;}}}return inside;}/**
	 * Test if a Polygon collider with a line. If so, returns true and false otherwise.
	 * Polygon must contain at least 3 edges.
	 * Line must have length greater then 0.
	 * @private
	 * @param {object} polygon
	 * @param {Array} polygon.vertices - Array of vertices
	 * @param {object} polygon.vertices.vertex
	 * @param {number} polygon.vertices.vertex.x - x-coordinate
	 * @param {number} polygon.vertices.vertex.y - y-coordinate
	 * @param {Array} polygon.edges - Array of edges
	 * @param {Array} polygon.edges.edge - Array of points
	 * @param {object} polygon.edges.edge.point
	 * @param {number} polygon.edges.edge.point.x - x-coordinate
	 * @param {number} polygon.edges.edge.point.y - y-coordinate
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @return {boolean} true if polygon collider with line
	 */function testPolygonLine(polygon,line){// TODO handle polygon that is a straight line, current impl gives a non-deterministic output, that is depending on number of vertices
	if(toFewEdges(polygon)){return false;}for(let i=0,num=polygon.edges.length;i<num;i++){const edge=pointsToLine(polygon.edges[i]);if(testLineLine(line,edge)){return true;}}const[p1,p2]=lineToPoints(line);return testPolygonPoint(polygon,p1)||testPolygonPoint(polygon,p2);}/**
	 * Test if a Polygon collider with a rectangle. If so, returns true and false otherwise.
	 * Polygon must contain at least 3 edges.
	 * Rectangle must width and height greater then 0.
	 * @private
	 * @param {object} polygon
	 * @param {Array} polygon.vertices - Array of vertices
	 * @param {object} polygon.vertices.vertex
	 * @param {number} polygon.vertices.vertex.x - x-coordinate
	 * @param {number} polygon.vertices.vertex.y - y-coordinate
	 * @param {Array} polygon.edges - Array of edges
	 * @param {Array} polygon.edges.edge - Array of points
	 * @param {object} polygon.edges.edge.point
	 * @param {number} polygon.edges.edge.point.x - x-coordinate
	 * @param {number} polygon.edges.edge.point.y - y-coordinate
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @return {boolean} true if polygon collider with rect
	 */function testPolygonRect(polygon,rect){// TODO handle polygon that is a straight line, current impl gives a non-deterministic output, that is depending on number of vertices
	if(toFewEdges(polygon)){return false;}for(let i=0,num=polygon.edges.length;i<num;i++){const edge=pointsToLine(polygon.edges[i]);if(testRectLine(rect,edge)){return true;}}const[p1,p2,p3,p4]=rectToPoints(rect);return testPolygonPoint(polygon,p1)||testPolygonPoint(polygon,p2)||testPolygonPoint(polygon,p3)||testPolygonPoint(polygon,p4);}/**
	 * Test if a Rectangle collide with another rectangle. If so, returns true and false otherwise.
	 * Both rectangles must have a width and height greather then 0.
	 * @private
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @return {boolean} true if rectangle collide with rectangle
	 */function testRectRect(rect1,rect2){if(rectHasNoSize(rect1)||rectHasNoSize(rect2)){return false;}return rect1.x<=rect2.x+rect2.width&&rect2.x<=rect1.x+rect1.width&&rect1.y<=rect2.y+rect2.height&&rect2.y<=rect1.y+rect1.height;}/**
	 * Test if a rectangle contains  another rectangle. If so, returns true and false otherwise.
	 * Both rectangles must have a width and height greather then 0.
	 * @private
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @return {boolean} true if rectangle collide with rectangle
	 */function testRectContainsRect(rect1,rect2){if(rectHasNoSize(rect1)||rectHasNoSize(rect2)){return false;}const points=[{x:rect2.x,y:rect2.y},{x:rect2.x+rect2.width,y:rect2.y},{x:rect2.x+rect2.width,y:rect2.y+rect2.height},{x:rect2.x,y:rect2.y+rect2.height}];return points.every(p=>testRectPoint(rect1,p));}/**
	 * Test if a Rectangle contains a Point. If so, returns true and false otherwise.
	 * Rectangle must have a width and height greather then 0.
	 * @private
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @param {object} point
	 * @param {number} point.x - x-coordinate
	 * @param {number} point.y - y-coordinate
	 * @return {boolean} true if rectangle contains point
	 */function testRectPoint(rect,point){if(rectHasNoSize(rect)){return false;}return point.x>=rect.x&&point.x<=rect.x+rect.width&&point.y>=rect.y&&point.y<=rect.y+rect.height;}/**
	 * Test if a Rectangle collider with a line. If so, returns true and false otherwise.
	 * Rectangle must have a width and height greather then 0.
	 * Line must have length greater then 0.
	 * @private
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @return {boolean} true if rectangle collide with line
	 */function testRectLine(rect,line){if(lineHasNoLength(line)||rectHasNoSize(rect)){return false;}const[p1,p2]=lineToPoints(line);if(testRectPoint(rect,p1)||testRectPoint(rect,p2)){return true;}const rectEdges=rectToPoints(rect);let num=rectEdges.length;for(let i=0;i<num;i++){const edge=pointsToLine([rectEdges[i],rectEdges[i!==3?i+1:0]]);if(testLineLine(edge,line)){return true;}}return false;}/**
	 * Test if a Line collider with another line. If so, returns true and false otherwise.
	 * Both lines must have length greater then 0.
	 * @private
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @return {boolean} true if line collide with line
	 */function testLineLine(line1,line2){const[p1,p2]=lineToPoints(line1);const[p3,p4]=lineToPoints(line2);const dx1=distanceX(p2,p1);const dy1=distanceY(p2,p1);const dx2=distanceX(p4,p3);const dy2=distanceY(p4,p3);const dx3=distanceX(p1,p3);const dy3=distanceY(p1,p3);let ub=dy2*dx1-dx2*dy1;const uat=dx2*dy3-dy2*dx3;const ubt=dx1*dy3-dy1*dx3;let t1;let t2;if(dx1===0&&dy1===0){// Line segment has no length
	return false;}if(dx2===0&&dy2===0){// Line segment has no length
	return false;}if(ub===0){if(uat===0&&ubt===0){// COINCIDENT;
	if(dx1===0){if(dy1===0){// p1 = p2
	return p1.x===p2.x&&p1.y===p2.y;}t1=distanceY(p3,p1)/dy1;t2=distanceY(p4,p1)/dy1;}else {t1=(p3.x-p1.x)/dx1;t2=(p4.x-p1.x)/dx1;}if(t1<0&&t2<0||t1>1&&t2>1){return false;}return true;}return false;// PARALLEL;
	}const ua=uat/ub;ub=ubt/ub;if(ua>=0.0&&ua<=1.0&&ub>=0.0&&ub<=1.0){return true;}return false;}/**
	 * Test if a Line contains a Point. If so, returns true and false otherwise.
	 * Line must have length greater then 0.
	 * @private
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {object} point
	 * @param {number} point.x - x-coordinate
	 * @param {number} point.y - y-coordinate
	 * @return {boolean} true if line contains point
	 */function testLinePoint(line,point){if(lineHasNoLength(line)){return false;}const[p1,p2]=lineToPoints(line);return isPointOnLine(p1,p2,point);}/**
	 * Test if a polygon intersects another polygon.
	 * Supports convex, concave and self-intersecting polygons (filled area).
	 * @private
	 * @param {object} polygon
	 * @param {object} polygon
	 * @returns {boolean} True if there is an intersection, false otherwise
	 */function testPolygonPolygon(polygon1,polygon2){const rect1=polygon1.boundingRect();const rect2=polygon2.boundingRect();if(!testRectRect(rect1,rect2)){return false;}if(testRectContainsRect(rect1,rect2)){return testPolygonPolygonSubCase(polygon1,polygon2);}return testPolygonPolygonSubCase(polygon2,polygon1);}/**
	 * Test if a geopolygon intersects a polygon.
	 * @private
	 * @param {object} geopolygon
	 * @param {object} polygon
	 * @returns {boolean} True if there is an intersection, false otherwise
	 */function testGeoPolygonPolygon(geopolygon,polygon){const rect1=geopolygon.boundingRect();const rect2=polygon.boundingRect();if(!testRectRect(rect1,rect2)){return false;}if(testRectContainsRect(rect2,rect1)){return testGeoPolygonPolygonCase2(geopolygon,polygon);}return testGeoPolygonPolygonCase1(geopolygon,polygon);}/**
	 * Test if a geopolygon intersects another geopolygon.
	 * @private
	 * @param {object} geopolygon
	 * @param {object} geopolygon
	 * @returns {boolean} True if there is an intersection, false otherwise
	 */function testGeoPolygonGeoPolygon(geopolygon1,geopolygon2){const rect1=geopolygon1.boundingRect();const rect2=geopolygon2.boundingRect();if(!testRectRect(rect1,rect2)){return false;}if(testRectContainsRect(rect2,rect1)){return testGeoPolygonGeoPolygonSubCase(geopolygon2,geopolygon1);}return testGeoPolygonGeoPolygonSubCase(geopolygon1,geopolygon2);}/**
	 * Test if a Circle collide with GeoPolygon. If so, returns true and false otherwise.
	 * Circle muse have a radius greater then 0.
	 * @private
	 * @param {object} circle
	 * @param {number} circle.cx - center x-coordinate
	 * @param {number} circle.cy - center y-coordinate
	 * @param {number} circle.r - circle radius
	 * @param {object} geopolygon
	 * @param {Array} geopolygon.polygons - Array of polygons
	 * @return {boolean} true if circle collide with polygon
	 */function testCircleGeoPolygon(circle,geopolygon){if(circleHasNoSize(circle)){return false;}const center={x:circle.cx,y:circle.cy};if(testGeoPolygonPoint(geopolygon,center)){return true;}const{numPolygons,polygons}=geopolygon;for(let n=0;n<numPolygons;n++){const polygon=polygons[n];const num=polygon.edges.length;for(let i=0;i<num;i++){const edge=pointsToLine(polygon.edges[i]);if(testCircleLine(circle,edge)){return true;}}}return false;}/**
	 * Test if a GeoPolygon contains a Point. If so, returns true and false otherwise.
	 * @private
	 * @param {object} geopolygon
	 * @param {Array} geopolygon.vertices - Array of of arrays of vertices
	 * @param {object} point
	 * @param {number} point.x - x-coordinate
	 * @param {number} point.y - y-coordinate
	 * @return {boolean} true if polygon conatins point
	 */function testGeoPolygonPoint(geopolygon,point){if(!testRectPoint(geopolygon.boundingRect(),point)){return false;}const{x,y}=point;const numPolygons=geopolygon.numPolygons;let inside=false;let vertices;let n;let l;let j;let i;let tx;for(n=0;n<numPolygons;n++){vertices=geopolygon.vertices[n];for(i=-1,l=vertices.length,j=l-1;++i<l;j=i){if(vertices[i].x===x&&vertices[i].y===y){// polygon vertice
	return true;}if(vertices[i].y===vertices[j].y&&vertices[i].y===y&&(x-vertices[i].x)*(x-vertices[j].x)<=0){// on horizontal edge of polygon
	return true;}if(vertices[i].y<y&&y<=vertices[j].y||vertices[j].y<y&&y<=vertices[i].y){tx=(vertices[j].x-vertices[i].x)*(y-vertices[i].y)/(vertices[j].y-vertices[i].y)+vertices[i].x;if(x===tx){// on polygon edge
	return true;}if(x<tx){inside=!inside;}}}}return inside;}/**
	 * Test if a GeoPolygon collider with a line. If so, returns true and false otherwise.
	 * Line must have length greater then 0.
	 * @private
	 * @param {object} geopolygon
	 * @param {Array} geopolygon.polygons - Array of polygons
	 * @param {object} line
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @param {number} line.x1 - x-coordinate
	 * @param {number} line.y1 - y-coordinate
	 * @return {boolean} true if polygon collider with line
	 */function testGeoPolygonLine(geopolygon,line){const[p1,p2]=lineToPoints(line);if(testGeoPolygonPoint(geopolygon,p1)||testGeoPolygonPoint(geopolygon,p2)){return true;}const{numPolygons,polygons}=geopolygon;for(let n=0;n<numPolygons;n++){const polygon=polygons[n];for(let i=0,num=polygon.edges.length;i<num;i++){const edge=pointsToLine(polygon.edges[i]);if(testLineLine(line,edge)){return true;}}}return false;}/**
	 * Test if a GeoPolygon collider with a rectangle. If so, returns true and false otherwise.
	 * Rectangle must have width and height greater than 0.
	 * @private
	 * @param {object} geopolygon
	 * @param {Array} geopolygon.polygons - Array of polygons
	 * @param {object} rect
	 * @param {number} rect.x - x-coordinate
	 * @param {number} rect.y - y-coordinate
	 * @param {number} rect.width - width
	 * @param {number} rect.height - height
	 * @return {boolean} true if polygon collider with rect
	 */function testGeoPolygonRect(geopolygon,rect){const[p1,p2,p3,p4]=rectToPoints(rect);if(testGeoPolygonPoint(geopolygon,p1)||testGeoPolygonPoint(geopolygon,p2)||testGeoPolygonPoint(geopolygon,p3)||testGeoPolygonPoint(geopolygon,p4)){return true;}const{numPolygons,polygons}=geopolygon;for(let n=0;n<numPolygons;n++){const polygon=polygons[n];for(let i=0,num=polygon.edges.length;i<num;i++){const edge=pointsToLine(polygon.edges[i]);if(testRectLine(rect,edge)){return true;}}}return false;}const VARIABLE_RX=/^\$/;const EXTEND='@extend';function throwCyclical(s){throw new Error("Cyclical reference for \"".concat(s,"\""));}function res(style,references,path){if(typeof style==='string'){let value=references[style];if(path.indexOf(style)!==-1){throwCyclical(style);}if(VARIABLE_RX.test(value)){path.push(style);return res(value,references,path);}return value;}let computed=style;const refs=extend$1$1(true,{},references,style);const s={};if(style[EXTEND]){const extendFrom=style[EXTEND];if(path.indexOf(extendFrom)!==-1){throwCyclical(extendFrom);}let pext=path.slice();pext.push(extendFrom);computed=extend$1$1(true,{},res(refs[extendFrom],references,pext),style);}Object.keys(computed).forEach(key=>{let p=path.slice();if(key===EXTEND||VARIABLE_RX.test(key)){return;}s[key]=computed[key];let value=s[key];if(VARIABLE_RX.test(value)&&value in refs){if(path.indexOf(value)!==-1){throwCyclical(value);}p.push(value);value=refs[value];if(typeof value==='object'){s[key]=res(value,refs,p);}else if(VARIABLE_RX.test(value)&&value in refs){s[key]=res(value,refs,p);}else {s[key]=value;}}else if(typeof value==='object'){s[key]=res(value,refs,p);}});return s;}/**
	 * Resolve style references
	 * @private
	 * @param {style-object} style
	 * @param {style-object} references
	 * @returns {object} The resolved style
	 * @example
	 * resolve({
	 *   label: '$label--big'
	 * }, {
	 *   '$size--m': '12px',
	 *   '$label--big': {
	 *     fontFamily: 'Arial',
	 *     fontSize: '$size--m'
	 *   }
	 * }); // { label: { fontFamily: 'Arial', fontSize: '12px' } }
	 */function resolve$1(style,references){return res(style,references,[]);}function themeFn(){let style=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let palettes=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];let pals={};let internalStyle=style;const setPalettes=p=>{p.forEach(palette=>{const pal=Array.isArray(palette.colors[0])?palette.colors:[palette.colors];pals[palette.key]={colors:pal,sizes:pal.map(colors=>colors?colors.length:0)};});};const getPalette=(key,num)=>{const palette=pals[key];if(!palette){return [];}const sizes=palette.sizes;// find the first color set containing at least 'num' colors
	for(let i=0;i<sizes.length;i++){if(num<=sizes[i]){return palette.colors[i];}}return palette.colors[sizes.length-1];};/**
	   * Theme API
	   * @private
	   * @experimental
	   */const theme={/**
	     * Get an array of colors
	     * @param {string} name - Name of the color palette
	     * @param {number} [num] - The minimum number of colors to get from the palette
	     */palette:(name,num)=>getPalette(name,num),setPalettes,/**
	     * Resolve style references
	     * @param {style-object} s - Object containing style
	     */style:s=>resolve$1(s,internalStyle),/**
	     * Set custom style
	     * @param {style-object} s - Object containing style
	     */setStyle:s=>{internalStyle=extend$1$1({},style,s);}};setPalettes(palettes);return theme;}function roundRect(rect){rect.x=Math.floor(rect.x);rect.y=Math.floor(rect.y);rect.width=Math.floor(rect.width);rect.height=Math.floor(rect.height);}function resolveContainerRects(rect,settings){const containerRect={x:0,y:0,width:0,height:0};const logicalContainerRect={x:0,y:0,width:0,height:0};// Check input object for size
	containerRect.width=rect.width||0;containerRect.height=rect.height||0;if(typeof settings.size!=='undefined'){containerRect.width=isNaN(settings.size.width)?containerRect.width:settings.size.width;containerRect.height=isNaN(settings.size.height)?containerRect.height:settings.size.height;}if(typeof settings.logicalSize!=='undefined'){logicalContainerRect.width=isNaN(settings.logicalSize.width)?containerRect.width:settings.logicalSize.width;logicalContainerRect.height=isNaN(settings.logicalSize.height)?containerRect.height:settings.logicalSize.height;logicalContainerRect.align=isNaN(settings.logicalSize.align)?0.5:Math.min(Math.max(settings.logicalSize.align,0),1);logicalContainerRect.preserveAspectRatio=settings.logicalSize.preserveAspectRatio;}else {logicalContainerRect.width=containerRect.width;logicalContainerRect.height=containerRect.height;logicalContainerRect.preserveAspectRatio=false;}roundRect(logicalContainerRect);roundRect(containerRect);return {logicalContainerRect,containerRect};}function resolveSettings$1(s){const settings={center:{minWidthRatio:0.5,minHeightRatio:0.5,minWidth:0,minHeight:0}};extend$1$1(true,settings,s);settings.center.minWidthRatio=Math.min(Math.max(settings.center.minWidthRatio,0),1);// Only accept value between 0-1
	settings.center.minHeightRatio=Math.min(Math.max(settings.center.minHeightRatio,0),1);// Only accept value between 0-1
	settings.center.minWidth=Math.max(settings.center.minWidth,0);// Consider <= 0 to be falsy and fallback to ratio
	settings.center.minHeight=Math.max(settings.center.minHeight,0);// Consider <= 0 to be falsy and fallback to ratio
	return settings;}function createRect(x,y,width,height,margin){return {x:isNaN(x)?0:x,y:isNaN(x)?0:y,width:isNaN(x)?0:width,height:isNaN(x)?0:height,margin:isNaN(margin)?0:margin};}function cacheSize(c,reducedRect,layoutRect){if(typeof c.cachedSize==='undefined'){const dock=c.config.dock();let size=c.comp.preferredSize({inner:reducedRect,outer:layoutRect,dock});// backwards compatibility
	if(!isNaN(size)){size={width:size,height:size};}else if(size&&!isNaN(size.size)){size.width=size.size;size.height=size.size;}let relevantSize;if(dock==='top'||dock==='bottom'){relevantSize=size.height;}else if(dock==='right'||dock==='left'){relevantSize=size.width;}else {relevantSize=Math.max(size.width,size.height);}c.cachedSize=Math.ceil(relevantSize);c.edgeBleed=size.edgeBleed||0;}return c.cachedSize;}function validateReduceRect(rect,reducedRect,settings){// Absolute value for width/height should have predence over relative value
	const minReduceWidth=Math.min(settings.center.minWidth,rect.width)||Math.max(rect.width*settings.center.minWidthRatio,1);const minReduceHeight=Math.min(settings.center.minHeight,rect.height)||Math.max(rect.height*settings.center.minHeightRatio,1);return reducedRect.width>=minReduceWidth&&reducedRect.height>=minReduceHeight;}function reduceDocRect(reducedRect,c){switch(c.config.dock()){case 'top':reducedRect.y+=c.cachedSize;reducedRect.height-=c.cachedSize;break;case 'bottom':reducedRect.height-=c.cachedSize;break;case 'left':reducedRect.x+=c.cachedSize;reducedRect.width-=c.cachedSize;break;case 'right':reducedRect.width-=c.cachedSize;break;}}function addEdgeBleed(currentEdgeBleed,c){const edgeBleed=c.edgeBleed;if(!edgeBleed){return;}currentEdgeBleed.left=Math.max(currentEdgeBleed.left,edgeBleed.left||0);currentEdgeBleed.right=Math.max(currentEdgeBleed.right,edgeBleed.right||0);currentEdgeBleed.top=Math.max(currentEdgeBleed.top,edgeBleed.top||0);currentEdgeBleed.bottom=Math.max(currentEdgeBleed.bottom,edgeBleed.bottom||0);}function reduceEdgeBleed(layoutRect,reducedRect,edgeBleed){if(reducedRect.x<edgeBleed.left){reducedRect.width-=edgeBleed.left-reducedRect.x;reducedRect.x=edgeBleed.left;}const reducedRectRightBoundary=layoutRect.width-(reducedRect.x+reducedRect.width);if(reducedRectRightBoundary<edgeBleed.right){reducedRect.width-=edgeBleed.right-reducedRectRightBoundary;}if(reducedRect.y<edgeBleed.top){reducedRect.height-=edgeBleed.top-reducedRect.y;reducedRect.y=edgeBleed.top;}const reducedRectBottomBoundary=layoutRect.height-(reducedRect.y+reducedRect.height);if(reducedRectBottomBoundary<edgeBleed.bottom){reducedRect.height-=edgeBleed.bottom-reducedRectBottomBoundary;}}function reduceSingleLayoutRect(layoutRect,reducedRect,edgeBleed,c,settings){const newReduceRect=extend$1$1({},reducedRect);const newEdgeBleed=extend$1$1({},edgeBleed);reduceDocRect(newReduceRect,c);addEdgeBleed(newEdgeBleed,c);reduceEdgeBleed(layoutRect,newReduceRect,newEdgeBleed);const isValid=validateReduceRect(layoutRect,newReduceRect,settings);if(!isValid){return false;}reduceDocRect(reducedRect,c);addEdgeBleed(edgeBleed,c);return true;}/**
	 * Updates the visible and hidden components based on components that are docked to other components.
	 * For example, assume a component called myRect:
	 * {
	 *  key: 'myRect',
	 *  type: 'rect',
	 *  dock: 'bottom'
	 * }
	 * and a component called myLine:
	 * {
	 *  key: 'myLine',
	 *  type: 'line',
	 *  dock: '@myRect'
	 * }
	 * if the layout engine decides to hide myRect, then myLine should be hidden as well.
	 * @param {Array} visible - Components to be decided if they should be hidden or not.
	 * @param {Array} hidden - Components that are already hidden.
	 * @returns {Object} containing the new visible components and additional components to be hidden.
	 * @ignore
	 */function filterReferencedDocks(visible,hidden){if(hidden.length===0){return;}for(let i=0;i<visible.length;++i){let v=visible[i];if(v.referencedDocks.length){const isAllHidden=v.referencedDocks.every(refDock=>hidden.some(h=>h.key===refDock));if(isAllHidden){hidden.push(visible.splice(i,1)[0]);}}}}function reduceLayoutRect(_ref){let{layoutRect,visible,hidden,settings}=_ref;const reducedRect=createRect(layoutRect.x,layoutRect.y,layoutRect.width,layoutRect.height);const edgeBleed={left:0,right:0,top:0,bottom:0};const sortedComponents=visible.slice();sortedComponents.sort((a,b)=>a.config.prioOrder()-b.config.prioOrder());// lower prioOrder will have higher prio
	for(let i=0;i<sortedComponents.length;++i){const c=sortedComponents[i];cacheSize(c,reducedRect,layoutRect);if(!reduceSingleLayoutRect(layoutRect,reducedRect,edgeBleed,c,settings)){hidden.push(sortedComponents.splice(i,1)[0]);--i;}}filterReferencedDocks(visible,hidden);const filteredUnsortedComps=visible.filter(c=>sortedComponents.indexOf(c)!==-1);visible.length=0;visible.push(...filteredUnsortedComps);reduceEdgeBleed(layoutRect,reducedRect,edgeBleed);return reducedRect;}function computeRect(rect){return {x:rect.margin.left+rect.x*rect.scaleRatio.x,y:rect.margin.top+rect.y*rect.scaleRatio.y,width:rect.width*rect.scaleRatio.x,height:rect.height*rect.scaleRatio.y};}function appendScaleRatio(rect,outerRect,layoutRect,containerRect){const scaleRatio={x:containerRect.width/layoutRect.width,y:containerRect.height/layoutRect.height};const margin={left:0,top:0};if(layoutRect.preserveAspectRatio){const xLessThenY=scaleRatio.x<scaleRatio.y;// To preserve the aspect ratio, take the smallest ratio and apply in both directions to "meet" the size of the container
	const minRatio=Math.min(scaleRatio.x,scaleRatio.y);scaleRatio.x=minRatio;scaleRatio.y=minRatio;const area=xLessThenY?'height':'width';const spread=(containerRect[area]-layoutRect[area]*scaleRatio.x)*layoutRect.align;margin.left=xLessThenY?0:spread;margin.top=xLessThenY?spread:0;}rect.scaleRatio=scaleRatio;rect.margin=margin;outerRect.scaleRatio=scaleRatio;outerRect.margin=margin;layoutRect.scaleRatio=scaleRatio;layoutRect.margin=margin;}function boundingBox(rects){const points=[].concat(...rects.map(rectToPoints));return pointsToRect(points);}function positionComponents(_ref2){let{visible,layoutRect,reducedRect,containerRect,translation}=_ref2;const vRect=createRect(reducedRect.x,reducedRect.y,reducedRect.width,reducedRect.height);const hRect=createRect(reducedRect.x,reducedRect.y,reducedRect.width,reducedRect.height);const referencedComponents={};const referenceArray=visible.slice();const elementOrder=referenceArray.slice().sort((a,b)=>a.config.displayOrder()-b.config.displayOrder());visible.sort((a,b)=>{if(a.referencedDocks.length>0&&b.referencedDocks.length>0){return 0;}if(b.referencedDocks.length>0){return  -1;}if(a.referencedDocks.length>0){return 1;}const diff=a.config.displayOrder()-b.config.displayOrder();if(diff===0){return referenceArray.indexOf(a)-referenceArray.indexOf(b);}return diff;}).forEach(c=>{let outerRect={};let rect={};const d=c.config.dock();switch(d){case 'top':outerRect.height=rect.height=c.cachedSize;outerRect.width=layoutRect.width;rect.width=vRect.width;outerRect.x=layoutRect.x;rect.x=vRect.x;outerRect.y=rect.y=vRect.y-c.cachedSize;vRect.y-=c.cachedSize;vRect.height+=c.cachedSize;break;case 'bottom':outerRect.x=layoutRect.x;rect.x=vRect.x;outerRect.y=rect.y=vRect.y+vRect.height;outerRect.width=layoutRect.width;rect.width=vRect.width;outerRect.height=rect.height=c.cachedSize;vRect.height+=c.cachedSize;break;case 'left':outerRect.x=rect.x=hRect.x-c.cachedSize;outerRect.y=layoutRect.y;rect.y=hRect.y;outerRect.width=rect.width=c.cachedSize;outerRect.height=layoutRect.height;rect.height=hRect.height;hRect.x-=c.cachedSize;hRect.width+=c.cachedSize;break;case 'right':outerRect.x=rect.x=hRect.x+hRect.width;outerRect.y=layoutRect.y;rect.y=hRect.y;outerRect.width=rect.width=c.cachedSize;outerRect.height=layoutRect.height;rect.height=hRect.height;hRect.width+=c.cachedSize;break;case 'center':outerRect.x=rect.x=reducedRect.x;outerRect.y=rect.y=reducedRect.y;outerRect.width=rect.width=reducedRect.width;outerRect.height=rect.height=reducedRect.height;break;default:if(c.referencedDocks.length>0){const refs=c.referencedDocks.map(ref=>referencedComponents[ref]).filter(ref=>!!ref);if(refs.length>0){outerRect=boundingBox(refs.map(ref=>ref.outerRect));rect=boundingBox(refs.map(ref=>ref.r));}}break;}if(c.key){referencedComponents[c.key]={// store the size of this component
	r:rect,outerRect};}appendScaleRatio(rect,outerRect,layoutRect,containerRect);rect.edgeBleed=c.edgeBleed;rect.computed=computeRect(rect);outerRect.edgeBleed=c.edgeBleed;outerRect.computed=computeRect(outerRect);rect.x+=translation.x;rect.y+=translation.y;outerRect.x+=translation.x;outerRect.y+=translation.y;c.comp.resize(rect,outerRect);c.cachedSize=undefined;c.edgeBleed=undefined;});return elementOrder;}function checkShowSettings(strategySettings,dockSettings,logicalContainerRect){const layoutModes=strategySettings.layoutModes||{};const minimumLayoutMode=dockSettings.minimumLayoutMode();let show=dockSettings.show();if(show&&typeof minimumLayoutMode==='object'){show=layoutModes[minimumLayoutMode.width]&&layoutModes[minimumLayoutMode.height]&&logicalContainerRect.width>=layoutModes[minimumLayoutMode.width].width&&logicalContainerRect.height>=layoutModes[minimumLayoutMode.height].height;}else if(show&&minimumLayoutMode!==undefined){show=layoutModes[minimumLayoutMode]&&logicalContainerRect.width>=layoutModes[minimumLayoutMode].width&&logicalContainerRect.height>=layoutModes[minimumLayoutMode].height;}return show;}function validateComponent(component){if(!component.resize||typeof component.resize!=='function'){throw new Error('Component is missing resize function');}if(!component.dockConfig&&!component.preferredSize){throw new Error('Component is missing preferredSize function');}}function filterComponents(components,settings,rect){const visible=[];const hidden=[];// check show settings
	for(let i=0;i<components.length;++i){const comp=components[i];validateComponent(comp);// backwards compatibility
	let config=comp.dockConfig;const key=comp.key;const d=config.dock();const referencedDocks=/@/.test(d)?d.split(',').map(s=>s.replace(/^\s*@/,'')):[];if(checkShowSettings(settings,config,rect)){visible.push({comp,key,config,referencedDocks});}else {hidden.push({comp,key,config,referencedDocks});}}return [visible,hidden];}/**
	 * Dock layout settings
	 * @typedef {object} DockLayoutSettings
	 * @property {object} [logicalSize] - Logical size
	 * @property {number} [logicalSize.width] - Width in pixels
	 * @property {number} [logicalSize.height] - Height in pixels
	 * @property {boolean} [logicalSize.preserveAspectRatio=false] - If true, takes the smallest ratio of width/height between logical and physical size ( physical / logical )
	 * @property {number} [logicalSize.align=0.5] - Normalized value between 0-1. Defines how the space around the scaled axis is spread in the container, with 0.5 meaning the spread is equal on both sides. Only applicable if preserveAspectRatio is set to true
	 * @property {object} [center] - Define how much space the center dock area requires
	 * @property {number} [center.minWidthRatio=0.5] - Value between 0 and 1
	 * @property {number} [center.minHeightRatio=0.5] - Value between 0 and 1
	 * @property {number} [center.minWidth] - Width in pixels
	 * @property {number} [center.minHeight] - Height in pixels
	 * @property {object<string, DockLayoutSettings~LayoutMode>} [layoutModes] Dictionary with named sizes
	 * @property {object} [size] - Size is equal to that of the container (element) of the chart by default. It's possible to overwrite it by explicitly setting width or height
	 * @property {number} [size.width] - Width in pixels
	 * @property {number} [size.height] - Height in pixels
	 *//**
	 * @typedef {object} DockLayoutSettings~LayoutMode
	 * @property {number} width
	 * @property {number} height
	 */function dockLayout(initialSettings){let settings=resolveSettings$1(initialSettings);const docker={};docker.layout=function layout(rect){let components=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];if(!rect||isNaN(rect.x)||isNaN(rect.y)||isNaN(rect.width)||isNaN(rect.height)){throw new Error('Invalid rect');}if(!components.length){return {visible:[],hidden:[],ordered:[]};}const{logicalContainerRect,containerRect}=resolveContainerRects(rect,settings);const[visible,hidden]=filterComponents(components,settings,logicalContainerRect);const reducedRect=reduceLayoutRect({layoutRect:logicalContainerRect,visible,hidden,settings});const translation={x:rect.x,y:rect.y};const ordered=positionComponents({visible,layoutRect:logicalContainerRect,reducedRect,containerRect,translation});hidden.forEach(c=>{c.comp.visible=false;// set empty rects on hidden components
	const r=createRect();c.comp.resize(r,r);});return {visible:visible.map(v=>v.comp),hidden:hidden.map(h=>h.comp),ordered:ordered.map(h=>h.comp)};};docker.settings=function settingsFn(s){settings=resolveSettings$1(s);};return docker;}const findComponentByKeyInList=(list,key)=>{for(let i=0;i<list.length;i++){const currComp=list[i];if(currComp.hasKey&&currComp.key===key){return list[i];}}return null;};const wrapChildren=children=>children===null||children===void 0?void 0:children.map(c=>{const dockConfig=c.instance.dockConfig();return {preferredSize(opts){return dockConfig.computePreferredSize(_objectSpread2$1(_objectSpread2$1({},opts),{},{children:wrapChildren(c.children)}));}};});const hideAll=(rect,components)=>({visible:[],hidden:components,ordered:[]});const customLayout=fn=>(rect,components)=>{var _fn;const vcomponents=components.map((c,i)=>{const dockConfig=c.instance.dockConfig();return {index:i,key:c.key,dockConfig,resize:c.instance.resize,preferredSize(opts){return dockConfig.computePreferredSize(_objectSpread2$1(_objectSpread2$1({},opts),{},{children:wrapChildren(c.children)}));}};});const mapBack=c=>components[c.index];const{visible=vcomponents,hidden=[],ordered=visible}=(_fn=fn(rect,vcomponents))!==null&&_fn!==void 0?_fn:{};return {visible:visible.map(mapBack),hidden:hidden.map(mapBack),ordered:ordered.map(mapBack)};};const normalLayout=layoutSettings=>{const dockLayout$1=dockLayout(layoutSettings);return customLayout((rect,vcomponents)=>dockLayout$1.layout(rect,vcomponents));};const getLayoutFn=strategy=>typeof strategy==='function'?customLayout(strategy):normalLayout(strategy);function collectionFn(_ref){let{createComponent}=_ref;const instance={};let allComponents=[];let topComponents=[];const createComp=compSettings=>{const component=createComponent(compSettings);if(component){allComponents.push(component);if(compSettings.components){component.children=compSettings.components.map(childSettings=>createComp(childSettings)).filter(c=>!!c);}}return component;};const removeFromAllComponents=component=>{const index=allComponents.indexOf(component);if(index!==-1){allComponents.splice(index,1);}};const removeDeleted=(compList,settingsList)=>{for(let i=compList.length-1;i>=0;i--){const currComp=compList[i];// TODO warn when there is no key
	const currSettings=settingsList.find(c=>currComp.hasKey&&currComp.key===c.key);if(!currSettings){// Component is removed
	compList.splice(i,1);removeFromAllComponents(currComp);if(currComp.children){removeDeleted(currComp.children,[]);}currComp.instance.destroy();}else if(currComp.children&&currSettings.components){removeDeleted(currComp.children,currSettings.components);}}};const addAndUpdate=_ref2=>{let{compList,data,excludeFromUpdate,formatters,scales,settingsList}=_ref2;return(// Let the "components" array determine order of components
	settingsList.map(comp=>{const component=findComponentByKeyInList(compList,comp.key);// Component should not be updated
	if(excludeFromUpdate.indexOf(comp.key)>-1){// TODO: decide if to skip children
	delete component.updateWith;return component;}if(!component){// Component is added
	return createComp(comp);}if(comp.rendererSettings&&typeof component.instance.renderer().settings==='function'){component.instance.renderer().settings(comp.rendererSettings);}// Only apply transform, no need for an update
	if(comp.rendererSettings&&typeof comp.rendererSettings.transform==='function'&&comp.rendererSettings.transform()){component.applyTransform=true;return component;}// Component is (potentially) updated
	component.updateWith={formatters,scales,data,settings:comp};if(comp.components){component.children=addAndUpdate({compList:component.children||[],data,excludeFromUpdate,formatters,scales,settingsList:comp.components});}return component;}).filter(c=>!!c));};const recLayout=_ref3=>{let{components,hidden,layoutFn,ordered,rect,visible}=_ref3;const{visible:v,hidden:h,ordered:o}=layoutFn(rect,components);visible.push(...v);hidden.push(...h);ordered.push(...o);v.forEach(c=>{if(c.children){var _c$settings$strategy,_c$settings;const lFn=getLayoutFn((_c$settings$strategy=(_c$settings=c.settings)===null||_c$settings===void 0?void 0:_c$settings.strategy)!==null&&_c$settings$strategy!==void 0?_c$settings$strategy:{});recLayout({components:c.children,hidden,layoutFn:lFn,ordered,rect:c.instance.getRect(),visible});}});h.forEach(c=>{if(c.children){recLayout({components:c.children,hidden,layoutFn:hideAll,ordered,rect:null,visible});}});};instance.destroy=()=>{allComponents.forEach(comp=>comp.instance.destroy());allComponents=[];topComponents=[];};instance.findComponentByKey=key=>findComponentByKeyInList(allComponents,key);instance.forEach=fn=>{allComponents.forEach(fn);};instance.layout=_ref4=>{let{layoutSettings,rect}=_ref4;const visible=[];const hidden=[];const ordered=[];const layoutFn=getLayoutFn(layoutSettings);recLayout({components:topComponents,hidden,layoutFn,ordered,rect,visible});return {visible,hidden,ordered};};instance.set=_ref5=>{let{components}=_ref5;topComponents=components.map(compSettings=>createComp(compSettings)).filter(c=>!!c);};instance.update=_ref6=>{let{components,data,excludeFromUpdate,formatters,scales}=_ref6;// remove deleted
	removeDeleted(topComponents,components);// Update and add new
	topComponents=addAndUpdate({compList:topComponents,data,excludeFromUpdate,formatters,scales,settingsList:components});};return instance;}/**
	 * @callback customLayoutFunction
	 * @param {Rect} rect
	 * @param {object[]} components
	 * @param {string} components[].key
	 * @param {object} components[].dockConfig
	 * @param {function} components[].resize
	 * @param {function} components[].preferredSize
	 *//**
	 * Called when the chart has been created
	 * @callback ChartDefinition~created
	 *//**
	 * Called before the chart has been mounted
	 * @callback ChartDefinition~beforeMount
	 *//**
	 * Called after the chart has been mounted
	 * @callback ChartDefinition~mounted
	 * @param {HTMLElement} element The element the chart been mounted to
	 *//**
	 * Called before the chart has been rendered
	 * @callback ChartDefinition~beforeRender
	 *//**
	 * Called before the chart has been updated
	 * @callback ChartDefinition~beforeUpdate
	 *//**
	 * Called after the chart has been updated
	 * @callback ChartDefinition~updated
	 *//**
	 * Called before the chart has been destroyed
	 * @callback ChartDefinition~beforeDestroy
	 *//**
	 * Called after the chart has been destroyed
	 * @callback ChartDefinition~destroyed
	 *//**
	 * @typedef {ComponentAxis | ComponentBox | ComponentBrushArea | ComponentBrushAreaDir | ComponentBrushLasso | ComponentBrushRange | ComponentContainer | ComponentGridLine | ComponentLabels | ComponentLegendCat | ComponentLegendSeq | ComponentLine | ComponentPie | ComponentPoint | ComponentRefLine | ComponentText | ComponentTooltip} ComponentTypes
	 *//**
	 * @typedef {object} ChartSettings
	 * @property {ComponentTypes[]} [components] Components
	 * @property {object.<string, ScaleDefinition>} [scales] Dictionary with scale definitions
	 * @property {object.<string, FormatterDefinition>} [formatters] Dictionary with formatter definitions
	 * @property {DockLayoutSettings} [strategy] Dock layout strategy
	 * @property {InteractionSettings[]} [interactions] Interaction handlers
	 * @property {CollectionSettings[]} [collections] Collections
	 *//**
	 * Generic settings available to all components
	 * @interface ComponentSettings
	 * @property {string} type - Component type (ex: axis, point, ...)
	 * @property {function} [preferredSize] - Function returning the preferred size
	 * @property {function} [created] Called when the component has been created
	 * @property {function} [beforeMount] Called before the component has been mounted
	 * @property {function} [mounted] Called after the component has been mounted
	 * @property {function} [beforeUpdate] Called before the component has been updated
	 * @property {function} [updated] Called after the component has been updated
	 * @property {function} [beforeRender] Called before the component has been rendered
	 * @property {function} [beforeDestroy] Called before the component has been destroyed
	 * @property {function} [destroyed] Called after the component has been destroyed
	 * @property {object} [brush] Brush settings
	 * @property {BrushTriggerSettings[]} [brush.trigger] Trigger settings
	 * @property {BrushConsumeSettings[]} [brush.consume] Consume settings
	 * @property {function} [brush.sortNodes] Sorting function for nodes. Should return sorted nodes.
	 * @property {object} [layout] Layout settings
	 * @property {number} [layout.displayOrder = 0]
	 * @property {number} [layout.prioOrder = 0]
	 * @property {string | {width: string, height: string}} [layout.minimumLayoutMode] Refer to layout sizes defined by layoutModes in `strategy`
	 * @property {string} [layout.dock] left, right, top or bottom
	 * @property {boolean} [show = true] If the component should be rendered
	 * @property {string} [scale] Named scale. Will be provided to the component if it asks for it.
	 * @property {string} [formatter] Named formatter. Fallback to create formatter from scale. Will be provided to the component if it asks for it.
	 * @property {ComponentSettings[]} [components] Optional list of child components
	 * @property {DockLayoutSettings|customLayoutFunction} [strategy] Layout strategy used for child components.
	 * @property {DataExtraction|DataFieldExtraction} [data] Extracted data that should be available to the component
	 * @property {RendererSettings} [rendererSettings] Settings for the renderer used to render the component
	 * @property {string} [key] Component key
	 */// mark strategy as experimental
	/**
	 * @type {DockLayoutSettings|customLayoutFunction}
	 * @name strategy
	 * @memberof ComponentSettings
	 * @experimental
	 */// mark components as experimental
	/**
	 * @type {ComponentSettings[]}
	 * @name components
	 * @memberof ComponentSettings
	 * @experimental
	 *//**
	 * @typedef {object} BrushTriggerSettings
	 * @property {string} [on] Type of interaction to trigger brush on
	 * @property {string} [action] Type of interaction to respond with
	 * @property {string[]} [contexts] Name of the brushing contexts to affect
	 * @property {string[]} [data] The mapped data properties to add to the brush
	 * @property {string} [propagation] Control the event propagation when multiple shapes are tapped. Disabled by default
	 * @property {string} [globalPropagation] Control the event propagation between components. Disabled by default
	 * @property {number} [touchRadius] Extend contact area for touch events. Disabled by default
	 * @property {number} [mouseRadius] Extend contact area for regular mouse events. Disabled by default
	 * @example
	 * {
	 *    on: 'tap',
	 *    action: 'toggle',
	 *    contexts: ['selection', 'tooltip'],
	 *    data: ['x'],
	 *    propagation: 'stop', // 'stop' => prevent trigger from propagating further than the first shape
	 *    globalPropagation: 'stop', // 'stop' => prevent trigger of same type to be triggered on other components
	 *    touchRadius: 24,
	 *    mouseRadius: 10
	 *  }
	 *//**
	 * @typedef {object} BrushConsumeSettings
	 * @property {string} [context] Name of the brush context to observe
	 * @property {string[]} [data] The mapped data properties to observe
	 * @property {string} [mode] Data properties operator: and, or, xor.
	 * @property {function} [filter] Filtering function
	 * @property {object} [style] The style to apply to the shapes of the component
	 * @property {object.<string, any>} [style.active] The style of active data points
	 * @property {object.<string, any>} [style.inactive] The style of inactive data points
	 * @example
	 * {
	 *    context: 'selection',
	 *    data: ['x'],
	 *    filter: (shape) => shape.type === 'circle',
	 *    style: {
	 *      active: {
	 *        fill: 'red',
	 *        stroke: '#333',
	 *        strokeWidth: (shape) => shape.strokeWidth * 2,
	 *      },
	 *      inactive: {},
	 *    },
	 * }
	 *//**
	 * @typedef {object} RendererSettings
	 * @property {RendererSettings~TransformFunction} [transform] Setting for applying transform without re-rendering the whole component completely.
	 * @property {RendererSettings~CanvasBufferSize} [canvasBufferSize] Specifies the size of buffer canvas (used together with transform setting).
	 * @property {RendererSettings~Progressive} [progressive] Setting for applying progressive rendering to a canvas renderer
	 * @property {boolean} [disableScreenReader = false] Setting to disable the screen reader for the component. If set to true, screen reader support will be disabled. This setting is not relevant when using the canvas renderer.
	 * @experimental
	 *//**
	 * Should return a transform object if transformation should be applied, otherwise undefined or a falsy value.
	 * Transforms can be applied with the canvas, svg and dom renderer.
	 * Transform is applied when running chart.update, see example.
	 * !Important: When a transform is applied to a component, the underlaying node representations are not updated with the new positions/sizes, which
	 * can cause problems for operations that relies on the positioning of the shapes/nodes (such as tooltips, selections etc). An extra chart update
	 * without a transform is therefore needed to make sure the node position information is in sync with the visual representation again.
	 * @typedef {function} RendererSettings~TransformFunction
	 * @returns {TransformObject}
	 * @experimental
	 * @example
	 * const pointComponentDef = {
	 *   type: 'point',
	 *   rendererSettings: {
	 *     tranform() {
	 *       if(shouldApplyTransform) {
	 *         return {
	 *           horizontalScaling: 1,
	 *           horizontalSkewing: 0,
	 *           verticalSkewing: 0,
	 *           verticalScaling: 1,
	 *           horizontalMoving: x,
	 *           verticalMoving: y
	 *         };
	 *       }
	 *     }
	 *   }
	 *   data: {
	 * // ............
	 *
	 * chart.update({ partialData: true });
	 *//**
	 * An object containing width and height of the canvas buffer or a function returning an object on that format.
	 * Gets a rect object as input parameter.
	 * @typedef {function|object} RendererSettings~CanvasBufferSize
	 * @experimental
	 *//**
	 * A format to represent a transformation.
	 * @typedef {object} TransformObject
	 * @property {number} horizontalScaling
	 * @property {number} horizontalSkewing
	 * @property {number} verticalSkewing
	 * @property {number} verticalScaling
	 * @property {number} horizontalMoving
	 * @property {number} verticalMoving
	 *//**
	 * A function which returns either (1) false (to specify no progressive rendering used) or an object specifing the data chunk rendered.
	 *  This is only applied to a canvas renderer.
	 * @typedef {function} RendererSettings~Progressive
	 * @returns {ProgressiveObject|boolean}
	 * @experimental
	 *//**
	 * A format to represent a data chunk to be rendered.
	 * @typedef {object} ProgressiveObject
	 * @property {number} start - Start index of a data chunk.
	 * @property {number} end - End index of a data chunk.
	 * @property {boolean} isFirst - If it is the first data chunk rendered. This helps to clear a canvas before rendering.
	 * @property {boolean} isLast - If it is the last data chunk rendered. This helps to update other components depending on a component with progressive rendering.
	 * @experimental
	 *//**
	 * @typedef {object} BrushTargetConfig
	 * @property {string} key - Component key
	 * @property {string[]} [contexts] - Name of the brushing contexts to affect
	 * @property {string[]} [data] - The mapped data properties to add to the brush
	 * @property {string} [action='set'] - Type of action to respond with
	 */function addComponentDelta(shape,containerBounds,componentBounds){const dx=containerBounds.left-componentBounds.left;const dy=containerBounds.top-componentBounds.top;const type=getShapeType(shape);const deltaShape=extend$1$1(true,{},shape);switch(type){case 'circle':deltaShape.cx+=dx;deltaShape.cy+=dy;break;case 'polygon':for(let i=0,num=deltaShape.vertices.length;i<num;i++){const v=deltaShape.vertices[i];v.x+=dx;v.y+=dy;}break;case 'geopolygon':// vertices is 2D array
	for(let n=0;n<deltaShape.vertices.length;n++){const vertices=deltaShape.vertices[n];for(let i=0,num=vertices.length;i<num;i++){const v=vertices[i];v.x+=dx;v.y+=dy;}}break;case 'line':deltaShape.x1+=dx;deltaShape.y1+=dy;deltaShape.x2+=dx;deltaShape.y2+=dy;break;case 'point':case 'rect':deltaShape.x+=dx;deltaShape.y+=dy;break;}return deltaShape;}const moveToPosition=(element,comp,index)=>{const el=comp.instance.renderer().element();if(isNaN(index)||!el||!element||!element.children){return;}const nodes=element.children;const i=Math.max(0,index);const node=nodes[i];if(el===node){return;}const additionalEl=comp.instance.def.additionalElements&&comp.instance.def.additionalElements().filter(Boolean);if(element.insertBefore&&typeof node!=='undefined'){element.insertBefore(el,node);if(additionalEl){additionalEl.forEach(ae=>{element.insertBefore(ae,el);});}}else {if(additionalEl){additionalEl.forEach(ae=>{element.appendChild(ae,el);});}element.appendChild(el);}};function orderComponents(element,ordered){const elToIdx=[];let numElements=0;ordered.forEach(comp=>{elToIdx.push(numElements);// assume each component has at least one element
	numElements++;// check additional elements
	const additionalEl=comp.instance.def.additionalElements&&comp.instance.def.additionalElements();if(additionalEl){numElements+=additionalEl.length;}});ordered.forEach((comp,i)=>moveToPosition(element,comp,elToIdx[i]));}function chartFn(definition,context){/**
	   * @typedef {object} ChartDefinition
	   * @property {ChartDefinition~beforeDestroy} [beforeDestroy]
	   * @property {ChartDefinition~beforeMount} [beforeMount]
	   * @property {ChartDefinition~beforeRender} [beforeRender]
	   * @property {ChartDefinition~beforeUpdate} [beforeUpdate]
	   * @property {ChartDefinition~created} [created]
	   * @property {ChartDefinition~destroyed} [destroyed]
	   * @property {ChartDefinition~mounted} [mounted]
	   * @property {ChartDefinition~updated} [updated]
	   */let{/**
	     * Element to attach chart to
	     * @type {HTMLElement}
	     * @memberof ChartDefinition
	     */element,/**
	     * Chart data
	     * @type {Array<DataSource>|DataSource}
	     * @memberof ChartDefinition
	     */data=[],/**
	     * Chart settings
	     * @type {ChartSettings}
	     * @memberof ChartDefinition
	     */settings={},on={}}=definition;const registries=context.registries;const logger=context.logger;const theme=themeFn(context.style,context.palettes);const listeners=[];/**
	   * Chart instance
	   * @alias Chart
	   * @interface
	   */const instance=extend$1$1({},definition);const mediator$1=mediator();let visibleComponents=[];let currentScales=null;// Built scales
	let currentFormatters=null;// Built formatters
	let currentScrollApis=null;// Build scroll apis
	let currentInteractions=[];let dataset=()=>{};let dataCollection=()=>{};const brushes={};let stopBrushing=false;const createComponent=compSettings=>{if(!registries.component.has(compSettings.type)){logger.warn("Unknown component: ".concat(compSettings.type));return false;}const componentDefinition=registries.component(compSettings.type);const compInstance=componentFactory(componentDefinition,{settings:compSettings,chart:instance,mediator:mediator$1,registries,theme,container:element});return {instance:compInstance,settings:extend$1$1(true,{},compSettings),key:compSettings.key,hasKey:typeof compSettings.key!=='undefined'};};const componentsC=collectionFn({createComponent});// Create a callback that calls lifecycle functions in the definition and config (if they exist).
	function createCallback(method){let defaultMethod=arguments.length>1&&arguments[1]!==undefined?arguments[1]:()=>{};return function cb(){const inDefinition=typeof definition[method]==='function';let returnValue;for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}if(inDefinition){returnValue=definition[method].call(instance,...args);}else {returnValue=defaultMethod.call(instance,...args);}return returnValue;};}function getElementRect(el){if(typeof el.getBoundingClientRect==='function'){const{width,height}=el.getBoundingClientRect();return {x:0,y:0,width,height};}return {x:0,y:0,width:0,height:0};}const layout=()=>{let layoutSettings;if(settings.dockLayout){logger.warn('Deprecation Warning: "dockLayout" property should be renamed to "strategy"');layoutSettings=settings.dockLayout;}else {layoutSettings=settings.strategy;}const rect=getElementRect(element);return componentsC.layout({layoutSettings,rect});};const created=createCallback('created');const beforeMount=createCallback('beforeMount');const mounted=createCallback('mounted');const beforeUpdate=createCallback('beforeUpdate');const updated=createCallback('updated');const beforeRender=createCallback('beforeRender');const beforeDestroy=createCallback('beforeDestroy');const destroyed=createCallback('destroyed');const set=function(_data,_settings){let{partialData}=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const{formatters={},scales={},scroll={}}=_settings;dataset=datasets(_data,{logger,types:registries.data});if(!partialData){Object.keys(brushes).forEach(b=>brushes[b].clear());}if(_settings.palettes){theme.setPalettes(_settings.palettes);}if(_settings.style){theme.setStyle(_settings.style);}dataCollection=create$p(_settings.collections,{dataset},{logger});const deps={theme,logger};currentScales=collection(scales,{dataset,collection:dataCollection},_objectSpread2$1(_objectSpread2$1({},deps),{},{scale:registries.scale}));currentFormatters=collection$1(formatters,{dataset,collection:dataCollection},_objectSpread2$1(_objectSpread2$1({},deps),{},{formatter:registries.formatter}));currentScrollApis=builder(scroll,currentScrollApis);};const render=()=>{const{components=[]}=settings;beforeRender();set(data,settings);componentsC.set({components});const{visible,hidden,ordered}=layout();visibleComponents=visible;hidden.forEach(comp=>{comp.instance.hide();comp.visible=false;});visible.forEach(comp=>comp.instance.beforeMount());visible.forEach(comp=>comp.instance.mount());visible.forEach(comp=>comp.instance.beforeRender());visible.forEach(comp=>comp.instance.render());visible.forEach(comp=>comp.instance.mounted());visible.forEach(comp=>{comp.visible=true;});orderComponents(element,ordered);};function setInteractions(){let interactions=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];const current={};const newKeys=interactions.filter(it=>!!it.key).map(it=>it.key);currentInteractions.forEach(cit=>{if(cit.key&&newKeys.indexOf(cit.key)!==-1){// keep old instance
	current[cit.key]=cit;}else {cit.destroy();}});currentInteractions=interactions.map(intSettings=>{const intDefinition=intSettings.key&&current[intSettings.key]?current[intSettings.key]:registries.interaction(intSettings.type)(instance,mediator$1,element);intDefinition.set(intSettings);return intDefinition;});}const componentsFromPoint=p=>{const br=element.getBoundingClientRect();const x='clientX'in p?p.clientX:p.x;const y='clientY'in p?p.clientY:p.y;const tp={x:x-br.left,y:y-br.top};const ret=[];visibleComponents.forEach(c=>{const r=c.instance.getRect();// Do test on physical rect and use computed rect if available, otherwise fallback to computing a new rect for legacy support
	if(testRectPoint(r.computedPhysical?r.computedPhysical:{x:r.margin.left+r.x*r.scaleRatio.x,y:r.margin.top+r.y*r.scaleRatio.y,width:r.width*r.scaleRatio.x,height:r.height*r.scaleRatio.y},tp)){ret.push(c);}});return ret;};const addDefaultEventListeners=()=>{if(listeners.length||!element){return;}Object.keys(on).forEach(key=>{const listener=on[key].bind(instance);element.addEventListener(key,listener);listeners.push({key,listener});});const eventInfo={};const onTapDown=e=>{if(e.touches){eventInfo.x=e.touches[0].clientX;eventInfo.y=e.touches[0].clientY;eventInfo.multiTouch=e.touches.length>1;}else {eventInfo.x=e.clientX;eventInfo.y=e.clientY;eventInfo.multiTouch=false;}eventInfo.time=Date.now();eventInfo.comps=componentsFromPoint(eventInfo);};const onBrushTap=e=>{const comps=eventInfo.comps||componentsFromPoint(e);if(comps.every(c=>c.instance.def.disableTriggers)){return;}if(e.type==='touchend'){e.preventDefault();}if(!isValidTapEvent(e,eventInfo)){return;}for(let i=comps.length-1;i>=0;i--){const comp=comps[i];comp.instance.onBrushTap(e);if(stopBrushing){stopBrushing=false;break;}}};const onBrushOver=e=>{const comps=componentsFromPoint(e);for(let i=comps.length-1;i>=0;i--){const comp=comps[i];comp.instance.onBrushOver(e);if(stopBrushing){stopBrushing=false;break;}}};const brushEventList=[];brushEventList.push({key:'mousedown',listener:onTapDown});brushEventList.push({key:'mouseup',listener:onBrushTap});if(detectTouchSupport(element)){brushEventList.push({key:'touchstart',listener:onTapDown});brushEventList.push({key:'touchend',listener:onBrushTap});}brushEventList.push({key:'mousemove',listener:onBrushOver});brushEventList.forEach(event=>{element.addEventListener(event.key,event.listener);listeners.push(event);});};const removeDefaultEventListeners=()=>{listeners.forEach(_ref=>{let{key,listener}=_ref;return element.removeEventListener(key,listener);});listeners.length=0;};// Browser only
	const mount=()=>{element.innerHTML='';render();addDefaultEventListeners();setInteractions(settings.interactions);};const unmount=()=>{removeDefaultEventListeners();setInteractions();};/**
	   * Layout the chart with new settings and / or data
	   * @param {object} [def] - New chart definition
	   * @param {Array<DataSource>|DataSource} [def.data] Chart data
	   * @param {ChartSettings} [def.settings] Chart settings
	   * @param {string[]} [def.excludeFromUpdate=[]] Keys of components to not include in the layout
	   * @experimental
	   */instance.layoutComponents=function(){let newProps=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{excludeFromUpdate=[]}=newProps;if(newProps.data){data=newProps.data;}if(newProps.settings){settings=newProps.settings;setInteractions(newProps.settings.interactions);}beforeUpdate();set(data,settings);const{formatters,scales,components=[]}=settings;componentsC.update({components,data,excludeFromUpdate,formatters,scales});componentsC.forEach(comp=>{if(comp.updateWith){comp.instance.set(comp.updateWith);}});componentsC.forEach(comp=>{if(comp.updateWith){comp.instance.beforeUpdate();}});layout();// Relayout
	};/**
	   * Update the chart with new settings and / or data
	   * @param {object} [def] - New chart definition
	   * @param {Array<DataSource>|DataSource} [def.data] Chart data
	   * @param {ChartSettings} [def.settings] Chart settings
	   * @param {boolean} [def.partialData=false] If set to true, will trigger a data update only. Meaning the layout will not be updated
	   * @param {string[]} [def.excludeFromUpdate=[]] Keys of components to not include in the update
	   */instance.update=function(){let newProps=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{partialData,excludeFromUpdate=[]}=newProps;let visibleOrdered;if(newProps.data){data=newProps.data;}if(newProps.settings){settings=newProps.settings;setInteractions(newProps.settings.interactions);}beforeUpdate();set(data,settings,{partialData});const{formatters,scales,components=[]}=settings;componentsC.update({components,data,excludeFromUpdate,formatters,scales});componentsC.forEach(comp=>{if(comp.updateWith){comp.instance.set(comp.updateWith);}});componentsC.forEach(comp=>{if(comp.updateWith){comp.instance.beforeUpdate();}});const toUpdate=[];const toRender=[];let toRenderOrUpdate;if(partialData){componentsC.forEach(comp=>{if((comp.updateWith||comp.applyTransform)&&comp.visible){toUpdate.push(comp);}});toRenderOrUpdate=toUpdate;}else {const{visible,hidden,ordered}=layout();// Relayout
	visibleComponents=visible;toRenderOrUpdate=visible;visibleOrdered=ordered;visible.forEach(comp=>{if(comp.updateWith&&comp.visible){toUpdate.push(comp);}else {toRender.push(comp);}});hidden.forEach(comp=>{comp.instance.hide();comp.visible=false;delete comp.updateWith;comp.applyTransform=false;});}toRender.forEach(comp=>comp.instance.beforeMount());toRender.forEach(comp=>comp.instance.mount());toRenderOrUpdate.forEach(comp=>comp.instance.beforeRender());toRenderOrUpdate.forEach(comp=>{if((comp.updateWith||comp.applyTransform)&&comp.visible){comp.instance.update();}else {comp.instance.render();}});// Ensure that displayOrder is keept, only do so on re-layout update.
	// Which is only the case if partialData is false.
	if(!partialData){orderComponents(element,visibleOrdered);}toRender.forEach(comp=>comp.instance.mounted());toUpdate.forEach(comp=>comp.instance.updated());visibleComponents.forEach(comp=>{delete comp.updateWith;comp.visible=true;comp.applyTransform=false;});updated();};/**
	   * Destroy the chart instance.
	   */instance.destroy=()=>{beforeDestroy();componentsC.destroy();unmount();delete instance.update;delete instance.destroy;destroyed();};/**
	   * Get all shapes associated with the provided context
	   * @param {string} context The brush context
	   * @param {string} mode Property comparison mode.
	   * @param {Array<string>} props Which specific data properties to compare
	   * @param {string} key Which component to get shapes from. Default gives shapes from all components.
	   * @return {Array<object>} Array of objects containing shape and parent element
	   */instance.getAffectedShapes=function(ctx){let mode=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'and';let props=arguments.length>2?arguments[2]:undefined;let key=arguments.length>3?arguments[3]:undefined;let shapes=[];visibleComponents.filter(comp=>key===undefined||key===null||comp.key===key).forEach(comp=>{const brushedShapes=comp.instance.getBrushedShapes(ctx,mode,props);shapes=[...shapes,...brushedShapes];});return shapes;};/**
	   * Get all nodes matching the provided selector
	   * @param {string} selector CSS selector [type, attribute, universal, class]
	   * @returns {Array<SceneNode>} Array of objects containing matching nodes
	   *
	   * @example
	   * chart.findShapes('Circle') // [<CircleNode>, <CircleNode>]
	   * chart.findShapes('Circle[fill="red"][stroke!="black"]') // [CircleNode, CircleNode]
	   * chart.findShapes('Container Rect') // [Rect, Rect]
	   */instance.findShapes=selector=>{let shapes=[];visibleComponents.forEach(c=>{const matchedShapes=c.instance.findShapes(selector);shapes=[...shapes,...matchedShapes];});return shapes;};/**
	   * Get components overlapping a point.
	   * @param {Point} p - Point with x- and y-coordinate. The coordinate is relative to the browser viewport.
	   * @returns {Array<Component>} Array of component contexts
	   */instance.componentsFromPoint=p=>componentsFromPoint(p).map(comp=>comp.instance.ctx);/**
	   * Get all nodes colliding with a geometrical shape (circle, line, rectangle, point, polygon, geopolygon).
	   *
	   * The input shape is identified based on the geometrical attributes in the following order: circle => line => rectangle => point => polygon => geopolygon.
	   * Note that not all nodes on a scene have collision detection enabled.
	   * @param {Line|Rect|Point|Circle} shape - A geometrical shape. Coordinates are relative to the top-left corner of the chart instance container.
	   * @param {object} opts - Options
	   * @param {object[]} [opts.components] - Array of components to include in the lookup. If no components are specified, all components will be included.
	   * @param {string} [opts.components[].component.key] - Component key
	   * @param {string} [opts.components[].component.propagation] - if set to `stop`, will start lookup on top visible shape and propagate downwards until a shape is found.
	   * @param {string} [opts.propagation] - if set to `stop`, will start lookup on top visible component and propagate downwards until a component has at least a match.
	   * @returns {Array<SceneNode>} Array of objects containing colliding nodes
	   *
	   * @example
	   * chart.shapesAt(
	   *  {
	   *    x: 0,
	   *    y: 0,
	   *    width: 100,
	   *    height: 100
	   *  },
	   *  {
	   *    components: [
	   *      { key: 'key1', propagation: 'stop' },
	   *      { key: 'key2' }
	   *    ],
	   *    propagation: 'stop'
	   *  }
	   * );
	   */instance.shapesAt=function(shape){let opts=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let result=[];const containerBounds=element.getBoundingClientRect();let comps=visibleComponents;// Assume that visibleComponents is ordererd according to displayOrder
	if(Array.isArray(opts.components)&&opts.components.length>0){const compKeys=opts.components.map(c=>c.key);comps=visibleComponents.filter(c=>compKeys.indexOf(c.key)!==-1).map(c=>({instance:c.instance,opts:opts.components[compKeys.indexOf(c.key)]}));}for(let i=comps.length-1;i>=0;i--){const c=comps[i];const componentBounds=c.instance.renderer().element().getBoundingClientRect();const deltaShape=addComponentDelta(shape,containerBounds,componentBounds);const shapes=c.instance.shapesAt(deltaShape,c.opts);const stopPropagation=shapes.length>0&&opts.propagation==='stop';result=[...result,...shapes];if(result.length>0&&stopPropagation){return result;}}return result;};/**
	   * Brush data by providing a collection of data bound shapes.
	   * @param {SceneNode[]} shapes - An array of data bound shapes.
	   * @param {object} config - Options
	   * @param {BrushTargetConfig[]} config.components - Array of components to include in the lookup
	   *
	   * @example
	   * const shapes = chartInstance.shapesAt(...);
	   * const config = {
	   *  components:[
	   *    {
	   *      key: 'key1',
	   *      contexts: ['myContext'],
	   *      data: [''],
	   *      action: 'add'
	   *    }
	   *  ]
	   * };
	   * chartInstance.brushFromShapes(shapes, config);
	   */instance.brushFromShapes=function(shapes){let config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{components:[]};for(let i=0;i<config.components.length;i++){const iKey=config.components[i].key;visibleComponents.filter(c=>iKey===c.key).forEach(c=>{let compShapes=shapes.filter(shape=>shape.key===c.key);c.instance.brushFromShapes(compShapes,config.components[i]);});}};/**
	   * @private
	   * @param {string} name - Name of scroll api
	   * @returns {object}
	   */instance.scroll=function scroll(){let name=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'default';return getOrCreateScrollApi(name,currentScrollApis);};/**
	   * Get
	   * @param {string} key - Get the dataset identified by `key`
	   * @returns {Dataset}
	   */instance.dataset=key=>dataset(key);instance.dataCollection=key=>dataCollection(key);/**
	   * Get all registered scales
	   * @returns {Object<string,Scale>}
	   */instance.scales=function scales(){return currentScales.all();};/**
	   * Get all registered formatters
	   * @returns {Object<string,formatter>}
	   */instance.formatters=function formatters(){return currentFormatters.all();};/**
	   * Get or create brush context for this chart
	   * @param {string} name - Name of the brush context. If no match is found, a new brush context is created and returned.
	   * @returns {Brush}
	   */instance.brush=function brushFn(){let name=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'default';if(!brushes[name]){brushes[name]=brush();}return brushes[name];};/**
	   * Get or create a scale for this chart
	   * @param {string|object} v - Scale reference or scale options
	   * @returns {Scale}
	   * @example
	   * instance.scale('nameOfMyScale'); // Fetch an existing scale by name
	   * instance.scale({ scale: 'nameOfMyScale' }); // Fetch an existing scale by name
	   * instance.scale({ source: '0/1', type: 'linear' }); // Create a new scale
	   */instance.scale=function scale(v){return currentScales.get(v);};/**
	   * Get or create a formatter for this chart
	   * @param {string|object} v - Formatter reference or formatter options
	   * @returns {formatter}
	   * @example
	   * instance.formatter('nameOfMyFormatter'); // Fetch an existing formatter by name
	   * instance.formatter({ formatter: 'nameOfMyFormatter' }); // Fetch an existing formatter by name
	   * instance.formatter({ type: 'q' }); // Fetch an existing formatter by type
	   * instance.formatter({
	   *  formatter: 'd3',
	   *  type: 'number',
	   *  format: '1.0.%'
	   * }); // Create a new formatter
	   */instance.formatter=function formatter(v){return currentFormatters.get(v);};/**
	   * @param {boolean} [val] - Toggle brushing on or off. If value is omitted, a toggle action is applied to the current state.
	   */instance.toggleBrushing=function toggleBrushing(val){if(typeof val!=='undefined'){stopBrushing=val;}else {stopBrushing=!stopBrushing;}};/**
	   * Get a component context
	   * @param {string} key - Component key
	   * @returns {Component} Component context
	   */instance.component=key=>{const component=componentsC.findComponentByKey(key);return component===null||component===void 0?void 0:component.instance.ctx;};instance.logger=()=>logger;instance.theme=()=>theme;instance.storage=createStorage({animations:{updatingStageMeta:{isInit:false,shouldBeRemoved:false}}});/**
	   * Interaction instance
	   * @typedef {object} Interaction
	   * @property {function} on Enable interaction
	   * @property {function} off Disable interaction
	   * @property {function} destroy Destroy interaction
	   * @property {string} key Interaction identifier
	   *//**
	   * Get all interaction instances
	   * @name Chart.interactions
	   * @type {object}
	   * @example
	   * chart.interactions.instances; // Array of all interaction instances
	   * chart.interactions.on(); // Toggle on all interactions instances
	   * chart.interactions.off(); // Toggle off all interactions instances
	   */Object.defineProperty(instance,'interactions',{get(){return/** @lends Chart.interactions */{/** @type Array<Interaction> */instances:currentInteractions,/** Enable all interaction instances */on(){addDefaultEventListeners();currentInteractions.forEach(i=>i.on());},/** Disable all interaction instances */off(){removeDefaultEventListeners();currentInteractions.forEach(i=>i.off());}};}});created();if(element){beforeMount();mount();mounted(element);instance.element=element;}return instance;}const rendererRegistry=reg=>{let f=registryFactory(reg);f.prio=p=>p?f.default(p[0]):[f.default()];f.types=()=>f.getKeys();return f;};var componentRegistry=registryFactory();function datumExtract$2(propCfg,cell,_ref){let{key}=_ref;const datum={value:typeof propCfg.value==='function'// eslint-disable-line no-nested-ternary
	?propCfg.value(cell):typeof propCfg.value!=='undefined'?propCfg.value:cell};datum.label=typeof propCfg.label==='function'// eslint-disable-line no-nested-ternary
	?propCfg.label(cell):typeof propCfg.label!=='undefined'?String(propCfg.label):String(datum.value);if(propCfg.field){datum.source={key,field:propCfg.field.key()};}return datum;}function extract$2(config,dataset){const cfgs=Array.isArray(config)?config:[config];let dataItems=[];cfgs.forEach(cfg=>{if(typeof cfg.field!=='undefined'){const f=dataset.field(cfg.field);const sourceKey=dataset.key();if(!f){throw Error("Field '".concat(cfg.field,"' not found"));}const{props,main}=getPropsInfo(cfg,dataset);const propsArr=Object.keys(props);const track$1=!!cfg.trackBy;const trackType=typeof cfg.trackBy;const tracker={};const trackedItems=[];const items=f.items();const mapped=[];for(let idx=0;idx<items.length;idx++){const mainCell=items[idx];const exclude=main.filter&&!main.filter(mainCell);if(exclude){continue;}const ret=datumExtract$2(main,mainCell,{key:sourceKey});// loop through all props that need to be mapped and
	// assign 'value' and 'source' to each property
	propsArr.forEach(prop=>{const p=props[prop];let propCell=p.field?p.field.items()[idx]:mainCell;ret[prop]=datumExtract$2(p,propCell,{key:sourceKey});});// collect items based on the trackBy value
	// items with the same trackBy value are placed in an array and reduced later
	if(track$1){track({cfg,itemData:mainCell,obj:ret,target:trackedItems,tracker,trackType});}mapped.push(ret);}// reduce if items have been grouped
	if(track$1){dataItems=[...dataItems,...collect(trackedItems,{main,propsArr,props})];}else {dataItems=[...dataItems,...mapped];}}});return dataItems;}const filters={numeric:values=>values.filter(v=>typeof v==='number'&&!isNaN(v))};function createFields$1(_ref){let{source,data,cache,config}=_ref;let headers;let content=data;const parse=config&&config.parse;if(Array.isArray(data[0])){// assume 2d matrix of data
	if(parse&&parse.headers===false){headers=data[0].map((v,i)=>i);}else {headers=data[0];content=data.slice(1);}}else {headers=Object.keys(data[0]);}const rowFn=!!parse&&typeof parse.row==='function'&&parse.row;let flds=headers;if(parse&&typeof parse.fields==='function'){flds=parse.fields(flds.slice());}else {flds=headers.map(h=>({key:h,title:h}));}let fieldValues;if(Array.isArray(data[0])){fieldValues=flds.map(()=>[]);}else {fieldValues={};flds.forEach(f=>{fieldValues[f.key]=[];});}for(let r=0;r<content.length;r++){const row=rowFn?rowFn(content[r],r,flds):content[r];if(!row){continue;}if(Array.isArray(row)){for(let c=0;c<flds.length;c++){fieldValues[c].push(row[c]);}}else {for(let c=0;c<flds.length;c++){fieldValues[flds[c].key].push(row[flds[c].key]);}}}const fv=Array.isArray(fieldValues)?i=>fieldValues[i]:i=>fieldValues[flds[i].key];for(let c=0;c<flds.length;c++){const values=fv(c);const numericValues=filters.numeric(values);const isMeasure=numericValues.length>0;const type=isMeasure?'measure':'dimension';const min=isMeasure?Math.min(...numericValues):NaN;const max=isMeasure?Math.max(...numericValues):NaN;cache.fields.push(field(extend$1$1({source,key:c,title:flds[c].title,values,min,max,type},flds[c]),{value:flds[c].value,label:flds[c].label}));}}const dsv=_ref2=>{let{data,config}=_ref2;const rows=data.split('\n');const row0=rows[0];const row1=rows[1];let delimiter=',';if(config&&config.parse&&config.parse.delimiter){delimiter=config.parse.delimiter;}else if(row0){// guess delimiter
	const guesses=[/,/,/\t/,/;/];for(let i=0;i<guesses.length;i++){const d=guesses[i];if(row0&&row1){if(d.test(row0)&&d.test(row1)&&row0.split(d).length===row1.split(d).length){delimiter=d;break;}}else if(d.test(row0)){delimiter=d;}}}return rows.map(row=>row.split(delimiter));};const parseData=_ref3=>{let{key,data,cache,config}=_ref3;if(!data){return;}let dd=data;if(typeof dd==='string'){// assume dsv
	dd=dsv({data,config});}if(!Array.isArray(dd)){return;// warn?
	}createFields$1({data:dd,cache,source:key,config});};/**
	 * Create a new dataset with default settings
	 * @private
	 * @return {Dataset}
	 */function ds(){let{key,data,config}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const cache={fields:[]};/**
	   * @alias Dataset
	   * @interface
	   */const dataset={/**
	     * Get the key identifying this dataset
	     * @returns {string}
	     */key:()=>key,/**
	     * Get the raw data
	     * @returns {any}
	     */raw:()=>data,/**
	     * Find a field within this dataset
	     * @param {string} query - The field to find
	     * @returns {Field}
	     */field:query=>findField$2(query,{cache}),/**
	     * Get all fields within this dataset
	     * @returns {Array<Field>}
	     */fields:()=>cache.fields.slice(),/**
	     * Extract data items from this dataset
	     * @param {DataExtraction~Extract|DataFieldExtraction} config
	     * @returns {Array<DatumExtract>}
	     */extract:cfg=>extract$2(cfg,dataset),/**
	     * @returns {null}
	     */hierarchy:()=>null};parseData({key,data,config,cache});return dataset;}ds.util={normalizeConfig:getPropsInfo,collect,track};/**
	 * Callback function. Should return the key to stack by
	 * @callback
	 * @typedef {function} DataExtraction~StackKeyCallback
	 * @param {DatumExtract} datum The extracted datum
	 * @returns {any} The data value to stack by
	 *//**
	 * Callback function. Should return the data value to stack with
	 * @callback
	 * @typedef {function} DataExtraction~StackValueCallback
	 * @param {DatumExtract} datum The extracted datum
	 * @returns {any} The data value to stack with
	 *//**
	 * Callback function to filter the extracted data items
	 * @callback
	 * @typedef {function} DataExtraction~FilterCallback
	 * @param {DatumExtract} datum The extracted datum
	 * @returns {boolean} Return true if the datum should be included in the final data set
	 *//**
	 * Callback function to sort the extracted data items
	 * @callback
	 * @typedef {function} DataExtraction~SortCallback
	 * @param {DatumExtract} a The extracted datum
	 * @param {DatumExtract} b The extracted datum
	 * @returns {number} If less than 0, sort a before b. If greater than 0, sort b before a
	 *//**
	 * Used to extract data from a `DataSource`
	 * @typedef {object} DataExtraction
	 * @property {DataExtraction~Extract|DataExtraction~Extract[]} extract Extract definition
	 * @property {object} [stack] If provided, defines how the data should be stacked
	 * @property {DataExtraction~StackKeyCallback} stack.stackKey Callback function. Should return the key to stack by
	 * @property {DataExtraction~StackValueCallback} stack.value Callback function. Should return the data value to stack with
	 * @property {DataExtraction~FilterCallback} [filter] Callback function to filter the extracted data items
	 * @property {DataExtraction~SortCallback} [sort] Callback function to sort the extracted data items
	 * @example
	{
	  extract: [{
	    source: 'Products',
	    field: 'Product',
	    value: d => d.name,
	    label: d => `<${d.name}>`
	    props: {
	      year: { field: 'Year' }
	      num: { field: 'Sales' }
	    }
	  }],
	  filter: d => d.label !== 'Sneakers', // extract everything except Sneakers
	  sort: (a, b) => a.label > b.label ? -1 : 1, // sort descending
	}
	 *//**
	 * @typedef {object} DataFieldExtraction
	 * @property {string} source - Which data source to extract from
	 * @property {string} field - The field to extract data from
	 * @property {DataExtraction~Extract~ValueFn|string|number|boolean} [value] - The field value accessor
	 * @property {DataExtraction~Extract~LabelFn|string|number|boolean} [label] - The field label accessor
	 * @example
	 * {
	 *  source: 'Products',
	 *  field: 'Sales',
	 *  value: (val) => Math.round(val),
	 *  label: (val) => `<${val}>`
	 * }
	 *//**
	 * Data extraction definition. Define how and what kind of data should be extracted from a `DataSource`.
	 * @typedef {object} DataExtraction~Extract
	 * @property {string} source - Which data source to extract from
	 * @property {string} field - The field to extract data from
	 * @property {DataExtraction~Extract~ValueFn|string|number|boolean} [value] - The field value accessor
	 * @property {DataExtraction~Extract~LabelFn|string|number|boolean} [label] - The field label accessor
	 * @property {DataExtraction~Extract~TrackByFn} [trackBy] - Track by value accessor
	 * @property {DataExtraction~Extract~ReduceFn|string} [reduce] - Reducer function
	 * @property {DataExtraction~Extract~ReduceLabelFn|string} [reduceLabel] - Label reducer function
	 * @property {DataExtraction~Extract~FilterFn} [filter] - Filter function
	 * @property {object.<string, DataExtraction~Extract~Props>} [props] - Additional properties to add to the extracted item
	 * @example
	 * {
	    source: 'Products',
	    field: 'Product',
	    value: (val) => val,
	    label: (val) => `<${val}>`
	    props: {
	      year: { field: 'Year' }
	      num: { field: 'Sales' }
	    }
	  }
	 *//**
	 * @typedef {object} DataExtraction~Extract~Props
	 * @property {string} field - The field to extract data from
	 * @property {DataExtraction~Extract~ValueFn|string|number|boolean} [value] - The field value accessor
	 * @property {DataExtraction~Extract~LabelFn|string|number|boolean} [label] - The field label accessor
	 * @example
	 * {
	 *  field: 'Sales',
	 *  value: (val) => Math.round(val),
	 *  label: (val) => `<${val}>`
	 * }
	 *//**
	 * Value callback function
	 * @callback DataExtraction~Extract~ValueFn
	 * @param {any} cell The field cell
	 * @returns {any}
	 *//**
	 * Label callback function
	 * @callback DataExtraction~Extract~LabelFn
	 * @param {any} cell The field cell
	 * @returns {string}
	 *//**
	 * Filter callback function
	 * @callback DataExtraction~Extract~FilterFn
	 * @param {any} cell The field cell
	 * @returns {boolean}
	 *//**
	 * TrackBy callback function
	 * @callback DataExtraction~Extract~TrackByFn
	 * @param {any} cell The field cell
	 * @returns {any}
	 *//**
	 * Reduce callback function
	 * @callback DataExtraction~Extract~ReduceFn
	 * @param {any[]} values The collected values to reduce
	 * @returns {any}
	 *//**
	 * ReduceLabel callback function
	 * @callback DataExtraction~Extract~ReduceLabelFn
	 * @param {any[]} labels The collected labels to reduce
	 * @param {any} value Reduced value
	 * @returns {string}
	 *//**
	 * @typedef {object} DatumExtract
	 * @property {any} value - The extracted value
	 * @property {string} label - The extracted value as a string
	 * @property {object} source - The data source of the extracted data
	 * @property {string} source.key - The data-source key
	 * @property {string} source.field - The source field
	 */const dataRegistry=registryFactory();dataRegistry.default('matrix');dataRegistry('matrix',ds);dataRegistry('default',ds);// deprecated
	/**
	 * Manages event handlers for native events
	 * @private
	 */function native(chart,mediator,element){let instance={chart,mediator,element};let nativeEvents=[];let settings;let itKey;let isOn=true;/**
	   * Set default settings
	   * @private
	   */function setDefaultSettings(newSettings){itKey=newSettings.key;settings=newSettings;settings.events=settings.events||[];if(settings.enable===undefined){settings.enable=true;}}/**
	   * Add native events based on settings
	   * @private
	   */function addEvents(){if(typeof settings.enable==='function'){settings.enable=settings.enable.bind(instance)();}if(!settings.enable){return;// interaction is disabled
	}Object.keys(settings.events).forEach(key=>{const listener=settings.events[key].bind(instance);element.addEventListener(key,listener);nativeEvents.push({key,listener});});}/**
	   * Removes all added native events
	   * @private
	   */function removeAddedEvents(){// remove added native events
	nativeEvents.forEach(_ref=>{let{key,listener}=_ref;element.removeEventListener(key,listener);});nativeEvents=[];}return {/**
	     * Getter for the key.
	     * @private
	     */get key(){return itKey;},/**
	     * Updates this with new settings
	     * @private
	     * @param {object} newSettings
	     * @param {string} [newSettings.type] - The interaction type. Is 'native' for this component
	     * @param {boolean|function} [newSettings.enable=true] - Should the interactions defined here be enabled or not.
	     * This is only run when adding event handlers. In effect at startup, update or during on/off.
	     * It does not run during every event loop.
	     * @param {array} [newSettings.gestures] - The keys in this object is the names of native events
	     * that should be added to the chart element and they should all point to function which
	     * will be the corresponding event handler.
	     */set(newSettings){setDefaultSettings(newSettings);removeAddedEvents();if(isOn){addEvents();}},/**
	     * Turns off interactions
	     * @private
	     */off(){isOn=false;removeAddedEvents();},/**
	     * Turns off interactions
	     * @private
	     */on(){isOn=true;if(nativeEvents.length===0){addEvents();}},/**
	     * Destroys and unbinds all event handlers
	     * @private
	     */destroy(){removeAddedEvents();instance=null;settings=null;}};}/**
	 * @interface InteractionSettings
	 * @property {string} type Type of interaction handler
	 * @property {string} [key] Unique key identifying the handler
	 * @property {function|boolean} enable Enable or disable the interaction handler. If a callback function is provided, it must return either true or false
	 * @example
	 * {
	 *  type: 'native',
	 *  key: 'nativeHandler',
	 *  enable: () => true,
	 *  events: { // "events" is a property specific to the native handler
	 *    mousemove: (e) => console.log('mousemove', e),
	 *  }
	 * }
	 */const reg$3=registryFactory();reg$3('native',native);/**
	 * Short-hand for max(min())
	 *
	 * @param {number} min Minimum allowed value
	 * @param {number} max Maximum allowed value
	 * @param {number} value The actual value to cap
	 * @ignore
	 */function cap(min,max,value){return Math.max(min,Math.min(max,value));}/**
	 * Resolve a diff, i.e. resolveDiff(0.2, 0.6, 1, 100) = 20
	 *
	 * @param {object} params parameters
	 * @param {number} params.start Normalized start value
	 * @param {number} params.end Normalized end value
	 * @param {number} params.minPx The minimum number of pixels
	 * @param {number} params.maxPx Maximum number of pixels, i.e. the width or height
	 * @ignore
	 */function resolveDiff(_ref){let{start,end,minPx=0.1,maxPx=1}=_ref;const high=Math.max(start,end);const low=Math.min(start,end);const highModified=cap(-0.1,1.2,high);const lowModified=cap(-0.1,1.2,low);const wantedDiff=highModified*maxPx-lowModified*maxPx;const actualDiff=Math.max(minPx,wantedDiff);const startModifier=(actualDiff-wantedDiff)/2;const actualLow=lowModified*maxPx-startModifier;return {actualDiff,startModifier,actualLow};}/**
	 * Out of bounds shape
	 * @param {object} params parameters
	 * @param {object} params.item Resolved styling item from box component with item.major
	 * @param {number} params.value 0 or 1 depending on where to render the oob shape
	 * @param {number} params.boxWidth Un-calculated box width in relative/normalized format
	 * @param {number} params.boxPadding Un-calculated box padding in relative/normalized format
	 * @param {number} params.rendWidth The pixel width of the area to render upon
	 * @param {number} params.rendHeight The pixel height of the area to render upon
	 * @param {boolean} params.flipXY Wether or not to flip X and Y coordinates together with Width and Height
	 * @param {function} params.symbol Symbol library function from component
	 * @ignore
	 */function oob(_ref){let{item,value,boxCenter,rendWidth,rendHeight,flipXY,symbol}=_ref;let x='x';let y='y';let calcwidth=rendWidth;let calcheight=rendHeight;let startAngle=value<0.5?90:-90;if(flipXY){x='y';y='x';calcwidth=rendHeight;calcheight=rendWidth;startAngle=value<0.5?180:0;}return symbol(extend$1$1({},item.oob,{[x]:boxCenter*calcwidth,[y]:Math.max(item.oob.size/2,Math.min(value*calcheight,calcheight-item.oob.size/2)),startAngle}));}/**
	 * Box shape calculation function
	 * @param {object} params parameters
	 * @param {object} params.item Resolved styling item from box component with item.major
	 * @param {number} params.boxWidth Un-calculated box width in relative/normalized format
	 * @param {number} params.boxPadding Un-calculated box padding in relative/normalized format
	 * @param {number} params.rendWidth The pixel width of the area to render upon
	 * @param {number} params.rendHeight The pixel height of the area to render upon
	 * @param {boolean} params.flipXY wether or not to flip X and Y coordinates together with Width and Height
	 * @ignore
	 */function box$1(_ref2){let{item,boxWidth,boxPadding,rendWidth,rendHeight,flipXY}=_ref2;let x='x';let y='y';let width='width';let height='height';let calcwidth=rendWidth;let calcheight=rendHeight;if(flipXY){x='y';y='x';width='height';height='width';calcwidth=rendHeight;calcheight=rendWidth;}const{actualDiff,actualLow}=resolveDiff({start:item.start,end:item.end,minPx:item.box.minHeightPx,maxPx:calcheight});return extend$1$1({},item.box,{type:'rect',[x]:(boxPadding+item.major)*calcwidth,[y]:actualLow,[height]:actualDiff,[width]:boxWidth*calcwidth,data:item.data||{},collider:{type:null}});}/**
	 * A vertical line shape (for start - min, end - max values)
	 * @param {object} params parameters
	 * @param {object} params.item Resolved styling item from box component with item.major
	 * @param {number} params.from Normalized from value
	 * @param {number} params.to Normalized to value
	 * @param {number} params.boxCenter Center coordinate for the box
	 * @param {number} params.rendWidth The pixel width of the area to render upon
	 * @param {number} params.rendHeight The pixel height of the area to render upon
	 * @param {boolean} params.flipXY wether or not to flip X and Y coordinates together with Width and Height
	 * @ignore
	 */function verticalLine(_ref3){let{item,from,to,boxCenter,rendWidth,rendHeight,flipXY}=_ref3;let x1='x1';let y1='y1';let x2='x2';let y2='y2';let calcwidth=rendWidth;let calcheight=rendHeight;if(flipXY){x1='y1';y1='x1';x2='y2';y2='x2';calcwidth=rendHeight;calcheight=rendWidth;}return extend$1$1({},item.line,{type:'line',[y2]:Math.floor(from*calcheight),[x1]:boxCenter*calcwidth,[y1]:Math.floor(to*calcheight),[x2]:boxCenter*calcwidth,data:item.data||{},collider:{type:null}});}/**
	 * A horizontal line shape (for median and whiskers)
	 * @param {object} params parameters
	 * @param {object} params.item Resolved styling item from box component with item.major
	 * @param {string} params.key Which key to use as style base in the item object
	 * @param {number} params.position At which "height" (X) to position the horizontal line
	 * @param {number} params.width Width of the horizontal line (i.e. box width or a multiple of it)
	 * @param {number} params.boxCenter Center coordinate for the box
	 * @param {number} params.rendWidth The pixel width of the area to render upon
	 * @param {number} params.rendHeight The pixel height of the area to render upon
	 * @param {boolean} params.flipXY wether or not to flip X and Y coordinates together with Width and Height
	 * @ignore
	 */function horizontalLine(_ref4){let{item,key,position,width,boxCenter,rendWidth,rendHeight,flipXY}=_ref4;let x1='x1';let y1='y1';let x2='x2';let y2='y2';let calcwidth=rendWidth;let calcheight=rendHeight;if(flipXY){x1='y1';y1='x1';x2='y2';y2='x2';calcwidth=rendHeight;calcheight=rendWidth;}const halfWidth=width/2;return extend$1$1({type:'line'},item[key],{[y1]:Math.floor(position*calcheight),[x1]:(boxCenter-halfWidth)*calcwidth,[y2]:Math.floor(position*calcheight),[x2]:(boxCenter+halfWidth)*calcwidth,r:halfWidth*calcwidth,cx:boxCenter*calcwidth,cy:position*calcheight,width:width*calcwidth,data:item.data||{},collider:{type:null}});}/**
	 * A horizontal line shape (for median and whiskers)
	 * @param {number} bandwidth The current bandwidth for this item
	 * @param {object} item A resolved style item to render with major and box width variables, minWidthPx and maxWidthPx
	 * @param {number} maxMajorWidth The actual maximum major width
	 * @ignore
	 */function getBoxWidth(bandwidth,item,maxMajorWidth){const{width,maxWidthPx,minWidthPx}=item.box;const sign=bandwidth>=0?1:-1;let boxWidth=Math.min(sign*bandwidth*width,isNaN(maxWidthPx)?maxMajorWidth:maxWidthPx/maxMajorWidth);boxWidth=isNaN(minWidthPx)?boxWidth:Math.max(minWidthPx/maxMajorWidth,boxWidth);return boxWidth*sign;}function buildShapes(_ref){let{width,height,flipXY,resolved,keys,symbol}=_ref;// if (!settings || !settings.major || !settings.major.scale || !settings.minor || !settings.minor.scale) {
	//   return [];
	// }
	const output=[];const majorItems=resolved.major.items;if(!majorItems.length){return output;}const rendWidth=width;const rendHeight=height;const maxMajorWidth=flipXY?height:width;const majorSettings=resolved.major.settings;const minorProps=['start','end','min','max','med'].filter(prop=>typeof resolved.minor.settings[prop]!=='undefined');const numMinorProps=minorProps.length;const nonOobKeys=keys.filter(key=>key!=='oob');let children;let major;let minorItem;let boxWidth;let boxPadding;let boxCenter;let isLowerOutOfBounds;let isHigherOutOfBounds;let isOutOfBounds;const numKeys=keys?keys.length:0;const numNonOobKeys=nonOobKeys?nonOobKeys.length:0;function addBox(){/* THE BOX */if(minorItem.box&&isNumber(minorItem.start)&&isNumber(minorItem.end)){children.push(box$1({item:minorItem,boxWidth,boxPadding,rendWidth,rendHeight,flipXY}));}}function addLine(){/* LINES MIN - START, END - MAX */if(isNumber(minorItem.min)&&isNumber(minorItem.start)){children.push(verticalLine({item:minorItem,from:minorItem.min,to:minorItem.start,boxCenter,rendWidth,rendHeight,flipXY}));}if(isNumber(minorItem.max)&&isNumber(minorItem.end)){children.push(verticalLine({item:minorItem,from:minorItem.max,to:minorItem.end,boxCenter,rendWidth,rendHeight,flipXY}));}}function addMedian(){/* MEDIAN */if(minorItem.median&&isNumber(minorItem.med)){children.push(horizontalLine({item:minorItem,key:'median',position:minorItem.med,width:boxWidth,boxCenter,rendWidth,rendHeight,flipXY}));}}function addWhisker(){/* WHISKERS */if(minorItem.whisker){const whiskerWidth=boxWidth*minorItem.whisker.width;if(isNumber(minorItem.min)){children.push(horizontalLine({item:minorItem,key:'whisker',position:minorItem.min,width:whiskerWidth,boxCenter,rendWidth,rendHeight,flipXY}));}if(isNumber(minorItem.max)){children.push(horizontalLine({item:minorItem,key:'whisker',position:minorItem.max,width:whiskerWidth,boxCenter,rendWidth,rendHeight,flipXY}));}}}function addOutOfBounds(){/* OUT OF BOUNDS */if(isLowerOutOfBounds){children.push(oob({item:minorItem,value:0,boxCenter,rendWidth,rendHeight,flipXY,symbol}));}else if(isHigherOutOfBounds){children.push(oob({item:minorItem,value:1,boxCenter,rendWidth,rendHeight,flipXY,symbol}));}}const addMarkerList={box:addBox,line:addLine,median:addMedian,whisker:addWhisker};function checkOutOfBounds(){let value;let max=-Number.MAX_VALUE;let min=Number.MAX_VALUE;for(let n=0;n<numMinorProps;n++){value=minorItem[minorProps[n]];if(isNumber(value)){if(max<value){max=value;}if(min>value){min=value;}}}isLowerOutOfBounds=max<0&&max!==-Number.MAX_VALUE;isHigherOutOfBounds=min>1&&min!==Number.MAX_VALUE;isOutOfBounds=isLowerOutOfBounds||isHigherOutOfBounds;}for(let i=0,len=majorItems.length;i<len;i++){children=[];major=null;const majorItem=majorItems[i];const d=majorItem.data;let majorVal=null;let majorEndVal=null;if(typeof majorSettings.binStart!=='undefined'){// if start and end is defined
	majorVal=majorItem.binStart;majorEndVal=majorItem.binEnd;major=majorSettings.binStart.scale;}else {major=majorSettings.major.scale;majorVal=major?majorItem.major:0;}let bandwidth=0;if(!major){bandwidth=1;}else if(major.bandwidth){bandwidth=major.bandwidth();majorVal-=bandwidth/2;}else {bandwidth=majorEndVal-majorVal;}minorItem=extend$1$1({},{major:majorVal,majorEnd:majorEndVal},resolved.minor.items[i]);for(let j=0;j<numKeys;j++){minorItem[keys[j]]=resolved[keys[j]].items[i];}boxWidth=getBoxWidth(bandwidth,minorItem,maxMajorWidth);boxPadding=(bandwidth-boxWidth)/2;boxCenter=boxPadding+minorItem.major+boxWidth/2;checkOutOfBounds();if(!isOutOfBounds){for(let k=0;k<numNonOobKeys;k++){if(minorItem[nonOobKeys[k]]&&minorItem[nonOobKeys[k]].show===false){continue;}addMarkerList[nonOobKeys[k]]();}}else if(minorItem.oob){addOutOfBounds();}const container={type:'container',data:d,collider:{type:'bounds'},children};output.push(container);}return output;}/**
	 * Resolve a complex object using the built-in resolver from this.resolver in component
	 * @ignore
	 */function complexResolver(_ref){let{keys,data,defaultSettings,style,settings,width,height,resolver}=_ref;const defaults=extend$1$1(true,{},defaultSettings||{},style||{});const scaled={major:settings.orientation==='horizontal'?height:width,minor:settings.orientation==='horizontal'?width:height};const majorSettings=settings.major;let majorResolved;if(typeof majorSettings==='object'&&typeof majorSettings.ref==='object'&&typeof majorSettings.ref.start!=='undefined'&&typeof majorSettings.ref.end!=='undefined'){// temporary backwards compatibility
	majorResolved=resolver.resolve({data,defaults:{start:0,end:1},scaled,settings:extend$1$1(true,{},{binStart:{scale:settings.major.scale,ref:settings.major.ref.start},binEnd:{scale:settings.major.scale,ref:settings.major.ref.end}})});}else if(typeof majorSettings==='object'&&typeof majorSettings.binStart!=='undefined'&&typeof majorSettings.binEnd!=='undefined'){majorResolved=resolver.resolve({data,defaults:{start:0,end:1},scaled,settings:extend$1$1(true,{},{binStart:{scale:settings.major.scale,ref:'binStart'},binEnd:{scale:settings.major.scale,ref:'binEnd'}},settings.major)});}else {majorResolved=resolver.resolve({data,scaled,defaults:{major:0.5},settings:{major:settings.major}});}const minorSettings=settings.minor||{};const defaultMinorSettings={};['start','end','min','max','med'].forEach(prop=>{if(minorSettings[prop]||data.items&&data.items.length&&data.items[0][prop]){defaultMinorSettings[prop]={scale:minorSettings.scale,ref:prop};}});const minorResolved=resolver.resolve({data,defaults:{start:0,end:1},scaled,settings:extend$1$1(true,{},defaultMinorSettings,minorSettings)});let key;let ext={major:majorResolved,minor:minorResolved};for(let ki=0,len=keys.length;ki<len;ki++){if(!settings[key]||settings[key].show!==false){key=keys[ki];ext[key]=resolver.resolve({data,defaults:defaults[key],settings:settings[key],scaled});}}return ext;}const DEFAULT_DATA_SETTINGS$2={oob:{show:true,type:'n-polygon',fill:'#999',stroke:'#000',strokeWidth:0,size:10,sides:3,startAngle:-90},box:{show:true,fill:'#fff',stroke:'#000',strokeWidth:1,strokeLinejoin:'miter',width:1,maxWidthPx:undefined,minWidthPx:1,minHeightPx:1},line:{show:true,stroke:'#000',strokeWidth:1},median:{show:true,stroke:'#000',strokeWidth:1},whisker:{show:true,stroke:'#000',strokeWidth:1,fill:'',type:'line',width:1}};const dataKeys=Object.keys(DEFAULT_DATA_SETTINGS$2);const component$3={require:['chart','resolver','symbol'],defaultSettings:{settings:{},data:{},style:{box:'$shape',line:'$shape-guide',whisker:'$shape-guide',median:'$shape-guide--inverted'}},created(){this.state={};},render(_ref){let{data}=_ref;const{width,height}=this.rect;const flipXY=this.settings.settings.orientation==='horizontal';const{style,resolver,symbol}=this;const keys=dataKeys.filter(key=>!this.settings.settings[key]||this.settings.settings[key].show!==false);const defaultSettings={};keys.forEach(key=>defaultSettings[key]=DEFAULT_DATA_SETTINGS$2[key]);const resolved=complexResolver({keys,data,defaultSettings,style,settings:this.settings.settings,width,height,resolver});const{settings,items}=resolved;const shapes=buildShapes({width,height,flipXY,resolved,keys,symbol});return shapes;}};function box(picasso){picasso.component('box',component$3);picasso.component('box-marker',component$3);// temporary backwards compatibility - DEPRECATED
	}/**
	 * @typedef {object} ComponentBox
	 * @extends ComponentSettings
	 * @property {'box'} type component type
	 * @example
	 * {
	 *   type: "box",
	 *   data: {
	 *    mapTo: {
	 *      min: { source: "/qHyperCube/qMeasureInfo/0" },
	 *      start: { source: "/qHyperCube/qMeasureInfo/1" },
	 *      med: { source: "/qHyperCube/qMeasureInfo/2" },
	 *      end: { source: "/qHyperCube/qMeasureInfo/3" },
	 *      max: { source: "/qHyperCube/qMeasureInfo/4" },
	 *    },
	 *    groupBy: {
	 *      source: "/qHyperCube/qDimensionInfo/0"
	 *    }
	 *  },
	 *  settings: {
	 *    major: {
	 *      scale: { source: "/qHyperCube/qDimensionInfo/0" }
	 *    },
	 *    minor: {
	 *      scale: { source: ["/qHyperCube/qMeasureInfo/0",
	 *               "/qHyperCube/qMeasureInfo/1",
	 *               "/qHyperCube/qMeasureInfo/2",
	 *               "/qHyperCube/qMeasureInfo/3",
	 *               "/qHyperCube/qMeasureInfo/4"] }
	 *    }
	 *  }
	 * }
	 *//**
	 * @typedef {object} ComponentBox.settings
	 * @property {object} major
	 * @property {string} major.scale The scale to use along the major (dimension) axis
	 * @property {string|ComponentBox~MajorReference} [major.ref='self'] Reference to the data property along the major axis
	 * @property {object} minor
	 * @property {string} minor.scale The scale to use along the minor (measure) axis
	 * @property {string} [orientation='vertical'] Which orientation to use (vertical or horizontal)
	 * @property {object} [box] Visual properties for the box shape in the box marker
	 * @property {boolean} [box.show=true] Boolean for showing the box shape
	 * @property {string} [box.fill='#fff']
	 * @property {string} [box.stroke='#000']
	 * @property {number} [box.strokeWidth=1]
	 * @property {string} [box.strokeLinejoin='miter']
	 * @property {number} [box.width=1]
	 * @property {number} [box.maxWidthPx=100] Maximum width of the box in pixels (not applicable when using major start and end)
	 * @property {number} [box.minWidthPx=1] Minimum width of the box in pixels (not applicable when using major start and end)
	 * @property {number} [box.minHeightPx=1] Minimum height of the box shape
	 * @property {object} [line] Visual properties for lines between min-start, end-max.
	 * @property {boolean} [line.show=true]
	 * @property {string} [line.stroke='#000']
	 * @property {number} [line.strokeWidth=1]
	 * @property {object} [whisker] All the visual properties for whiskers at min and max.
	 * @property {boolean} [whisker.show=true]
	 * @property {string} [whisker.stroke='#000']
	 * @property {number} [whisker.strokeWidth=1]
	 * @property {number} [whisker.width=1]
	 * @property {object} [median] Visual properties for the median
	 * @property {boolean} [median.show=true]
	 * @property {string} [median.stroke='#000']
	 * @property {number} [median.strokeWidth=1]
	 * @property {object} [oob] EXPERIMENTAL: Out of bounds symbol utilizing the symbol API
	 * @property {boolean} [oob.show=true]
	 * @property {string} [oob.type='n-polygon'] Type of the symbol to be used
	 * @property {string} [oob.fill='#999'] Fill color of the symbol
	 * @property {string} [oob.stroke='#000'] Stroke color
	 * @property {number} [oob.strokeWidth=0] Stroke width
	 * @property {number} [oob.size=10] Size/width of the symbol in pixels
	 * @property {number} [oob.sides=3] Number of sides for a n-polygon (3 for triangle)
	 *//**
	 * @typedef {object} ComponentBox~MajorReference
	 * @property {string} start Reference to the data property of the start value along the major axis
	 * @property {string} end Reference to the data property of the end value along the major axis
	 *//**
	 * @typedef {object} ComponentBox.data
	 * @property {number} [min] Min
	 * @property {number} [max] Max
	 * @property {number} [start] Start of box
	 * @property {number} [end] End of box
	 * @property {number} [med] Median
	 */const DEFAULT_ERROR_SETTINGS={errorShape:{shape:'saltire',width:2,size:0.5,fill:'#333',stroke:'#333',strokeWidth:0}};const PX_RX=/px$/;/**
	 * Component settings
	 * @typedef {object=}
	 * @alias ComponentPoint.settings
	 */const DEFAULT_DATA_SETTINGS$1={/** Type of shape
	   * @type {DatumString=} */shape:'circle',/** Label
	   * @type {DatumString=} */label:'',/** Fill color
	   * @type {DatumString=} */fill:'#333',/** Stroke color
	   * @type {DatumString=} */stroke:'#ccc',/** Stroke dash array
	   * @type {DatumString=} */strokeDasharray:'',/** Stroke width
	   * @type {DatumNumber=} */strokeWidth:0,/** Stroke line join
	   * @type {DatumString=} */strokeLinejoin:'miter',/** Opacity of shape
	   * @type {DatumNumber=} */opacity:1,/** Normalized x coordinate
	   * @type {DatumNumber=} */x:0.5,/** Normalized y coordinate
	   * @type {DatumNumber=} */y:0.5,/** Normalized size of shape
	   * @type {DatumNumber=} */size:1,/** Whether or not to show the point
	   * @type {DatumBoolean=} */show:true};/**
	 * @typedef {object=}
	 * @alias ComponentPoint.settings.sizeLimits
	 */const SIZE_LIMITS={/** Maximum size of shape, in pixels
	   * @type {number=} */maxPx:10000,/** Minimum size of shape, in pixels
	   * @type {number=} */minPx:1,/** Maximum size relative linear scale extent
	   * @type {number=} */maxRelExtent:0.1,/** Minimum size relative linear scale extent
	   * @type {number=} */minRelExtent:0.01,/** Maximum size relative discrete scale banwidth
	   * @type {number=} */maxRelDiscrete:1,/** Minimum size relative discrete scale banwidth
	   * @type {number=} */minRelDiscrete:0.1};function getPxSpaceFromScale(s,space){if(s&&typeof s.bandwidth==='function'){// some kind of ordinal scale
	return {isBandwidth:true,value:Math.max(1,s.bandwidth()*space)};}return {isBandwidth:false,value:Math.max(1,space)};}function getPointSizeLimits(x,y,width,height,limits){const xSpacePx=getPxSpaceFromScale(x?x.scale:undefined,width);const ySpacePx=getPxSpaceFromScale(y?y.scale:undefined,height);let maxSizePx=Math.min(xSpacePx.value*limits[xSpacePx.isBandwidth?'maxRelDiscrete':'maxRelExtent'],ySpacePx.value*limits[ySpacePx.isBandwidth?'maxRelDiscrete':'maxRelExtent']);let minSizePx=Math.min(xSpacePx.value*limits[xSpacePx.isBandwidth?'minRelDiscrete':'minRelExtent'],ySpacePx.value*limits[ySpacePx.isBandwidth?'minRelDiscrete':'minRelExtent']);const min=Math.max(1,Math.floor(minSizePx));const max=Math.max(1,Math.floor(maxSizePx));return {min,max,maxGlobal:limits.maxPx,minGlobal:limits.minPx};}function getType(s){let type=DEFAULT_DATA_SETTINGS$1.shape;let props={};if(typeof s.shape==='object'&&typeof s.shape.type==='string'){type=s.shape.type;props=s.shape;}else if(typeof s.shape==='string'){type=s.shape;}return [type,props];}function createDisplayPoints(dataPoints,_ref,pointSize,shapeFn){let{width,height}=_ref;return dataPoints.filter(p=>p.show!==false&&!isNaN(p.x+p.y)).map(p=>{let s=p;let size=PX_RX.test(p.size)?parseInt(p.size,10):pointSize.min+s.size*(pointSize.max-pointSize.min);if(notNumber(size)){s=DEFAULT_ERROR_SETTINGS.errorShape;size=pointSize.min+s.size*(pointSize.max-pointSize.min);}const[type,typeProps]=getType(s);const shapeSpec=_objectSpread2$1(_objectSpread2$1({},typeProps),{},{type,label:p.label,x:p.x*width,y:p.y*height,fill:s.fill,size:Math.min(pointSize.maxGlobal,Math.max(pointSize.minGlobal,size)),stroke:s.stroke,strokeWidth:s.strokeWidth,strokeDasharray:s.strokeDasharray,opacity:s.opacity});if(s===p.errorShape){shapeSpec.width=s.width;}const shape=shapeFn(shapeSpec);shape.data=p.data;return shape;});}const component$2={require:['chart','resolver','symbol'],defaultSettings:{settings:{},data:{},animations:{enabled:false,trackBy:node=>node.data.value},style:{item:'$shape'}},render(_ref2){let{data}=_ref2;const resolved=this.resolver.resolve({data,defaults:extend$1$1({},DEFAULT_DATA_SETTINGS$1,this.style.item),settings:this.settings.settings,scaled:{x:this.rect.width,y:this.rect.height}});const{width,height}=this.rect;const limits=extend$1$1({},SIZE_LIMITS,this.settings.settings.sizeLimits);const points=resolved.items;const pointSize=getPointSizeLimits(resolved.settings.x,resolved.settings.y,width,height,limits);return createDisplayPoints(points,this.rect,pointSize,this.settings.shapeFn||this.symbol);}};/**
	 * @typedef {object} ComponentPoint
	 * @property {'point'} type component type
	 * @extends ComponentSettings
	 * @example
	{
	  type: 'point',
	  data: {
	    extract: {
	      field: 'Month',
	      props: {
	        x: { field: 'Margin' },
	        y: { field: 'Year' }
	      }
	    }
	  },
	  settings: {
	    x: { scale: 'm' },
	    y: { scale: 'y' },
	  }
	}
	 */const type$3='point';function pointMarker$1(picasso){picasso.component(type$3,component$2);picasso.component('point-marker',component$2);// temporary backwards compatibility - DEPRECATED
	}/**
	 * Component settings
	 * @typedef {object}
	 * @alias ComponentPie.settings
	 */const DEFAULT_DATA_SETTINGS={/**
	   * @typedef {object}
	   */slice:{label:'',/** Absolute value of the slice's arc length
	     * @type {number=} */arc:1,/** Visibility of the slice
	     * @type {boolean=} */show:true,/** Fill color of the slice
	     * @type {string=} */fill:'#333',/** Stroke color of the slice
	     * @type {string=} */stroke:'#ccc',/** Stroke width of the slice
	     * @type {number=} */strokeWidth:1,/** Stroke line join
	     * @type {string=} */strokeLinejoin:'round',/** Opacity of the slice
	     * @type {number=} */opacity:1,/** Inner radius of the slice
	     * @type {number=} */innerRadius:0,/** Outer radius of the slice
	     * @type {number=} */outerRadius:0.8,/** Corner radius of the slice, in pixels
	     * @type {number=} */cornerRadius:0,/** Radial offset of the slice
	     * @type {number=} */offset:0}};/**
	 * @typedef {object} ComponentPie
	 * @extends ComponentSettings
	 * @property {'pie'} type component type
	 * @example
	 * {
	 *   type: 'pie',
	 *   data: {
	 *     extract: {
	 *       field: 'Region',
	 *       props: {
	 *         num: { field: 'Population' }
	 *       }
	 *     }
	 *   },
	 *   settings: {
	 *     startAngle: Math.PI / 2,
	 *     endAngle: -Math.PI / 2,
	 *     slice: {
	 *       arc: { ref: 'num' },
	 *       fill: 'green',
	 *       stroke: 'red',
	 *       strokeWidth: 2,
	 *       strokeLinejoin: 'round',
	 *       innerRadius: 0.6,
	 *       outerRadius 0.8,
	 *       opacity: 0.8,
	 *       offset: 0.2
	 *     }
	 *   }
	 * }
	 */function offsetSlice(centroid,offset,outerRadius,innerRadius){let[vx,vy]=centroid;const vlen=Math.sqrt(vx*vx+vy*vy);vx/=vlen;vy/=vlen;const diff=outerRadius-innerRadius;return {x:vx*offset*diff,y:vy*offset*diff};}function createDisplayPies(arcData,_ref,slices,sum){let{x,y,width,height}=_ref;const arcGen=arc();const center={x:x+width/2,y:y+height/2};const innerRadius=Math.min(width,height)/2;const outerRadius=Math.min(width,height)/2;const cornerRadius=outerRadius/100;return arcData.map((a,i)=>{const slice=slices[i];slice.type='path';const or=outerRadius*slice.outerRadius;const ir=innerRadius*slice.innerRadius;const cr=cornerRadius*slice.cornerRadius;arcGen.innerRadius(ir);arcGen.outerRadius(or);arcGen.cornerRadius(cr);slice.arcDatum=a;const centroid=arcGen.centroid(a);const offset=slice.offset?offsetSlice(centroid,slice.offset,or,ir):{x:0,y:0};slice.transform="translate(".concat(offset.x,", ").concat(offset.y,") translate(").concat(center.x,", ").concat(center.y,")");slice.desc={share:a.value/sum,slice:{start:a.startAngle,end:a.endAngle,innerRadius:ir,outerRadius:or,cornerRadius:cr,offset:{x:center.x+offset.x,y:center.y+offset.y}}};return slice;});}function arcValue(stngs,item){if(stngs.slice&&'arc'in stngs.slice){return item.arc;}return item.data.value;}const pieComponent={require:['chart','resolver'],defaultSettings:{settings:{startAngle:0,endAngle:2*Math.PI,padAngle:0,slice:{}},style:{slice:'$shape'},data:{}},render(_ref2){let{data}=_ref2;const arcValues=[];const slices=[];const stngs=this.settings.settings;const{items}=this.resolver.resolve({data,defaults:extend$1$1({},DEFAULT_DATA_SETTINGS.slice,this.style.slice),settings:stngs.slice});let sum=0;for(let i=0,len=items.length;i<len;i++){const val=arcValue(stngs,items[i]);if(val>0&&items[i].outerRadius>=items[i].innerRadius){arcValues.push(val);slices.push(items[i]);sum+=val;}}const pieGen=pie$1().sortValues(null);pieGen.startAngle(stngs.startAngle);pieGen.endAngle(stngs.endAngle);pieGen.padAngle(stngs.padAngle);const arcData=pieGen(arcValues);return createDisplayPies(arcData,extend$1$1({},this.rect,{x:0,y:0}),slices,sum);}};function pie(picasso){picasso.component('pie',pieComponent);}/**
	 * Create a crispifier
	 * @ignore
	 *
	 * @param  {Object} [crispMap] Optional crispmap if you need custom crisping.
	 * @return {Function}          crispItem function
	 *
	 * @example
	 * import { crispifierFactory } from "core/crispifier";
	 *
	 * let crispify = crispifierFactory(customCrispMap);
	 *
	 * // For a single item
	 * crispify(myItem);
	 *
	 * // For multiple items
	 * crispify.multiple(myArrayOfItems);
	 */function crispifierFactory(crispMap){// Define the crispMap
	if(crispMap===undefined){crispMap={};crispMap.line={append:['x1','x2','y1','y2'],round:[],condition:item=>item.x1===item.x2||item.y1===item.y2,conditionAppend:item=>item.strokeWidth%2!==0};crispMap.rect={append:['x','y'],round:['width','height'],condition:()=>true,conditionAppend:item=>item.strokeWidth%2!==0};}// Re-map the crispmap
	Object.keys(crispMap).forEach(type=>{const self=crispMap[type];self.items=[];self.append.forEach(toAppend=>{self.items.push({key:toAppend,type:'append'});});self.round.forEach(toAppend=>{self.items.push({key:toAppend,type:'round'});});});/**
	   * Crispify a single item
	   * @ignore
	   * @param  {Object} item  Item with renderer variables such as X, Y, and type.
	   * @return {Undefined}    Returns nothing, modifies the original item instead
	   */function crispItem(item){if(crispMap[item.type]&&crispMap[item.type].condition(item)){const self=crispMap[item.type];const doAppend=self.conditionAppend===undefined||self.conditionAppend(item);self.items.forEach(i=>{const rounded=Math.round(item[i.key]);const diff=item[i.key]-rounded;item[i.key]=rounded;if(doAppend&&i.type==='append'){if(diff>0){item[i.key]+=0.5;}else {item[i.key]-=0.5;}}});}}/**
	   * Crispify multiple items
	   * @ignore
	   *
	   * @param  {Array} items  Array of objects to crispify
	   * @return {Undefined}    Returns nothing, modifies the original item instead
	   */crispItem.multiple=items=>items.forEach(item=>crispItem(item));return crispItem;}const crispifier=crispifierFactory();class Transposer{/**
	   * @private
	   */constructor(){this.reset();this.push(...arguments);}/**
	   * Evaluate a key for a transposed coordinate
	   *
	   * @param  {String} key   Key
	   * @return {String}         Actual key
	   */static evaluateKey(key,flipXY){if(flipXY){const firstChar=key.substring(0,1);const rest=key.substring(1);if(firstChar==='x'){return "y".concat(rest);}if(firstChar==='y'){return "x".concat(rest);}if(key==='cx'){return 'cy';}if(key==='cy'){return 'cx';}if(key==='width'){return 'height';}if(key==='height'){return 'width';}}return key;}/**
	   * Transpose a coordinate according to this.flipXY and
	   * the available rendering area
	   *
	   * @param  {String} key        The key of the coordinate to transpose
	   * @param  {Number} coordinate The coordinate
	   * @return {Number}            The actual location of the coordinate
	   */transposeCoordinate(key,coordinate,flipXY){if(typeof coordinate==='number'&&isFinite(coordinate)){const firstChar=key.substring(0,1);if(firstChar==='x'||key==='cx'){return coordinate*this.width;}if(key==='width'){return coordinate*this.width;}if(key==='r'){return coordinate*(!flipXY?this.width:this.height);}if(firstChar==='y'||key==='cy'){return coordinate*this.height;}if(key==='height'){return coordinate*this.height;}}return coordinate;}/**
	   * Push an item into the storage of the transposer
	   *
	   * @param  {Object} items An item to be drawed
	   * @return {Object}       Can be chained
	   */push(){this.storage.push(...arguments);return this;}processItem(item){let newItem={};const flipXY=typeof item.flipXY!=='undefined'?item.flipXY:this.flipXY;const crisp=typeof item.crisp!=='undefined'?item.crisp:this.crisp;if(item.fn&&typeof item.fn==='function'){let width=flipXY?this.height:this.width;let height=flipXY?this.width:this.height;item=item.fn({width,height,flipXY});const objectKeys=Object.keys(item);for(let ki=0,kl=objectKeys.length;ki<kl;ki++){let key=objectKeys[ki];const nkey=Transposer.evaluateKey(key,flipXY);newItem[nkey]=item[key];}}else {const objectKeys=Object.keys(item);for(let ki=0,kl=objectKeys.length;ki<kl;ki++){let key=objectKeys[ki];const nkey=Transposer.evaluateKey(key,flipXY);const nval=this.transposeCoordinate(nkey,item[key],flipXY);newItem[nkey]=nval;}}if(crisp){crispifier(newItem);}return newItem;}/**
	   * Get the output of the transposer
	   *
	   * @return {Array}   Array of objects
	   */output(){let items=[];for(let i=0,l=this.storage.length;i<l;i++){let newItem=this.processItem(this.storage[i]);items.push(newItem);}return items;}/**
	   * Reset the transposer
	   *
	   * @return {Undefined}  Does not return anything
	   */reset(){this.storage=[];this.flipXY=false;this.crisp=false;this.width=0;this.height=0;}}function transposer(){for(var _len=arguments.length,items=new Array(_len),_key=0;_key<_len;_key++){items[_key]=arguments[_key];}return new Transposer(...items);}/**
	 * Generate array of lines (ticks) from scale
	 *
	 * @param {object} scale - A scale supplied by the chart
	 * @param {object} settings - The settings object from the grid line component
	 * @param {object} rect - The rect containing width and height to renderer in
	 * @returns {array} - Returns an array of ticks
	 * @ignore
	 */function lineGen(scale,distance){if(!scale||!distance){return [];}return scale.cachedTicks&&scale.cachedTicks()||scale.ticks({distance});}const gridLineComponent={created(){},require:['chart','renderer','resolver'],defaultSettings:{layout:{displayOrder:0},style:{// Theming style
	ticks:'$guide-line',minorTicks:'$guide-line--minor'}},beforeRender(){this.blueprint=transposer();this.blueprint.width=this.rect.width;this.blueprint.height=this.rect.height;this.blueprint.x=this.rect.x;this.blueprint.y=this.rect.y;this.blueprint.crisp=true;},render(){// Setup scales
	this.x=this.settings.x?this.chart.scale(this.settings.x):null;this.y=this.settings.y?this.chart.scale(this.settings.y):null;updateScaleSize(this,'x',this.rect.width);updateScaleSize(this,'y',this.rect.height);// Return an empty array to abort rendering when no scales are available to renderer
	if(!this.x&&!this.y){return [];}this.settings.ticks=extend$1$1({show:true},this.style.ticks,this.settings.ticks||{});this.settings.minorTicks=extend$1$1({show:false},this.style.minorTicks,this.settings.minorTicks||{});// Setup lines for X and Y
	this.lines={x:[],y:[]};// Use the lineGen function to generate appropriate ticks
	this.lines.x=lineGen(this.x,this.rect.width);this.lines.y=lineGen(this.y,this.rect.height);// Set all Y lines to flipXY by default
	// This makes the transposer flip them individually
	this.lines.y=this.lines.y.map(i=>extend$1$1(i,{flipXY:true}));let addTicks=_ref=>{let{dir,isMinor}=_ref;let items=this.lines[dir].filter(tick=>!!tick.isMinor===isMinor);let settings=isMinor?this.settings.minorTicks:this.settings.ticks;let ticks=this.resolver.resolve({settings,data:{items,dir}}).items;ticks.forEach(style=>{let p=style.data;// If the style's show is falsy, don't renderer this item (to respect axis settings).
	if(style.show){var _p$value,_p$data;// Use the transposer to handle actual positioning
	this.blueprint.push({type:'line',x1:p.position,y1:0,x2:p.position,y2:1,stroke:style.stroke||'black',strokeWidth:typeof style.strokeWidth!=='undefined'?style.strokeWidth:1,strokeDasharray:typeof style.strokeDasharray!=='undefined'?style.strokeDasharray:undefined,flipXY:p.flipXY||false,// This flips individual points (Y-lines)
	value:(_p$value=p.value)!==null&&_p$value!==void 0?_p$value:(_p$data=p.data)===null||_p$data===void 0?void 0:_p$data.value,dir});}});};addTicks({dir:'x',isMinor:false});addTicks({dir:'x',isMinor:true});addTicks({dir:'y',isMinor:false});addTicks({dir:'y',isMinor:true});return this.blueprint.output();}};/**
	 * @typedef {object} ComponentGridLine
	 * @extends ComponentSettings
	 * @property {'grid-line'} type component type
	 * @example
	 * {
	 *  type: 'grid-line',
	 *  settings: {
	 *    x: {
	 *      scale: '<name-of-scale>',
	 *    },
	 *    y: {
	 *      scale: '<name-of-scale>',
	 *    },
	 *  },
	 * }
	 *//**
	 * Component settings
	 * @typedef {object} ComponentGridLine.settings
	 * @property {object} x
	 * @property {string} x.scale - The scale to use along x
	 * @property {object} y
	 * @property {string} y.scale - The scale to use along y
	 * @property {object} [ticks]
	 * @property {boolean} [ticks.show=true]
	 * @property {string} [ticks.stroke='black']
	 * @property {number} [ticks.strokeWidth='1']
	 * @property {string} [ticks.strokeDasharray]
	 * @property {object} [minorTicks]
	 * @property {boolean} [minorTicks.show=true]
	 * @property {string} [minorTicks.stroke='black']
	 * @property {number} [minorTicks.strokeWidth='1']
	 * @property {string} [minorTicks.strokeDasharray]
	 */function gridLine$1(picasso){picasso.component('grid-line',gridLineComponent);}/**
	 * Return a D property for a SVG path to get a direction marker
	 *
	 * @param {number} x - X coordinate
	 * @param {number} y - Y coordinate
	 * @param {number} r - Radius
	 * @param {string} [d='bottom'] - Direction
	 * @returns {string} - Finished D property
	 * @ignore
	 */function directionMarker(x,y,r){let d=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'bottom';r*=0.8;if(d==='left'||d==='right'){let right=d==='right';return "\n      M ".concat(x," ").concat(y-r,"\n      A ").concat(r*1.25," ").concat(r*1.25,", 0, 1, ").concat(right?0:1,", ").concat(x," ").concat(y+r,"\n      L ").concat(right?x+r:x-r," ").concat(y," Z\n    ");}let bottom=d==='bottom';return "\n    M ".concat(x-r," ").concat(y,"\n    A ").concat(r*1.25," ").concat(r*1.25,", 0, 1, ").concat(bottom?1:0,", ").concat(x+r," ").concat(y,"\n    L ").concat(x," ").concat(bottom?y+r:y-r," Z\n  ");}function directionTriangle(x,y,r){let d=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'bottom';r*=0.75;if(d==='left'||d==='right'){let right=d==='right';x+=right?r*1.5:-(r*1.5);return "\n      M ".concat(x," ").concat(y-r,"\n      L ").concat(x," ").concat(y+r,"\n      L ").concat(right?x+r:x-r," ").concat(y," Z\n    ");}let bottom=d==='bottom';y+=bottom?r*1.5:-(r*1.5);return "\n    M ".concat(x-r," ").concat(y,"\n    L ").concat(x+r," ").concat(y,"\n    L ").concat(x," ").concat(bottom?y+r:y-r," Z\n  ");}/**
	 * Handle out of bound shapes
	 * Does not return anything, modifies "items" property instead (should be re-considered)
	 *
	 * @param {object} oob - Out of bounds object from parent
	 * @param {object} settings - Settings object from parent
	 * @param {object[]} items - Array of all items (for collision detection)
	 * @ignore
	 */function oobManager(_ref){let{blueprint,oob,settings,items}=_ref;const oobKeys=Object.keys(oob);let style=settings.style.oob||{};for(let i=0,len=oobKeys.length;i<len;i++){const key=oobKeys[i];const value=oob[key];if(value.length>0){let position=key.charAt(1);let flipXY=key.charAt(0)==='y';let xPadding=style.padding.x+style.width;let yPadding=style.padding.y+style.width;let direction='bottom';if(flipXY){direction=position==='1'?'bottom':'top';}else {direction=position==='1'?'right':'left';}let indicator=blueprint.processItem({fn:_ref2=>{let{width,height}=_ref2;/* eslint no-loop-func: 0 */let x=position*width+(position==='1'?-xPadding:xPadding);let y=flipXY?yPadding:height-yPadding;if(style.type==='arc'){return {type:'path',d:directionMarker(flipXY?y:x,flipXY?x:y,style.width,direction),x,y,stroke:style.stroke,fill:style.fill,strokeWidth:style.strokeWidth||0};}return {type:'circle',cx:x,cy:y,r:style.width,stroke:style.stroke,fill:style.fill,strokeWidth:style.strokeWidth||0,opacity:style.opacity,data:value};},flipXY});let x=indicator.cx||indicator.x;let y=indicator.cy||indicator.y;const tooltips=value.map(v=>v.label?"".concat(v.label," (").concat(v.value,")"):"(".concat(v.value,")"));const title=tooltips.reduce((text,current,index)=>index===0?current:"".concat(text,"\n\n").concat(current),'');let text={type:'text',text:value.length||'',title,x:x-style.width*0.4,y:y+style.width*0.4,fontFamily:style.text.fontFamily,fontSize:"".concat(style.width*1.3,"px"),stroke:style.text.stroke,fill:style.text.fill,strokeWidth:style.text.strokeWidth||0,opacity:style.text.opacity};let triangle={type:'path',d:directionTriangle(x,y,style.width,direction),x,y,stroke:style.triangle.stroke,fill:style.triangle.fill,strokeWidth:style.triangle.strokeWidth||0,opacity:style.triangle.opacity};items.push(indicator,text,triangle);}}}function isOob(value,min,max){return value<min||value>max;}const DOCK_CORNER=0.8;function refLabelDefaultSettings(){return {fill:'#000',fontFamily:'Arial',fontSize:'12px',opacity:1,maxWidth:1,maxWidthPx:9999,padding:5,background:{fill:'#fff',stroke:'transparent',strokeWidth:0,opacity:0.5}};}function isMaxY(chart,slope,value){// when maxY exceeds the shown scale
	const scaleX=chart.scale({scale:'x'});const scaleY=chart.scale({scale:'y'});if(slope>0){const maxY=scaleX.max()*slope+value;if(maxY>=scaleY.max()){return true;}}else if(slope<0){const minY=scaleX.min()*slope+value;if(minY>=scaleY.max()){return true;}}return false;}function getMaxXPosition(chart,slope,value){// if maxY then get maxX position available on the scale
	const scaleX=chart.scale({scale:'x'});const scaleY=chart.scale({scale:'y'});// For negative slopes
	if(slope<0){return scaleX((scaleY.max()-value)/slope);}// For positive slopes
	return scaleX((scaleY.max()-value)/slope);}function getFormatter(p,chart){if(typeof p.formatter==='string'){return chart.formatter(p.formatter);}if(typeof p.formatter==='object'){return chart.formatter(p.formatter);}if(typeof p.scale!=='undefined'&&p.scale.data){// TODO - Add support for array as source into formatter
	const scaleData=p.scale.data()&&p.scale.data().fields;return scaleData&&scaleData[0]?scaleData[0].formatter():null;}return null;}function isColliding(items,slopeValue,measured,xPadding,yPadding){for(let i=0,len=items.length;i<len;i++){const curItem=items[i];if((curItem===null||curItem===void 0?void 0:curItem.type)==='text'){if(Math.abs(curItem.x-slopeValue.x)<Math.max(curItem.width+xPadding,slopeValue.width+xPadding)&&Math.abs(curItem.y-slopeValue.y)<measured.height+yPadding){return true;}}}return false;}function calculateX(slopeLine,line,maxX,measured,blueprint,slopeStyle){let neededPadding=0;// calculate x for the various scenarios possible
	if(maxX!==undefined){// docking at top
	if(maxX<DOCK_CORNER){neededPadding=slopeLine.slope<0||slopeLine.isRtl?slopeStyle.padding*3:slopeStyle.padding*2;return slopeLine.isRtl?maxX*blueprint.width+neededPadding:maxX*blueprint.width+neededPadding;}if(maxX===1){// dock at the corner of the data area top and right
	return slopeLine.isRtl?maxX*blueprint.width-(measured.width+slopeStyle.padding*3):maxX*blueprint.width-(measured.width+slopeStyle.padding*6);}if(maxX>DOCK_CORNER){// very close to the corner when width doesn't fit
	return slopeLine.isRtl?maxX*blueprint.width-(measured.width+slopeStyle.padding*3):maxX*blueprint.width-(measured.width+slopeStyle.padding*6);}}else if(slopeLine.slope>0){// dock at right
	return line.x2-(measured.width+slopeStyle.padding*2);}//  Negative slope dock on left
	return slopeLine.isRtl?line.x1-(measured.width+slopeStyle.padding*2):line.x1;}/**
	 * Converts a numerical OR string value to a normalized value
	 *
	 * @param {string|number} align -Description how to align (Numerical from 0-1 or 'top', 'left', 'center', 'middle', 'bottom' or 'right')
	 * @returns {number} - Normalized value 0...1
	 * @ignore
	 */function alignmentToNumber(align){if(typeof align==='undefined'){return 0;}if(typeof align==='number'&&isFinite(align)){return align;}if(typeof align==='string'){switch(align){case 'center':case 'middle':return 0.5;case 'bottom':case 'right':return 1;case 'top':case 'left':default:return 0;}}return 0;}/**
	 * Create line and label (if applicable)
	 * Does not return anything, modifies "items" property instead (should be re-considered)
	 *
	 * @param {object} p - Current point
	 * @param {object} style - Applicable line styling
	 * @param {object} settings - Settings object derived from parent
	 * @param {object[]} items - Array of all items (for collision detection)
	 * @ignore
	 */function createLineWithLabel(_ref){var _slopeLine$label,_slopeLine$label2;let{chart,blueprint,renderer,p,settings,items,slopeLine}=_ref;let doesNotCollide=true;let line=false;let rect=false;let label=false;let value=false;let style=extend$1$1(true,{},settings.style.line,p.line||{});let slopeStyle=extend$1$1(true,refLabelDefaultSettings(),settings.style.label||{},{fill:style.stroke});// Use the transposer to handle actual positioning
	if(slopeLine){line=blueprint.processItem({type:'line',x1:slopeLine.x1,y1:slopeLine.y1,x2:slopeLine.x2,y2:slopeLine.y2,stroke:style.stroke||'black',strokeWidth:style.strokeWidth||1,strokeDasharray:style.strokeDasharray,flipXY:false,value:p.valueInfo?p.valueInfo.id:p.value});}else {line=blueprint.processItem({type:'line',x1:p.position,y1:0,x2:p.position,y2:1,stroke:style.stroke||'black',strokeWidth:style.strokeWidth||1,strokeDasharray:style.strokeDasharray,flipXY:p.flipXY||false,// This flips individual points (Y-lines)
	value:p.valueInfo?p.valueInfo.id:p.value});}if(p.label&&p.label.show!==false&&!(slopeLine!==null&&slopeLine!==void 0&&slopeLine.slope&&slopeLine.slope!==0)){const item=extend$1$1(true,refLabelDefaultSettings(),settings.style.label||{},{fill:style.stroke},p.label);let formatter;let measuredValue={width:0,height:0};let valueString='';formatter=getFormatter(p,chart);if(p.label.showValue!==false){if(formatter){valueString=" (".concat(formatter(p.value),")");}else if(p.scale){valueString=" (".concat(p.value,")");}}if(valueString){measuredValue=renderer.measureText({text:valueString,fontFamily:item.fontFamily,fontSize:item.fontSize});}// Measure the label text
	let measuredLabel=renderer.measureText({text:item.text||'',fontFamily:item.fontFamily,fontSize:item.fontSize});let measured={width:measuredLabel.width+measuredValue.width,height:Math.max(measuredLabel.height,measuredValue.height)};let labelPadding=item.padding;// let anchor = item.anchor === 'end' ? 'end' : 'start';
	let align=alignmentToNumber(p.flipXY?item.vAlign:item.align);let vAlign=alignmentToNumber(p.flipXY?item.align:item.vAlign);let calcWidth=Math.min(1+measured.width+labelPadding*2,item.maxWidth*blueprint.width,item.maxWidthPx);let calcHeight=measured.height+labelPadding*2;let rectWidth=p.flipXY?calcHeight:calcWidth;let rectHeight=p.flipXY?calcWidth:calcHeight;rect=blueprint.processItem({fn:_ref2=>{let{width,height}=_ref2;let x=p.position*width-(p.flipXY?calcHeight:calcWidth)*(1-align);x=p.flipXY?x:Math.max(x,0);const y=Math.max(Math.abs(vAlign*height-rectHeight*vAlign),0);return {type:'rect',x,y,width:p.flipXY?rectWidth:Math.min(rectWidth,blueprint.width-x),height:rectHeight,stroke:item.background.stroke,strokeWidth:item.background.strokeWidth,fill:item.background.fill,opacity:item.background.opacity};},flipXY:p.flipXY||false// This flips individual points (Y-lines)
	});if(rect.x<-1||rect.x+rect.width>blueprint.width+1||rect.y<-1||rect.y+rect.height>blueprint.height+1){// do not create labels if out of bounds
	rect=undefined;}else {// Labels are just basic objects attached to a corner of a rect,
	// and this rect needs to already be processed
	// so there is no blueprint.processItem required here
	label={type:'text',text:item.text||'',fill:item.fill,opacity:item.opacity,fontFamily:item.fontFamily,fontSize:item.fontSize,x:rect.x+labelPadding,y:rect.y+rect.height/2+measured.height/3,maxWidth:rect.width-labelPadding*2-measuredValue.width,anchor:'start'};if(valueString){value={type:'text',text:valueString||'',fill:item.fill,opacity:item.opacity,fontFamily:item.fontFamily,fontSize:item.fontSize,x:label.x+3+(rect.width-(measuredValue.width+labelPadding*2)),y:label.y};}// Detect collisions with other labels/rects or lines
	for(let i=0,len=items.length;i<len;i++){let curItem=items[i];if(curItem.type==='rect'){// We only detect rects here, since rects are always behind labels,
	// and we wouldn't want to measure text one more time
	if(testRectRect(rect,curItem)){doesNotCollide=false;}}else if(curItem.type==='line'){// This will only collide when flipXY are the same for both objects,
	// So it only collides on objects on the same "axis"
	if(p.flipXY===curItem.flipXY&&testRectLine(rect,curItem)){doesNotCollide=false;}}}}}// Always push the line,
	// but this is done after collision detection,
	// because otherwise it would collide with it's own line
	// check for slopeline if the points are almost on the blueprints edge
	if(line){items.push(line);}if(slopeLine&&slopeLine.slope!==0&&(((_slopeLine$label=slopeLine.label)===null||_slopeLine$label===void 0?void 0:_slopeLine$label.show)!==false||((_slopeLine$label2=slopeLine.label)===null||_slopeLine$label2===void 0?void 0:_slopeLine$label2.showValue)!==false)){var _slopeLine$label3,_slopeLine$label4,_slopeLine$label5;// create data area labels for slope line
	let valueString;let labelBackground;const maxLabelWidth=120;let slopeLabelText=((_slopeLine$label3=slopeLine.label)===null||_slopeLine$label3===void 0?void 0:_slopeLine$label3.show)!==false?(_slopeLine$label4=slopeLine.label)===null||_slopeLine$label4===void 0?void 0:_slopeLine$label4.text:'';if(((_slopeLine$label5=slopeLine.label)===null||_slopeLine$label5===void 0?void 0:_slopeLine$label5.showValue)!==false){var _slopeLine$label6;const formatter=getFormatter(p,chart);const formattedValue=formatter?formatter(slopeLine.value):slopeLine.value;valueString="(".concat(slopeLine.slope,"x + ").concat(formattedValue,")");slopeLabelText+=(_slopeLine$label6=slopeLine.label)!==null&&_slopeLine$label6!==void 0&&_slopeLine$label6.text?" ".concat(valueString):valueString;}if(slopeLabelText.length>1){var _slopeLine$label7,_slopeLine$label$stro,_slopeLine$label8;// Measure the label text
	const measured=renderer.measureText({text:slopeLabelText,fontFamily:slopeStyle.fontFamily,fontSize:slopeStyle.fontSize});measured.width=measured.width>maxLabelWidth?maxLabelWidth:measured.width;const maxX=isMaxY(chart,slopeLine.slope,slopeLine.value)?getMaxXPosition(chart,slopeLine.slope,slopeLine.value):undefined;const xPadding=maxX!==undefined&&!slopeLine.isRtl?slopeStyle.padding*3:slopeStyle.padding;const yPadding=maxX!==undefined||slopeLine.slope>0?slopeStyle.padding*3:slopeStyle.padding;const x=calculateX(slopeLine,line,maxX,measured,blueprint,slopeStyle);const y=Math.min(line.y1,line.y2);// if coloredBackground is true make a rect
	if((_slopeLine$label7=slopeLine.label)!==null&&_slopeLine$label7!==void 0&&_slopeLine$label7.stroke){labelBackground={type:'rect',x:slopeLine.isRtl?Math.max(x,xPadding)-2:Math.max(x,xPadding)+2,y:Math.abs(Math.max(y,yPadding)-measured.height),rx:3,ry:3,width:measured.width+slopeStyle.padding,height:measured.height-2,stroke:style.stroke,fill:style.stroke};}const slopeLabel={type:'text',text:slopeLabelText,fill:(_slopeLine$label$stro=(_slopeLine$label8=slopeLine.label)===null||_slopeLine$label8===void 0?void 0:_slopeLine$label8.stroke)!==null&&_slopeLine$label$stro!==void 0?_slopeLine$label$stro:style.stroke,opacity:slopeStyle.opacity,fontFamily:slopeStyle.fontFamily,fontSize:slopeStyle.fontSize,x:labelBackground?labelBackground.x+2:Math.max(x,xPadding)+2,y:labelBackground?labelBackground.y+measured.height-slopeStyle.padding:Math.abs(Math.max(y,yPadding)-slopeStyle.padding/2),anchor:'start',title:slopeLabelText,maxWidth:maxLabelWidth,width:measured.width};if(!isColliding(items,slopeLabel,measured,xPadding,yPadding)){if(labelBackground){items.push(labelBackground);}items.push(slopeLabel);}}}// Only push rect & label if we haven't collided and both are defined
	if(doesNotCollide&&rect&&label){items.push(rect,label);if(value){items.push(value);}}}function createOobData(line){const data={value:line.value};if(line.label){data.label=line.label.text;}return data;}function filterUndefinedValue(line){const value=typeof line.value==='function'?line.value():line.value;return typeof value!=='undefined';}function isInvert(scale){const range=scale.range();return (range===null||range===void 0?void 0:range.length)===2&&range[0]>range[1];}function getPosition(scale,value){const min=scale.min();const max=scale.max();if(min===max){const invert=isInvert(scale);if(value<min){return invert?2:-1;}if(value>min){return invert?-1:2;}}return scale(value);}const EPSILON$2=1e-15;function isIdentical(p1,p2){return p1&&p2&&Math.abs(p1.x-p2.x)<EPSILON$2&&Math.abs(p1.y-p2.y)<EPSILON$2;}function removeDuplication(intersections){if(isIdentical(intersections[0],intersections[1])){intersections[1]=undefined;}if(isIdentical(intersections[1],intersections[2])){intersections[2]=undefined;}if(isIdentical(intersections[2],intersections[3])){intersections[3]=undefined;}if(isIdentical(intersections[3],intersections[0])){intersections[3]=undefined;}}/**
	 * Component settings
	 * @typedef {object} ComponentRefLine.settings
	 * @property {object} lines - X & Y Lines
	 * @property {ComponentRefLine~Line[]} [lines.x=[]] - Reference lines along X axis
	 * @property {ComponentRefLine~Line[]} [lines.y=[]] - Reference lines along Y axis
	 *//**
	 * @private
	 * @typedef {object} ComponentRefLine.style
	 * @property {refline-oob-style} [oob=ComponentRefLine.style.oob] - Style for out of bounds object (oob)
	 * @property {ComponentRefLine~Line} [line=ComponentRefLine~Line] - Generic style for lines
	 * @property {ComponentRefLine~LineLabel} [label=ComponentRefLine~LineLabel] - Generic style for labels
	 *//**
	 * @typedef {object} ComponentRefLine.style.oob
	 * @property {boolean} [show=true] - Show out of bounds items
	 * @property {string} [type=undefined] - EXPERIMENTAL:  Set this to 'arc' for an experimental out of bounds shape (only works with SVG)
	 * @property {number} [width=10] - Width of the out of bounds object
	 * @property {string} [fill='#1A1A1A'] - Fill color of the OOB object
	 * @property {string} [stroke='transparent'] - Stroke of the OOB object
	 * @property {number} [strokeWidth=0] - Stroke width of the OOB object
	 * @property {number} [opacity=1] - Opacity of the OOB object
	 * @property {ComponentRefLine~GenericText} [text=ComponentRefLine~GenericText] - Text configuration for out of bounds
	 * @property {ComponentRefLine~GenericObject} [triangle=ComponentRefLine~GenericObject] - The triangle in OOB
	 * @property {object} [padding] - Padding on X
	 * @property {number} [padding.x=28] - Padding on X
	 * @property {number} [padding.y=5] - Padding on X
	 *//**
	 * @typedef {object} ComponentRefLine~GenericText
	 * @property {string} [text=''] - Text (if applicable)
	 * @property {string} [fontSize='12px'] - Font size (if applicable)
	 * @property {string} [fontFamily='Arial'] - Font family
	 * @property {string} [fill='#fff'] - Fill color
	 * @property {string} [stroke='transparent'] - Stroke
	 * @property {number} [strokeWidth=0] - Stroke width
	 * @property {string} [strokeDasharray] - Stroke dash array
	 * @property {number} [opacity=1] - Opacity
	 *//**
	 * @typedef {object} ComponentRefLine~Line
	 * @property {number|function} value - The value of the reference line. If a scale is specified, it is applied.
	 * @property {string} [scale] - Scale to use (if undefined will use normalized value 0-1)
	 * @property {ComponentRefLine~GenericObject} [line=ComponentRefLine~GenericObject] - The style of the line
	 * @property {ComponentRefLine~LineLabel} [label=ComponentRefLine~LineLabel] - The label style of the line
	 * @property {number} [slope=0] - The slope for the reference line
	 *//**
	 * @typedef {object} ComponentRefLine~LineLabel
	 * @property {number} padding=5 - Padding inside the label
	 * @property {string} [text=''] - Text
	 * @property {string} [fontSize='12px'] - Font size
	 * @property {string} [fontFamily='Arial'] - Font family
	 * @property {string} [stroke='transparent'] - Stroke
	 * @property {number} [strokeWidth=0] - Stroke width
	 * @property {number} [opacity=1] - Opacity
	 * @property {number|string} [align=0] - Alignment property left to right (0 = left, 1 = right). Also supports string ('left', 'center', 'middle', 'right')
	 * @property {number|string} [vAlign=0] - Alignment property top to bottom (0 = top, 1 = bottom). Also supports string ('top', 'center', 'middle', 'bottom')
	 * @property {number} [maxWidth=1] - The maximum relative width to the width of the rendering area (see maxWidthPx as well)
	 * @property {number} [maxWidthPx=9999] - The maximum width in pixels. Labels will be rendered with the maximum size of the smallest value of maxWidth and maxWidthPx size, so you may specify maxWidth 0.8 but maxWidthPx 100 and will never be over 100px and never over 80% of the renderable area
	 * @property {ComponentRefLine~LineLabelBackground} [background=ComponentRefLine~LineLabelBackground] - The background style (rect behind text)
	 * @property {boolean} [show=true] - Show label
	 * @property {boolean} [showValue=true] - Show value label
	 *//**
	 * @typedef {object} ComponentRefLine~LineLabelBackground
	 * @property {string} [fill='#fff'] - Fill color
	 * @property {string} [stroke='transparent'] - Stroke
	 * @property {number} [strokeWidth=0] - Stroke width
	 * @property {number} [opacity=0.5] - Opacity
	 *//**
	 * @typedef {object} ComponentRefLine~GenericObject
	 * @property {string} [fill='#fff'] - Fill color
	 * @property {string} [stroke='transparent'] - Stroke
	 * @property {number} [strokeWidth=0] - Stroke width
	 * @property {number} [opacity=1] - Opacity
	 */const refLineComponent={require:['chart','renderer'],defaultSettings:{layout:{displayOrder:0},style:{oob:{show:true,width:10,fill:'#1A1A1A',stroke:'transparent',strokeWidth:0,opacity:1,text:{fontFamily:'Arial',stroke:'transparent',fill:'#fff',strokeWidth:0,opacity:1},triangle:{fill:'#4D4D4D',stroke:'transparent',strokeWidth:0,opacity:1},padding:{x:28,y:5}},line:{stroke:'#000'},label:{strokeWidth:0}}},preferredSize(){return 30;},beforeRender(){this.blueprint=transposer();this.blueprint.width=this.rect.width;this.blueprint.height=this.rect.height;this.blueprint.x=this.rect.x;this.blueprint.y=this.rect.y;this.blueprint.crisp=true;},render(){let settings=this.settings;// Setup lines for X and Y
	this.lines={x:[],y:[]};this.lines.x=settings.lines&&settings.lines.x||[];this.lines.y=settings.lines&&settings.lines.y||[];if(this.lines.x.length===0&&this.lines.y.length===0){return [];}const oob={x0:[],x1:[],y0:[],y1:[]};// Convert a value to an actual position using the scale
	this.lines.x=this.lines.x.filter(filterUndefinedValue).map(line=>{if(typeof line.value==='function'){line.value=line.value();}if(line.scale){let scale=this.chart.scale(line.scale);const position=getPosition(scale,line.value);return extend$1$1(line,{scale,position});}return extend$1$1(line,{position:line.value});});// Set all Y lines to flipXY by default
	// This makes the transposer flip them individually
	this.lines.y=this.lines.y.filter(filterUndefinedValue).map(line=>{if(typeof line.value==='function'){line.value=line.value();}if(line.scale){let scale=this.chart.scale(line.scale);const position=getPosition(scale,line.value);return extend$1$1(line,{scale,position,flipXY:true});}return extend$1$1(line,{position:line.value,flipXY:true});});// Move out of bounds lines (OOB) to separate rendering
	this.lines.x=this.lines.x.filter(line=>{if(line.position<0||line.position>1){oob["x".concat(line.position>1?1:0)].push(createOobData(line));return false;}return true;});this.lines.y=this.lines.y.filter(line=>{if(line.slope&&line.slope!==0){return true;}if(line.position<0||line.position>1){oob["y".concat(line.position>1?1:0)].push(createOobData(line));return false;}return true;});let items=[];// Loop through all X and Y lines
	[...this.lines.x,...this.lines.y].forEach(p=>{let show=p.show===true||typeof p.show==='undefined';if(show){// Create slope line with labels
	let slopeLine;if(p.slope&&p.slope!==0){const scaleX=this.chart.scale({scale:'x'});const scaleY=this.chart.scale({scale:'y'});const minX=scaleX.min();const maxX=scaleX.max();const minY=scaleY.min();const maxY=scaleY.max();slopeLine=_objectSpread2$1(_objectSpread2$1({},p),{},{x1:undefined,y1:undefined,x2:undefined,y2:undefined});const y1=minX*p.slope+p.value;const y2=maxX*p.slope+p.value;const x1=(minY-p.value)/p.slope;const x2=(maxY-p.value)/p.slope;let intersections=[];if(!isOob(y1,minY,maxY)){intersections[0]={x:getPosition(scaleX,minX),y:getPosition(scaleY,y1)};}if(!isOob(x1,minX,maxX)){intersections[1]={x:getPosition(scaleX,x1),y:1};}if(!isOob(y2,minY,maxY)){intersections[2]={x:getPosition(scaleX,maxX),y:getPosition(scaleY,y2)};}if(!isOob(x2,minX,maxX)){intersections[3]={x:getPosition(scaleX,x2),y:0};}const numIntersections=intersections.filter(i=>!!i).length;if(numIntersections>2){removeDuplication(intersections);}intersections=intersections.filter(i=>!!i);if(intersections.length<2){oob["y".concat(y1>maxY?0:1)].push(createOobData(p));return;}slopeLine.x1=intersections[0].x;slopeLine.y1=intersections[0].y;slopeLine.x2=intersections[1].x;slopeLine.y2=intersections[1].y;}else {slopeLine=undefined;}// Create line with labels
	createLineWithLabel({chart:this.chart,blueprint:this.blueprint,renderer:this.renderer,p,settings,items,slopeLine});}});// Handle out of bounds
	if(settings.style.oob.show){oobManager({blueprint:this.blueprint,oob,settings,items});}return items;}};/**
	 * @typedef {object} ComponentRefLine
	 * @extends ComponentSettings
	 * @property {'ref-line'} type component type
	 * @example
	 * {
	 *  type: 'ref-line',
	 *  lines: {
	 *    y: [{
	 *      scale: 'y',
	 *      value: 5000,
	 *      label: {
	 *        text: 'value label'
	 *      }
	 *      slope: 0.5,
	 *    }]
	 *  }
	 * }
	 */function refLine$1(picasso){picasso.component('ref-line',refLineComponent);}function appendStyle$5(struct,buildOpts){extend$1$1(struct,buildOpts.style);}function buildLine$1(buildOpts){const struct={type:'line',x1:0,x2:0,y1:0,y2:0,collider:{type:null}};if(buildOpts.align==='top'||buildOpts.align==='bottom'){struct.x1=buildOpts.innerRect.x-buildOpts.outerRect.x;struct.x2=struct.x1+buildOpts.innerRect.width;struct.y1=struct.y2=buildOpts.align==='top'?buildOpts.innerRect.height-buildOpts.padding:buildOpts.padding;}else {struct.x1=struct.x2=buildOpts.align==='left'?buildOpts.innerRect.width-buildOpts.padding:buildOpts.padding;struct.y1=buildOpts.innerRect.y-buildOpts.outerRect.y;struct.y2=struct.y1+buildOpts.innerRect.height;}appendStyle$5(struct,buildOpts);return struct;}function checkText$1(text){return typeof text==='string'||typeof text==='number'?text:'-';}function appendStyle$4(struct,buildOpts){['fill','fontSize','fontFamily'].forEach(style=>{struct[style]=buildOpts.style[style];});}function clampEnds(struct,buildOpts){if(buildOpts.tilted||buildOpts.stepSize){return;}if(buildOpts.align==='top'||buildOpts.align==='bottom'){const leftBoundary=0;const rightBoundary=buildOpts.outerRect.width;const textWidth=Math.min(buildOpts.maxWidth/2,buildOpts.textRect.width/2);const leftTextBoundary=struct.x-textWidth;const rightTextBoundary=struct.x+textWidth;if(leftTextBoundary<leftBoundary){struct.anchor='start';struct.x=buildOpts.innerRect.x-buildOpts.outerRect.x;}else if(rightTextBoundary>rightBoundary){struct.anchor='end';struct.x=buildOpts.innerRect.width+buildOpts.innerRect.x;}}else {const topBoundary=0;const bottomBoundary=buildOpts.outerRect.height;const textHeight=buildOpts.maxHeight/2;const topTextBoundary=struct.y-textHeight;const bottomTextBoundary=struct.y+textHeight;if(topTextBoundary<topBoundary){struct.y=buildOpts.innerRect.y-buildOpts.outerRect.y;struct.baseline='text-before-edge';}else if(bottomTextBoundary>bottomBoundary){struct.y=buildOpts.innerRect.height+(buildOpts.innerRect.y-buildOpts.outerRect.y);struct.baseline='text-after-edge';}}}function appendPadding$1(struct,buildOpts){if(buildOpts.align==='top'){struct.y-=buildOpts.padding;}else if(buildOpts.align==='bottom'){struct.y+=buildOpts.padding+buildOpts.maxHeight;}else if(buildOpts.align==='left'){struct.x-=buildOpts.padding;}else if(buildOpts.align==='right'){struct.x+=buildOpts.padding;}}function appendTilting(struct,buildOpts){if(buildOpts.tilted){const r=-buildOpts.angle;const radians=r*(Math.PI/180);if(buildOpts.align==='bottom'){struct.x-=buildOpts.maxHeight*Math.sin(radians)/2;struct.y-=buildOpts.maxHeight;struct.y+=buildOpts.maxHeight*Math.cos(radians)/2;}else {struct.x-=buildOpts.maxHeight*Math.sin(radians)/3;}struct.transform="rotate(".concat(r,", ").concat(struct.x,", ").concat(struct.y,")");struct.anchor=buildOpts.align==='bottom'===buildOpts.angle<0?'start':'end';// adjustForEnds
	const textWidth=Math.cos(radians)*buildOpts.maxWidth;if(buildOpts.align==='bottom'===buildOpts.angle<0){// right
	const rightBoundary=buildOpts.outerRect.width-buildOpts.paddingEnd;const rightTextBoundary=struct.x+textWidth;if(rightTextBoundary>rightBoundary){struct.maxWidth=(rightBoundary-struct.x-10)/Math.cos(radians);}}else {// left
	const leftBoundary=buildOpts.paddingEnd;const leftTextBoundary=struct.x-textWidth;if(leftTextBoundary<leftBoundary){struct.maxWidth=(struct.x-leftBoundary-10)/Math.cos(radians);}}}}function bandwidthCollider(tick,struct,buildOpts){if(buildOpts.align==='bottom'||buildOpts.align==='top'){const tickCenter=tick.position*buildOpts.innerRect.width;const leftBoundary=tickCenter+(buildOpts.innerRect.x-buildOpts.outerRect.x-buildOpts.stepSize/2);struct.collider={type:'rect',x:leftBoundary,y:0,width:leftBoundary<0?buildOpts.stepSize+leftBoundary:buildOpts.stepSize,// Adjust collider so that it doesnt extend onto neighbor collider
	height:buildOpts.innerRect.height};}else {const tickCenter=tick.position*buildOpts.innerRect.height;const topBoundary=tickCenter+(buildOpts.innerRect.y-buildOpts.outerRect.y-buildOpts.stepSize/2);struct.collider={type:'rect',x:0,y:topBoundary,width:buildOpts.innerRect.width,height:topBoundary<0?buildOpts.stepSize+topBoundary:buildOpts.stepSize// Adjust collider so that it doesnt extend onto neighbor collider
	};}// Clip edges of the collider, should not extend beyoned the outerRect
	const collider=struct.collider;collider.x=Math.max(collider.x,0);collider.y=Math.max(collider.y,0);const widthClip=collider.x+collider.width-(buildOpts.outerRect.x+buildOpts.outerRect.width);collider.width=widthClip>0?collider.width-widthClip:collider.width;const heightClip=collider.y+collider.height-(buildOpts.outerRect.y+buildOpts.outerRect.height);collider.height=heightClip>0?collider.height-heightClip:collider.height;}function boundsCollider(tick,struct){struct.collider={type:'polygon',vertices:[{x:struct.boundingRect.x,y:struct.boundingRect.y},{x:struct.boundingRect.x+struct.boundingRect.width,y:struct.boundingRect.y},{x:struct.boundingRect.x+struct.boundingRect.width,y:struct.boundingRect.y+struct.boundingRect.height},{x:struct.boundingRect.x,y:struct.boundingRect.y+struct.boundingRect.height}]};}function tiltedCollider(tick,struct,buildOpts){const radians=buildOpts.angle*(Math.PI/180);const halfWidth=Math.max(buildOpts.stepSize/2,struct.boundingRect.height/2);// Handle if bandwidth is zero
	const startAnchor=struct.anchor==='start';const em=struct.anchor==='end'&&radians<0;const sp=struct.anchor==='start'&&radians>=0;const y=struct.boundingRect.y+(sp||em?struct.boundingRect.height:0);// Generate starting points at bandwidth boundaries
	const points=[{x:struct.x-halfWidth,y},{x:struct.x+halfWidth,y}].map(p=>rotate(p,radians,{x:struct.x,y:struct.y}));// Rotate around center point to counteract labels rotation
	// Append points to wrap polygon around label
	const margin=10;// extend slightly to handle single char labels better
	const leftPoint={x:startAnchor?struct.boundingRect.x+struct.boundingRect.width+margin:struct.boundingRect.x-margin,y:struct.boundingRect.y+struct.boundingRect.height};const rightPoint={x:startAnchor?struct.boundingRect.x+struct.boundingRect.width+margin:struct.boundingRect.x-margin,y:struct.boundingRect.y};const orderedPoints=radians>=0?[leftPoint,rightPoint]:[rightPoint,leftPoint];points.push(...orderedPoints);struct.collider={type:'polygon',vertices:points};}function appendCollider(tick,struct,buildOpts){if(buildOpts.layered||!buildOpts.stepSize){boundsCollider(tick,struct);}else if(buildOpts.tilted){tiltedCollider(tick,struct,buildOpts);}else {bandwidthCollider(tick,struct,buildOpts);}}function appendBounds$1(struct,buildOpts){struct.boundingRect=buildOpts.textBounds(struct);}function wiggle(buildOpts,isVertical){const a=isNaN(buildOpts.style.align)?0.5:Math.min(Math.max(buildOpts.style.align,0),1);let w=0;if(buildOpts.tilted){w=buildOpts.stepSize*a;}else {const size=isVertical?buildOpts.textRect.height:buildOpts.textRect.width;w=Math.max(0,buildOpts.stepSize-size)*a;}return w;}function buildNode$1(tick,buildOpts){var _tick$value,_tick$data;const struct={type:'text',text:checkText$1(tick.label),x:0,y:0,maxWidth:buildOpts.maxWidth,maxHeight:buildOpts.maxHeight,tickValue:(_tick$value=tick.value)!==null&&_tick$value!==void 0?_tick$value:(_tick$data=tick.data)===null||_tick$data===void 0?void 0:_tick$data.value};if(buildOpts.align==='top'||buildOpts.align==='bottom'){struct.x=tick.start*buildOpts.innerRect.width+(buildOpts.innerRect.x-buildOpts.outerRect.x)+wiggle(buildOpts,false);struct.y=buildOpts.align==='top'?buildOpts.innerRect.height:0;struct.anchor=buildOpts.stepSize?'start':'middle';struct.x+=isNaN(buildOpts.style.offset)?0:+buildOpts.style.offset;}else {struct.y=tick.start*buildOpts.innerRect.height+(buildOpts.innerRect.y-buildOpts.outerRect.y)+wiggle(buildOpts,true);struct.x=buildOpts.align==='left'?buildOpts.innerRect.width:0;struct.anchor=buildOpts.align==='left'?'end':'start';struct.baseline=buildOpts.stepSize?'text-before-edge':'central';struct.y+=isNaN(buildOpts.style.offset)?0:+buildOpts.style.offset;}appendStyle$4(struct,buildOpts);clampEnds(struct,buildOpts);appendPadding$1(struct,buildOpts);appendTilting(struct,buildOpts);appendBounds$1(struct,buildOpts);appendCollider(tick,struct,buildOpts);return struct;}function appendStyle$3(struct,buildOpts){extend$1$1(struct,buildOpts.style);}function appendPadding(struct,buildOpts){if(buildOpts.align==='top'){struct.y1-=buildOpts.padding;struct.y2-=buildOpts.padding;}else if(buildOpts.align==='bottom'){struct.y1+=buildOpts.padding;struct.y2+=buildOpts.padding;}else if(buildOpts.align==='left'){struct.x1-=buildOpts.padding;struct.x2-=buildOpts.padding;}else if(buildOpts.align==='right'){struct.x1+=buildOpts.padding;struct.x2+=buildOpts.padding;}}function adjustForEnds(struct,buildOpts){const halfWidth=struct.strokeWidth/2;if(struct.x1===buildOpts.innerRect.width){// outer end tick
	struct.x1-=halfWidth;struct.x2-=halfWidth;}else if(struct.x1===0){// outer start tick
	struct.x1+=halfWidth;struct.x2+=halfWidth;}else if(struct.y1===buildOpts.innerRect.height){struct.y1-=halfWidth;struct.y2-=halfWidth;}else if(struct.y1===0){struct.y1+=halfWidth;struct.y2+=halfWidth;}}function buildNode(tick,buildOpts){const struct={type:'line',x1:0,x2:0,y1:0,y2:0,collider:{type:null},tickValue:tick.value};if(buildOpts.align==='top'||buildOpts.align==='bottom'){struct.x1=struct.x2=tick.position*buildOpts.innerRect.width+(buildOpts.innerRect.x-buildOpts.outerRect.x);struct.y1=buildOpts.align==='top'?buildOpts.innerRect.height:0;struct.y2=buildOpts.align==='top'?struct.y1-buildOpts.tickSize:struct.y1+buildOpts.tickSize;}else {struct.y1=struct.y2=tick.position*buildOpts.innerRect.height+(buildOpts.innerRect.y-buildOpts.outerRect.y);struct.x1=buildOpts.align==='left'?buildOpts.innerRect.width:0;struct.x2=buildOpts.align==='left'?struct.x1-buildOpts.tickSize:struct.x1+buildOpts.tickSize;}appendStyle$3(struct,buildOpts);appendPadding(struct,buildOpts);adjustForEnds(struct,buildOpts);return struct;}function isMajorTick(tick){return !tick.isMinor&&tick.position>=0&&tick.position<=1;}function isVerticalLabelOverlapping(_ref){let{majorTicks,measureText,rect}=_ref;const size=rect.height;const textHeight=measureText('M').height;if(majorTicks.length<2){return false;}const d=size*Math.abs(majorTicks[0].position-majorTicks[1].position);if(d<textHeight){return true;}return false;}function isHorizontalLabelOverlapping(_ref2){let{majorTicks,measureText,rect,state}=_ref2;/*
	   * Currently isn't any good way of doing a accurate measurement on size available (bandWidth * width) for labels.
	   * It's a lifecycle limitation as components docked either left or right can affect the width available after the calculation is done.
	   * <number of components docked left/right> * <width of components> => Less accurate ===> Can result in only ellips char rendered as labels.
	   */const m=state.labels.activeMode==='layered'?2:1;const size=rect.width;const tickSize=majorTicks.map(tick=>tick.label).map(l=>"".concat(l.slice(0,1)).concat(l.length>1?'…':''))// Measure the size of 1 chars + the ellips char.
	.map(measureText).map(r=>r.width);for(let i=0;i<majorTicks.length;++i){const tick=majorTicks[i];const d1=m*size*Math.abs(tick.start-tick.end);const d2=tickSize[i];if(d1<d2){return true;}}return false;}function shouldAutoTilt(_ref3){let{majorTicks,measure,rect,state,settings}=_ref3;const glyphCount=settings.labels.maxGlyphCount;const m=state.labels.activeMode==='layered'?2:1;const magicSizeRatioMultipler=settings.labels.tiltThreshold?settings.labels.tiltThreshold:0.7;// So that if less the 70% of labels are visible, toggle on tilt or use variable tiltThreshold
	const ellipsCharSize=measure('…').width;// include ellipsed char in calc as it's generally large then the char it replaces
	const size=rect.width;let maxLabelWidth=0;let d1=0;if(!isNaN(glyphCount)){const minBandwidth=majorTicks.reduce((prev,curr)=>Math.min(Math.abs(curr.start-curr.end),prev),Infinity);d1=m*size*minBandwidth;maxLabelWidth=measure('M').width*magicSizeRatioMultipler*glyphCount;if(maxLabelWidth+ellipsCharSize>d1){return true;}}else {for(let i=0;i<majorTicks.length;i++){const tick=majorTicks[i];const label=tick.label;const width=measure(label).width*(label.length>1?magicSizeRatioMultipler:1);d1=m*size*Math.abs(tick.start-tick.end);if(width+ellipsCharSize>d1){return true;}}}return false;}function isTiltedLabelOverlapping(_ref4){let{majorTicks,measureText,rect,bleedSize,angle}=_ref4;if(majorTicks.length<2){return false;}if(angle===0){return true;// TODO 0 angle should be considered non-tilted
	}const absAngle=Math.abs(angle);const size=Math.min(rect.outer.width-bleedSize,rect.inner.width);const stepSize=size*Math.abs(majorTicks[0].position-majorTicks[1].position);const textHeight=measureText('M').height;const reciprocal=1/stepSize;// 1 === Math.sin(90 * (Math.PI / 180))
	const distanceBetweenLabels=Math.sin(absAngle*(Math.PI/180))/reciprocal;return textHeight>distanceBetweenLabels;}function isToLarge(_ref5){let{rect,state,majorTicks,measure,horizontal}=_ref5;if(horizontal){return isHorizontalLabelOverlapping({majorTicks,measureText:measure,rect,state});}return isVerticalLabelOverlapping({majorTicks,measureText:measure,rect});}function getClampedValue(_ref6){let{value,maxValue,minValue,range,modifier}=_ref6;if(!isNaN(range)&&!isNaN(modifier)){value=range*modifier;}if(value>maxValue){value=maxValue;}if(value<minValue){value=minValue;}return value;}function getSize(_ref7){let{isDiscrete,rect,formatter,measureText,scale,settings,state}=_ref7;let size=0;const edgeBleed={left:0,top:0,right:0,bottom:0};const{maxLengthPx:maxValue,minLengthPx:minValue}=settings.labels;if(settings.labels.show){const align=settings.align;const horizontal=align==='top'||align==='bottom';const distance=horizontal?rect.inner.width:rect.inner.height;const majorTicks=scale.ticks({settings,distance,formatter}).filter(isMajorTick);const measure=text=>{const m=measureText({text,fontSize:settings.labels.fontSize,fontFamily:settings.labels.fontFamily});m.width=getClampedValue({value:m.width,maxValue,minValue});return m;};if(isDiscrete&&horizontal&&settings.labels.mode==='auto'){if(shouldAutoTilt({majorTicks,measure,rect:rect.inner,state,settings})){state.labels.activeMode='tilted';}else {state.labels.activeMode='horizontal';}}if(!settings.labels.filterOverlapping&&state.labels.activeMode!=='tilted'&&isToLarge({rect:rect.inner,state,majorTicks,measure,horizontal})){const toLargeSize=Math.max(rect.outer.width,rect.outer.height);// used to hide the axis
	return {size:toLargeSize,isToLarge:true};}let sizeFromTextRect;if(state.labels.activeMode==='tilted'){const radians=Math.abs(settings.labels.tiltAngle)*(Math.PI/180);// angle in radians
	sizeFromTextRect=r=>getClampedValue({value:r.width,maxValue,minValue})*Math.sin(radians)+r.height*Math.cos(radians);}else if(horizontal){sizeFromTextRect=r=>r.height;}else {sizeFromTextRect=r=>getClampedValue({value:r.width,maxValue,minValue});}let labels;if(horizontal&&state.labels.activeMode!=='tilted'){labels=['M'];}else if(!isNaN(settings.labels.maxGlyphCount)){let label='';for(let i=0;i<settings.labels.maxGlyphCount;i++){label+='M';}labels=[label];}else {labels=majorTicks.map(tick=>tick.label);}const tickMeasures=labels.map(measure);const labelSizes=tickMeasures.map(sizeFromTextRect);const textSize=Math.max(...labelSizes,0);size+=textSize;size+=settings.labels.margin;if(state.labels.activeMode==='layered'){size*=2;}if(state.labels.activeMode==='tilted'){const extendLeft=settings.align==='bottom'===settings.labels.tiltAngle>=0;const radians=Math.abs(settings.labels.tiltAngle)*(Math.PI/180);// angle in radians
	const h=measure('M').height;const maxWidth=(textSize-h*Math.cos(radians))/Math.sin(radians);const labelWidth=r=>Math.min(maxWidth,r.width)*Math.cos(radians)+r.height;const adjustByPosition=(s,i)=>{const pos=majorTicks[i]?majorTicks[i].position:0;if(extendLeft){return s-pos*rect.inner.width;}return s-(1-pos)*rect.inner.width;};const bleedSize=Math.min(settings.labels.maxEdgeBleed,Math.max(...tickMeasures.map(labelWidth).map(adjustByPosition),0))+settings.paddingEnd;const bleedDir=extendLeft?'left':'right';edgeBleed[bleedDir]=bleedSize;if(!settings.labels.filterOverlapping&&isTiltedLabelOverlapping({majorTicks,measureText:measure,rect,bleedSize,angle:settings.labels.tiltAngle})){const toLargeSize=Math.max(rect.outer.width,rect.outer.height);// used to hide the axis
	return {size:toLargeSize,isToLarge:true};}}}return {size,edgeBleed};}const PADDING$1=2;const tickDistance=(rect,start,end)=>rect.width*Math.abs(start.position-end.position);const getLeftEdgeWidth=_ref=>{let{innerRect,outerRect,tick,nextWidth}=_ref;const leftEdgeBleed=innerRect.x-outerRect.x;const left=innerRect.width*tick.position+leftEdgeBleed;const minDubble=Math.min(nextWidth,left)*2;const minWidth=tick.position===0?innerRect.width/2-PADDING$1:0;return Math.max(nextWidth,minDubble,minWidth);};const getRightEdgeWidth=_ref2=>{let{innerRect,outerRect,tick,prevWidth}=_ref2;const leftEdgeBleed=innerRect.x-outerRect.x;const rightEdgeBleed=outerRect.width-innerRect.width-leftEdgeBleed;const right=innerRect.width-innerRect.width*tick.position+rightEdgeBleed;const minDubble=Math.min(prevWidth,right)*2;const minWidth=tick.position===1?innerRect.width/2-PADDING$1:0;return Math.max(prevWidth,minDubble,minWidth);};function getHorizontalWidth(_ref3){let{layered,major,innerRect,outerRect,tick,index}=_ref3;const step=layered?2:1;const prev=major[index-step];const next=major[index+step];const prevWidth=prev?tickDistance(innerRect,tick,prev)/2-PADDING$1:Infinity;const nextWidth=next?tickDistance(innerRect,tick,next)/2-PADDING$1:Infinity;if(major.length<2){return innerRect.width;}if(!prev){return getLeftEdgeWidth({innerRect,outerRect,tick,nextWidth});}if(!next){return getRightEdgeWidth({innerRect,outerRect,tick,prevWidth});}return Math.min(prevWidth,nextWidth)*2;}function appendStyle$2(struct,buildOpts){extend$1$1(struct,buildOpts.style);}function buildArcLine(buildOpts){const rect=buildOpts.innerRect;const centerPoint={cx:rect.width/2,cy:rect.height/2};const halfPlotSize=Math.min(rect.height,rect.width)/2;const innerRadius=halfPlotSize*buildOpts.radius;const outerRadius=innerRadius+buildOpts.style.strokeWidth;const startAngle=buildOpts.startAngle;const endAngle=buildOpts.endAngle;const struct={visible:true,type:'path',arcDatum:{startAngle,endAngle},transform:"translate(0, 0) translate(".concat(centerPoint.cx,", ").concat(centerPoint.cy,")"),desc:{share:1,slice:{cornerRadius:0,innerRadius,outerRadius}},ticks:[]};appendStyle$2(struct,buildOpts);return struct;}function appendStyle$1(struct,buildOpts){const styleClone=_objectSpread2$1({},buildOpts.style);// Shallow clone
	extend$1$1(struct,styleClone);}function polarToCartesian$1(centerX,centerY,radius,angle){return {x:centerX+radius*Math.cos(angle),y:centerY+radius*Math.sin(angle)};}function buildArcTicks(tick,buildOpts){const rect=buildOpts.innerRect;const centerPoint={cx:rect.width/2,cy:rect.height/2};const halfPlotSize=Math.min(rect.height,rect.width)/2;const innerRadius=halfPlotSize*buildOpts.radius;const outerRadius=innerRadius+buildOpts.padding;const startAngle=buildOpts.startAngle;const endAngle=buildOpts.endAngle;const tickLength=buildOpts.tickSize;const angleRange=endAngle-startAngle;let angle=endAngle-tick.position*angleRange;angle-=Math.PI/2;const innerPos=polarToCartesian$1(centerPoint.cx,centerPoint.cy,outerRadius+tickLength,angle);const outerPos=polarToCartesian$1(centerPoint.cx,centerPoint.cy,outerRadius,angle);const struct={type:'line',x1:innerPos.x,y1:innerPos.y,x2:outerPos.x,y2:outerPos.y,value:tick.value};appendStyle$1(struct,buildOpts);return struct;}function appendStyle(struct,buildOpts){['fill','fontSize','fontFamily'].forEach(style=>{struct[style]=buildOpts.style[style];});}function polarToCartesian(centerX,centerY,radius,angle){return {x:centerX+radius*Math.cos(angle),y:centerY+radius*Math.sin(angle)};}function checkText(text){return typeof text==='string'||typeof text==='number'?text:'-';}function calculateMaxWidth(buildOpts,side,innerPos){let maxWidth;if(side==='left'){maxWidth=innerPos.x;}else if(side==='right'){maxWidth=buildOpts.outerRect.width-innerPos.x;}else {maxWidth=Math.max(innerPos.x,buildOpts.outerRect.width-innerPos.x);}return maxWidth;}function checkRadialOutOfBounds(buildOpts,innerPos,struct){let maxHeightTop;let maxHeightBottom;const textHeight=parseFloat(struct.fontSize)||0;maxHeightTop=innerPos.y-textHeight/2;maxHeightBottom=buildOpts.innerRect.height-(innerPos.y+textHeight/2);if(maxHeightTop<0||maxHeightBottom<0){struct.text='';}return maxHeightBottom;}function appendBounds(struct,buildOpts){struct.boundingRect=buildOpts.textBounds(struct);}function buildArcLabels(tick,buildOpts){const rect=buildOpts.innerRect;const centerPoint={cx:rect.width/2,cy:rect.height/2};const halfPlotSize=Math.min(rect.height,rect.width)/2;const innerRadius=halfPlotSize*buildOpts.radius;const outerRadius=innerRadius+buildOpts.padding;const startAngle=buildOpts.startAngle;const endAngle=buildOpts.endAngle;const tickLength=buildOpts.tickSize;const angleRange=endAngle-startAngle;const centerOffset=0.2;let angle;let side;if(buildOpts.align==='top'||buildOpts.align==='bottom'){angle=endAngle-tick.position*angleRange;}else {angle=startAngle+tick.position*angleRange;}if(angle<0-centerOffset&&angle>-Math.PI+centerOffset){side='left';}else if(angle>0+centerOffset&&angle<Math.PI-centerOffset){side='right';}else {side='center';}angle-=Math.PI/2;const padding=6;const innerPos=polarToCartesian(centerPoint.cx,centerPoint.cy,outerRadius+tickLength+padding,angle);let textAnchor;if(side==='left'){textAnchor='end';// Align text to the right of the x-coordinate
	}else if(side==='right'){textAnchor='start';// Align text to the left of the x-coordinate
	}else {textAnchor='middle';// Center align the text
	}const struct={type:'text',text:checkText(tick.label),align:side,x:innerPos.x,y:innerPos.y,maxHeight:buildOpts.maxHeight,maxWidth:calculateMaxWidth(buildOpts,side,innerPos),anchor:textAnchor,baseline:'middle'};appendStyle(struct,buildOpts);appendBounds(struct,buildOpts);checkRadialOutOfBounds(buildOpts,innerPos,struct);return struct;}function tickSpacing(settings){let spacing=0;spacing+=settings.paddingStart;spacing+=settings.line.show?settings.line.strokeWidth/2:0;spacing+=settings.ticks.show?settings.ticks.margin:0;return spacing;}function arcTickSpacing(settings){let spacing=0;spacing+=settings.line.show?settings.line.strokeWidth/2:0;spacing+=settings.ticks.show?settings.ticks.margin:0;return spacing;}function tickMinorSpacing(settings){return settings.line.strokeWidth+settings.minorTicks.margin;}function labelsSpacing(settings){let spacing=0;spacing+=settings.ticks.show?settings.ticks.tickSize:0;spacing+=tickSpacing(settings)+settings.labels.margin;return spacing;}function arcLabelSpacing(settings){let spacing=0;spacing+=settings.ticks.show?settings.ticks.tickSize:0;spacing+=arcTickSpacing(settings)+settings.labels.margin;return spacing;}function calcActualTextRect(_ref){let{style,measureText,tick}=_ref;return measureText({text:tick.label,fontSize:style.fontSize,fontFamily:style.fontFamily});}function majorTicks(ticks){return ticks.filter(t=>!t.isMinor);}function minorTicks(ticks){return ticks.filter(t=>t.isMinor);}function tickBuilder(ticks,buildOpts){return ticks.map(tick=>buildNode(tick,buildOpts));}function arcTickBuilder(ticks,buildOpts){return ticks.map(tick=>buildArcTicks(tick,buildOpts));}function tickBandwidth(scale,tick){return tick?Math.abs(tick.end-tick.start):scale.bandwidth();}function labelBuilder(ticks,buildOpts,resolveTickOpts){return ticks.map((tick,idx)=>{resolveTickOpts(tick,idx);const label=buildNode$1(tick,buildOpts);label.data=tick.data;return label;});}function arcLabelBuilder(ticks,buildOpts,resolveTickOpts){return ticks.map((tick,idx)=>{resolveTickOpts(tick,idx);const label=buildArcLabels(tick,buildOpts);label.data=tick.data;return label;});}function layeredLabelBuilder(ticks,buildOpts,settings,resolveTickOpts){const padding=buildOpts.padding;const spacing=labelsSpacing(settings);return ticks.map((tick,idx)=>{resolveTickOpts(tick,idx);const padding2=spacing+buildOpts.maxHeight+settings.labels.margin;buildOpts.layer=idx%2;buildOpts.padding=idx%2===0?padding:padding2;const label=buildNode$1(tick,buildOpts);label.data=tick.data;return label;});}function filterOverlappingLabels$1(labels,ticks,buildOpts){let isOverlapping=(i,k)=>{const rect1=expandRect(1,labels[i].boundingRect);const rect2=expandRect(1,labels[k].boundingRect);return testRectRect(rect1,rect2);};if(buildOpts&&buildOpts.tilted){const absAngle=Math.abs(buildOpts.angle);isOverlapping=(i,k)=>{const stepSize=Math.abs(labels[i].x-labels[k].x);const reciprocal=1/stepSize;const distanceBetweenLabels=Math.sin(absAngle*(Math.PI/180))/reciprocal;return labels[i].boundingRect.height>distanceBetweenLabels;};}for(let i=0;i<=labels.length-1;i++){for(let k=i+1;k<=Math.min(i+5,i+(labels.length-1));k++){// TODO Find a better way to handle exteme/layered labels then to iterare over ~5 next labels
	if(labels[i]&&labels[k]&&isOverlapping(i,k)){if(k===labels.length-1){// On collition with last label, remove current label instead
	labels.splice(i,1);if(ticks){ticks.splice(i,1);}}else {labels.splice(k,1);if(ticks){ticks.splice(k,1);}}k--;i--;}}}}function discreteCalcMaxTextRect(_ref2){let{textMetrics,settings,innerRect,scale,tilted,layered,tick}=_ref2;const h=textMetrics.height;const bandwidth=tickBandwidth(scale,tick);const textRect={width:0,height:h};if(settings.align==='left'||settings.align==='right'){textRect.width=innerRect.width-labelsSpacing(settings)-settings.paddingEnd;}else if(layered){textRect.width=bandwidth*innerRect.width*2;}else if(tilted){const radians=Math.abs(settings.labels.tiltAngle)*(Math.PI/180);textRect.width=(innerRect.height-labelsSpacing(settings)-settings.paddingEnd-h*Math.cos(radians))/Math.sin(radians);}else {textRect.width=bandwidth*innerRect.width;}textRect.width=getClampedValue({value:textRect.width,maxValue:settings.labels.maxLengthPx,minValue:settings.labels.minLengthPx});return textRect;}function continuousCalcMaxTextRect(_ref3){let{textMetrics,settings,innerRect,outerRect,tilted,layered,tick,index,major}=_ref3;const h=textMetrics.height;const textRect={width:0,height:h};if(settings.align==='left'||settings.align==='right'){textRect.width=innerRect.width-labelsSpacing(settings)-settings.paddingEnd;}else if(tilted){const radians=Math.abs(settings.labels.tiltAngle)*(Math.PI/180);textRect.width=(innerRect.height-labelsSpacing(settings)-settings.paddingEnd-h*Math.cos(radians))/Math.sin(radians);}else {textRect.width=getHorizontalWidth({layered,major,innerRect,outerRect,tick,index});}textRect.width=getClampedValue({value:textRect.width,maxValue:settings.labels.maxLengthPx,minValue:settings.labels.minLengthPx});return textRect;}function getStepSizeFn(_ref4){let{innerRect,scale,settings,tick}=_ref4;const size=settings.align==='top'||settings.align==='bottom'?innerRect.width:innerRect.height;const bandwidth=tickBandwidth(scale,tick);return size*bandwidth;}function nodeBuilder(isDiscrete){let resolveLabelRect;function continuous(){resolveLabelRect=continuousCalcMaxTextRect;return continuous;}function discrete(){resolveLabelRect=discreteCalcMaxTextRect;return discrete;}function build(_ref5){let{settings,scale,innerRect,outerRect,measureText,ticks,state,textBounds}=_ref5;const nodes=[];const major=majorTicks(ticks);const minor=minorTicks(ticks);const buildOpts={innerRect,align:settings.align,outerRect};const tilted=state.labels.activeMode==='tilted';const layered=state.labels.activeMode==='layered';let majorTickNodes;if(settings.arc){buildOpts.startAngle=settings.arc.startAngle;buildOpts.endAngle=settings.arc.endAngle;buildOpts.radius=settings.arc.radius;}if(settings.line.show){buildOpts.style=settings.line;buildOpts.padding=settings.paddingStart;if(settings.arc){nodes.push(buildArcLine(buildOpts));}else {nodes.push(buildLine$1(buildOpts));}}if(settings.ticks.show){buildOpts.style=settings.ticks;buildOpts.tickSize=settings.ticks.tickSize;buildOpts.padding=tickSpacing(settings);if(settings.arc){buildOpts.padding=arcTickSpacing(settings);majorTickNodes=arcTickBuilder(major,buildOpts);}else {majorTickNodes=tickBuilder(major,buildOpts);}}if(settings.labels.show){const padding=labelsSpacing(settings);buildOpts.style=settings.labels;buildOpts.padding=padding;buildOpts.tilted=tilted;buildOpts.layered=layered;buildOpts.angle=settings.labels.tiltAngle;buildOpts.paddingEnd=settings.paddingEnd;buildOpts.textBounds=textBounds;const resolveTickOpts=(tick,index)=>{buildOpts.textRect=calcActualTextRect({tick,measureText,style:buildOpts.style});const maxSize=resolveLabelRect({textMetrics:buildOpts.textRect,settings,innerRect,outerRect,scale,tilted,layered,tick,major,index});buildOpts.maxWidth=maxSize.width;buildOpts.maxHeight=maxSize.height;buildOpts.stepSize=getStepSizeFn({innerRect,scale,settings,tick});};let labelNodes=[];if(settings.arc){buildOpts.padding=arcLabelSpacing(settings);labelNodes=arcLabelBuilder(major,buildOpts,resolveTickOpts);}else if(layered&&(settings.align==='top'||settings.align==='bottom')){labelNodes=layeredLabelBuilder(major,buildOpts,settings,resolveTickOpts);}else {labelNodes=labelBuilder(major,buildOpts,resolveTickOpts);}// Remove labels (and paired tick) that are overlapping
	if(settings.labels.filterOverlapping){filterOverlappingLabels$1(labelNodes,majorTickNodes,buildOpts);}nodes.push(...labelNodes);}if(settings.minorTicks&&settings.minorTicks.show&&minor.length>0){buildOpts.style=settings.minorTicks;buildOpts.tickSize=settings.minorTicks.tickSize;buildOpts.padding=tickMinorSpacing(settings);nodes.push(...tickBuilder(minor,buildOpts));}if(majorTickNodes){nodes.push(...majorTickNodes);}return nodes;}continuous.build=build;discrete.build=build;return isDiscrete?discrete():continuous();}// const DEFAULT_LAYOUT_SETTINGS = { // TODO create dis and con specific settings
	//   anchor: 'auto', // TODO re-name from align..
	//   // orientation: 'auto', // TODO impl. v/h/auto
	//   // direction: 'auto', // TODO impl. left/right/top/bottom/auto
	//   padding: { // TODO use dock layout margin instead..
	//     start: 0,
	//     end: 10
	//   },
	//   maxGlyphCount: NaN,
	//   maxEdgeBleed: Infinity
	//   // labelMode: 'auto' // TODO move here? auto, horizontal, layered
	// };
	/**
	 * @typedef {object} ComponentAxis
	 * @extends ComponentSettings
	 * @property {'axis'} type component type
	 * @property {string} scale reference to band or linear scale
	 * @property {ComponentAxis~DiscreteSettings|ComponentAxis~ContinuousSettings} [settings] discrete or continuous axis settings
	 * @example
	 * {
	 *  type: 'axis',
	 *  scale: '<name-of-scale>'
	 * }
	 *//**
	 * Discrete axis settings
	 * @typedef {object}
	 * @alias ComponentAxis~DiscreteSettings
	 * @example
	 * {
	 *  type: 'axis',
	 *  scale: '<name-of-band-scale>',
	 *  settings: {
	 *    labels: {
	 *      mode: 'tilted',
	 *      tiltAngle: 40,
	 *    },
	 *  },
	 * }
	 */const DEFAULT_DISCRETE_SETTINGS={/**
	   * @typedef {object}
	   */labels:{/** Toggle labels on/off
	     * @type {boolean=} */show:true,/** Tilting angle in degrees. Capped between -90 and 90. Only applicable when labels are in `tilted` mode.
	     * @type {number=} */tiltAngle:40,/** Threshold for toggle of tilted labels. Capped between 0 and 1. For example, if it is set to 0.7, then tilted labels will be toggled if less than 70% of the labels are visible.
	     * @type {number=} */tiltThreshold:0.7,/** Control the amount of space (in pixels) that labes can occupy outside their docking area. Only applicable when labels are in `tilted` mode.
	     * @type {number=} */maxEdgeBleed:Infinity,/** Space in pixels between the tick and label.
	     * @type {number=} */margin:4,/** Max length of labels in pixels
	     * @type {number=} */maxLengthPx:150,/** Min length of labels in pixels. Labels will always at least require this much space
	     * @type {number=} */minLengthPx:0,/** Control how labels arrange themself. Availabe modes are `auto`, `horizontal`, `layered` and `tilted`. When set to `auto` the axis determines the best possible layout in the current context.
	     * @type {string=} */mode:'auto',/** When only a sub-set of data is available, ex. when paging. This property can be used to let the axis estimate how much space the labels will consume, allowing it to give a consistent space estimate over the entire dataset when paging.
	     * @type {number=} */maxGlyphCount:NaN,/** Align act as a slider for the text bounding rect over the item bandwidth, given that the item have a bandwidth. Except when labels are tilted, then the align is a pure align that shifts the position of the label anchoring point.
	     * @type {number=} */align:0.5,/** Offset in pixels along the axis direction.
	     * @type {number=} */offset:0,/**
	     * Toggle whether labels should be filtered if they are overlapping. Filtering may be applied in a non-sequential order.
	     * If labels are overlapping and this setting is toggled off, the axis will automatically hide.
	     * @type {boolean=}
	     */filterOverlapping:false},/**
	   * @typedef {object}
	   */ticks:{/** Toggle ticks on/off
	     * @type {boolean=} */show:false,/** Space in pixels between the ticks and the line.
	     * @type {number=} */margin:0,/** Size of the ticks in pixels.
	     * @type {number=} */tickSize:4},/**
	   * @typedef {object}
	   */line:{/** Toggle line on/off
	     * @type {boolean=} */show:false},/** Padding in direction perpendicular to the axis
	   * @type {number=} */paddingStart:0,/** Padding in direction perpendicular to the axis
	   * @type {number=} */paddingEnd:10,/** Set the anchoring point of the axis. Available options are `auto/left/right/bottom/top`. In `auto` the axis determines the best option. The options are restricted based on the axis orientation, a vertical axis may only anchor on `left` or `right`
	   * @type {string=} */align:'auto'};/**
	 * @typedef {object} ArcSettings
	 * @property {number} startAngle - Start of arc line, in radians
	 * @property {number} endAngle - End of arc line, in radians
	 * @property {number} radius - Radius of arc line
	 *//**
	 * Continuous axis settings
	 * @typedef {object}
	 * @alias ComponentAxis~ContinuousSettings
	 * @property {ArcSettings=} arc - Optional arc settings
	 * @example
	 * {
	 *  type: 'axis',
	 *  scale: '<name-of-linear-scale>',
	 *  settings: {
	 *    minorTicks: {
	 *      show: false,
	 *    },
	 *  },
	 * }
	 */const DEFAULT_CONTINUOUS_SETTINGS={/**
	   * @typedef {object}
	   */labels:{/** Toggle labels on/off
	     * @type {boolean=} */show:true,/** Space in pixels between the tick and label.
	     * @type {number=} */margin:4,/** Max length of labels in pixels
	     * @type {number=} */maxLengthPx:150,/** Min length of labels in pixels. Labels will always at least require this much space
	     * @type {number=} */minLengthPx:0,/** Align act as a slider for the text bounding rect over the item bandwidth, given that the item have a bandwidth.
	     * @type {number=} */align:0.5,/** Offset in pixels along the axis direction.
	     * @type {number=} */offset:0,/**
	     * Toggle whether labels should be filtered if they are overlapping. Filtering may be applied in a non-sequential order.
	     * If labels are overlapping and this setting is toggled off, the axis will automatically hide.
	     * @type {boolean=}
	     */filterOverlapping:true},/**
	   * @typedef {object}
	   */ticks:{/** Toggle ticks on/off
	     * @type {boolean=} */show:true,/** Space in pixels between the ticks and the line.
	     * @type {number=} */margin:0,/** Size of the ticks in pixels.
	     * @type {number=} */tickSize:8},/**
	   * @typedef {object}
	   */minorTicks:{/** Toggle minor-ticks on/off
	     * @type {boolean=} */show:false,/** Size of the ticks in pixels.
	     * @type {number=} */tickSize:3,/** Space in pixels between the ticks and the line.
	     * @type {number=} */margin:0},/**
	   * @typedef {object}
	   */line:{/** Toggle line on/off
	     * @type {boolean=} */show:true},/** Padding in direction perpendicular to the axis
	   * @type {number=} */paddingStart:0,/** Padding in direction perpendicular to the axis
	   * @type {number=} */paddingEnd:10,/** Set the anchoring point of the axis. Available options are `auto/left/right/bottom/top`. In `auto` the axis determines the best option. The options are restricted based on the axis orientation, a vertical axis may only anchor on `left` or `right`
	   * @type {string=} */align:'auto'};function oppositeAlign(align){switch(align){case 'top':return 'bottom';case 'bottom':return 'top';case 'left':return 'right';case 'right':return 'left';default:return align;}}function calcRequiredSize(_ref){let{isDiscrete,rect,formatter,measureText,scale,settings,state}=_ref;let size=0;const{size:labelSize,edgeBleed,isToLarge}=getSize({isDiscrete,rect,formatter,measureText,scale,settings,state});size+=labelSize;if(isToLarge){return {size};}if(settings.ticks.show){size+=settings.ticks.margin;size+=settings.ticks.tickSize;}if(settings.minorTicks&&settings.minorTicks.show){const minorTicksSize=settings.minorTicks.margin+settings.minorTicks.tickSize;if(minorTicksSize>size){size=minorTicksSize;}}if(settings.line.show){const halfWidth=settings.line.strokeWidth/2;size+=halfWidth;edgeBleed[oppositeAlign(settings.align)]=Math.ceil(halfWidth);}size+=settings.paddingStart;size+=settings.paddingEnd;return {size,edgeBleed};}function alignTransform(_ref){let{align,inner}=_ref;if(align==='left'){return {x:inner.width+inner.x};}if(align==='right'||align==='bottom'){return inner;}return {y:inner.y+inner.height};}function resolveAlign(align,dock){const horizontal=['top','bottom'];const vertical=['left','right'];if(horizontal.indexOf(align)!==-1&&vertical.indexOf(dock)===-1){return align;}if(vertical.indexOf(align)!==-1&&horizontal.indexOf(dock)===-1){return align;}return dock;// Invalid align, return current dock as default
	}/**
	 * @ignore
	 * @param {object} context - The component context
	 */function resolveLocalSettings(_ref2){let{state,style,settings}=_ref2;const defaultStgns=extend$1$1(true,{},state.isDiscrete?DEFAULT_DISCRETE_SETTINGS:DEFAULT_CONTINUOUS_SETTINGS,style);const localStgns=extend$1$1(true,{},defaultStgns,settings.settings);const dock=settings.layout.dock||state.defaultDock;localStgns.dock=dock;localStgns.align=resolveAlign(settings.settings.align,dock);localStgns.labels.tiltAngle=Math.max(-90,Math.min(localStgns.labels.tiltAngle,90));const{paddingStart,paddingEnd}=localStgns;localStgns.paddingStart=typeof paddingStart==='function'?paddingStart.call(null):paddingStart;localStgns.paddingEnd=typeof paddingEnd==='function'?paddingEnd.call(null):paddingEnd;return localStgns;}function updateActiveMode(state,settings,isDiscrete){const mode=settings.labels.mode;if(!isDiscrete||!state.isHorizontal){return 'horizontal';}if(mode==='auto'){return state.labels.activeMode;}if(['layered','tilted'].indexOf(settings.labels.mode)!==-1&&['top','bottom'].indexOf(settings.dock)!==-1){return mode;}return 'horizontal';}const axisComponent={require:['chart','renderer','dockConfig'],defaultSettings:{layout:{displayOrder:0,prioOrder:0},settings:{},style:{labels:'$label',ticks:'$guide-line',minorTicks:'$guide-line--minor',line:'$guide-line'}},created(){// State is a representation of properties that are private to this component defintion and may be modified by only in this context.
	this.state={isDiscrete:!!this.scale.bandwidth,isHorizontal:false,labels:{activeMode:'horizontal'},ticks:[],innerRect:{width:0,height:0,x:0,y:0},outerRect:{width:0,height:0,x:0,y:0},defaultDock:undefined,concreteNodeBuilder:undefined,settings:undefined};if(this.state.isDiscrete){this.state.defaultDock='bottom';}else {this.state.defaultDock='left';}this.setState(this.settings);},setState(){this.state.isDiscrete=!!this.scale.bandwidth;this.state.settings=resolveLocalSettings(this);this.state.concreteNodeBuilder=nodeBuilder(this.state.isDiscrete);this.dockConfig.dock(this.state.settings.dock);// Override the dock setting (TODO should be removed)
	this.state.isHorizontal=this.state.settings.align==='top'||this.state.settings.align==='bottom';this.state.labels.activeMode=updateActiveMode(this.state,this.state.settings,this.state.isDiscrete);},preferredSize(opts){const{formatter,state,scale}=this;const distance=this.state.isHorizontal?opts.inner.width:opts.inner.height;this.state.pxScale=scaleWithSize(scale,distance);const reqSize=calcRequiredSize({isDiscrete:this.state.isDiscrete,rect:{inner:opts.inner,outer:opts.outer},formatter,measureText:this.renderer.measureText,scale:this.state.pxScale,settings:this.state.settings,state});return reqSize;},beforeUpdate(){let opts=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{settings}=opts;this.setState(settings);},resize(opts){const{inner,outer}=opts;const extendedInner=extend$1$1({},inner,alignTransform({align:this.state.settings.align,inner}));const finalOuter=outer||extendedInner;extend$1$1(this.state.innerRect,extendedInner);extend$1$1(this.state.outerRect,finalOuter);return outer;},beforeRender(){const{scale,formatter}=this;const distance=this.state.isHorizontal?this.state.innerRect.width:this.state.innerRect.height;this.state.pxScale=scaleWithSize(scale,distance);this.state.ticks=this.state.pxScale.ticks({distance,formatter}).filter(t=>t.position>=0&&t.position<=1);},render(){const{state}=this;const nodes=[];nodes.push(...this.state.concreteNodeBuilder.build({settings:this.state.settings,scale:this.state.pxScale,innerRect:this.state.innerRect,outerRect:this.state.outerRect,measureText:this.renderer.measureText,textBounds:this.renderer.textBounds,ticks:this.state.ticks,state}));crispifier.multiple(nodes);return nodes;}};const type$2='axis';function axis$1(picasso){picasso.component(type$2,axisComponent);}/**
	 * @typedef {object} ComponentContainer
	 * @experimental
	 * @extends ComponentSettings
	 * @property {'container'} type component type
	 * @example
	 * {
	 *  type: 'container',
	 *  preferredSize: ({ inner, outer, dock, children }) => {
	 *    const sizes = children.map(c => c.preferredSize({ inner, outer }));
	 *    return Math.max(...sizes);
	 *  },
	 *  strategy: (rect, components) => {
	 *    const height = rect.height / components.length;
	 *    components.forEach((c, i) => {
	 *      c.resize({ ...rect, height, y: rect.y + i * height })
	 *    });
	 *    return { visible: components, hidden: [], order: components };
	 *  },
	 *  components: [
	 *     ...
	 *  ],
	 * }
	 */const containerComponent={render(){return [];}};function container(picasso){picasso.component('container',containerComponent);}function parseTitle(text,join,scale){let title='';if(typeof text==='function'){title=text();}else if(typeof text==='string'){title=text;}else if(scale){let data=scale.data();const titles=(data.fields||[]).map(field=>field.title());title=titles.join(join);}return title;}function getTextAnchor(dock,anchor){let val='middle';if(dock==='left'){if(anchor==='top'){val='end';}else if(anchor==='bottom'){val='start';}}else if(dock==='right'){if(anchor==='top'){val='start';}else if(anchor==='bottom'){val='end';}}else if(anchor==='left'){val='start';}else if(anchor==='right'){val='end';}return val;}function generateTitle(_ref){let{title,definitionSettings,dock,rect,measureText,style}=_ref;const struct={type:'text',text:title,x:0,y:0,dx:0,dy:0,anchor:getTextAnchor(dock,definitionSettings.anchor),baseline:'alphabetical',stroke:'transparent',strokeWidth:0,fontWeight:'normal'};extend$1$1(struct,style.text);const textRect=measureText(struct);if(dock==='top'||dock==='bottom'){let x=rect.width/2;if(definitionSettings.anchor==='left'){x=definitionSettings.paddingLeft||0;}else if(definitionSettings.anchor==='right'){x=rect.width-(definitionSettings.paddingRight||0);}struct.x=x;struct.y=dock==='top'?rect.height-definitionSettings.paddingStart:definitionSettings.paddingStart+textRect.height;struct.dy=dock==='top'?-(textRect.height/6):-(textRect.height/3);struct.maxWidth=rect.width*0.8;}else {let y=rect.height/2;if(definitionSettings.anchor==='top'){y=definitionSettings.paddingStart;}else if(definitionSettings.anchor==='bottom'){y=rect.height-definitionSettings.paddingStart;}struct.y=y;struct.x=dock==='left'?rect.width-definitionSettings.paddingStart:definitionSettings.paddingStart;struct.dx=dock==='left'?-(textRect.height/3):textRect.height/3;const rotation=dock==='left'?270:90;struct.transform="rotate(".concat(rotation,", ").concat(struct.x+struct.dx,", ").concat(struct.y+struct.dy,")");struct.maxWidth=rect.height*0.8;}if(!isNaN(definitionSettings.maxLengthPx)){struct.maxWidth=Math.min(struct.maxWidth,definitionSettings.maxLengthPx);}return struct;}/**
	 * @typedef {object} ComponentText
	 * @extends ComponentSettings
	 * @property {'text'} type component type
	 * @property {string|function} text Text to display
	 * @example
	 * {
	 *  type: 'text',
	 *  text: 'my title',
	 *  dock: 'left',
	 *  settings: {
	 *    anchor: 'left',
	 *  }
	 * }
	 *//**
	 * @typedef {object} ComponentText.settings
	 * @property {number} [paddingStart=5] - Start padding in pixels
	 * @property {number} [paddingEnd=5] - End padding in pixels
	 * @property {number} [paddingLeft=0] - Left padding in pixels
	 * @property {number} [paddingRight=0] - Right padding in pixels
	 * @property {string} [anchor='center'] - Where to v- or h-align the text. Supports `left`, `right`, `top`, `bottom` and `center`
	 * @property {string} [join=', '] - String to add when joining titles from multiple sources
	 * @property {number} [maxLengthPx] - Limit the text length
	 *//**
	 * @typedef {object} ComponentText.style
	 * @property {object} [text]
	 *//**
	 * @typedef {object} ComponentText.style.text
	 * @property {string} [fontSize='12px'] - Font size of text
	 * @property {string} [fontFamily='Source Sans Pro'] - Font family of text
	 * @property {string} [fontWeight='normal'] - Font weight of text
	 * @property {string} [fill='#ffffff'] - Fill color of text
	 * @property {string} [stroke='transparent'] - Stroke of text
	 * @property {number} [strokeWidth=0] - Stroke width of text
	 * @property {number} [opacity=1] - Opacity of text
	 */const textComponent={require:['renderer','chart'],defaultSettings:{layout:{dock:'bottom',displayOrder:0,prioOrder:0},settings:{paddingStart:5,paddingEnd:5,paddingLeft:0,paddingRight:0,anchor:'center',join:', ',maxLengthPx:NaN},style:{text:'$title'}},created(){this.definitionSettings=this.settings.settings;const text=this.settings.text;const join=this.definitionSettings.join;this.title=parseTitle(text,join,this.scale);},preferredSize(){const height=this.renderer.measureText({text:this.title,fontSize:this.style.text.fontSize,fontFamily:this.style.text.fontFamily}).height;return height+this.definitionSettings.paddingStart+this.definitionSettings.paddingEnd;},render(){const{title,definitionSettings,rect}=this;const nodes=[];nodes.push(generateTitle({title,dock:this.settings.layout.dock,definitionSettings,rect,measureText:this.renderer.measureText,style:this.style}));return nodes;},beforeUpdate(opts){if(opts.settings){extend$1$1(this.settings,opts.settings);this.definitionSettings=opts.settings.settings;}const text=this.settings.text;const join=this.definitionSettings.join;this.title=parseTitle(text,join,this.scale);}};function text$1(picasso){picasso.component('text',textComponent);}/**
	 * @typedef {object} ComponentScrollbar
	 * @extends ComponentSettings
	 * @private
	 *//**
	 * @typedef {object} ComponentScrollbar.settings
	 * @property {boolean} [backgroundColor = '#eee']
	 * @property {boolean} [thumbColor = '#ccc']
	 * @property {boolean} [width = 16]
	 */function start$1(_scrollbar,pos){const dock=_scrollbar.settings.layout.dock;const invert=_scrollbar.settings.settings.invert;const horizontal=dock==='top'||dock==='bottom';const lengthAttr=horizontal?'width':'height';const length=_scrollbar.rect[lengthAttr];const scroll=_scrollbar.chart.scroll(_scrollbar.settings.scroll);let currentMove;{// local scope to allow reuse of variable names later
	let offset=pos[horizontal?'x':'y'];if(invert){offset=length-offset;}const scrollState=scroll.getState();currentMove={startOffset:offset,startScroll:scrollState.start,swipe:false};// Detect swipe start outsize the thumb & change startScroll to jump the scroll there.
	const scrollPoint=offset/length*(scrollState.max-scrollState.min)+scrollState.min;if(scrollPoint<scrollState.start){currentMove.startScroll=scrollPoint;}else if(scrollPoint>scrollState.start+scrollState.viewSize){currentMove.startScroll=scrollPoint-scrollState.viewSize;}}const update=p=>{let offset=p[horizontal?'x':'y'];if(invert){offset=length-offset;}if(!currentMove.swipe){if(Math.abs(currentMove.startOffset-offset)<=1){return;}currentMove.swipe=true;}const scrollState=scroll.getState();const scrollMove=(offset-currentMove.startOffset)/length*(scrollState.max-scrollState.min);const scrollStart=currentMove.startScroll+scrollMove;scroll.moveTo(scrollStart);};const end=p=>{let offset=p[horizontal?'x':'y'];if(invert){offset=length-offset;}const scrollState=scroll.getState();if(currentMove.swipe){const scrollMove=(offset-currentMove.startOffset)/length*(scrollState.max-scrollState.min);const scrollStart=currentMove.startScroll+scrollMove;scroll.moveTo(scrollStart);}else {const scrollCenter=offset/length*(scrollState.max-scrollState.min)+scrollState.min;const scrollStart=scrollCenter-scrollState.viewSize/2;scroll.moveTo(scrollStart);}};return {update,end};}function getLocalPos(event,renderer){const containerRect=renderer.element().getBoundingClientRect();return {x:event.center.x-containerRect.left,y:event.center.y-containerRect.top};}const scrollbarComponent={require:['chart','renderer'],on:{panStart(event){const pos=getLocalPos(event,this.renderer);const startPos={x:pos.x-event.deltaX,y:pos.y-event.deltaY};this.currentMove=start$1(this,startPos);this.currentMove.update(pos);},panMove(event){if(!this.currentMove){return;}const pos=getLocalPos(event,this.renderer);this.currentMove.update(pos);},panEnd(event){if(!this.currentMove){return;}const pos=getLocalPos(event,this.renderer);this.currentMove.end(pos);this.currentMove=null;},panCancel(){this.currentMove=null;},tap(event){const pos=getLocalPos(event,this.renderer);const move=start$1(this,pos);move.end(pos);}},defaultSettings:{settings:{backgroundColor:'#eee',thumbColor:'#ccc',width:16// 32 for touch
	}},preferredSize:function preferredSize(rect){const scrollState=this.chart.scroll(this.settings.scroll).getState();// hide the scrollbar if it is not possible to scroll
	if(scrollState.viewSize>=scrollState.max-scrollState.min){const toLargeSize=Math.max(rect.width,rect.height);return toLargeSize;}return this.settings.settings.width;},render:function render(h){const dock=this.settings.layout.dock;const invert=this.settings.settings.invert;const horizontal=dock==='top'||dock==='bottom';const lengthAttr=horizontal?'width':'height';const _rect=this.rect;const length=_rect[lengthAttr];const scrollState=this.chart.scroll(this.settings.scroll).getState();let thumbStart=length*(scrollState.start-scrollState.min)/(scrollState.max-scrollState.min);const thumbRange=length*scrollState.viewSize/(scrollState.max-scrollState.min);if(invert){thumbStart=length-thumbStart-thumbRange;}return h('div',{style:{position:'relative',width:'100%',height:'100%',background:this.settings.settings.backgroundColor,pointerEvents:'auto'}},[].concat(h('div',{class:'scroller',style:{position:'absolute',[horizontal?'left':'top']:"".concat(thumbStart,"px"),[horizontal?'top':'left']:'25%',[horizontal?'height':'width']:'50%',// ${width}px
	[lengthAttr]:"".concat(Math.max(1,thumbRange),"px"),background:this.settings.settings.thumbColor}})));},renderer:'dom'};function scrollbar$1(picasso){picasso.component('scrollbar',scrollbarComponent);}const TARGET_SIZE=5;const VERTICAL=0;const HORIZONTAL=1;function buildLine(_ref){let{h,isVertical,value,pos,align,borderHit,state,idx}=_ref;const isAlignStart=align!=='end';const alignStart={left:'0',top:'0'};const alignEnd={right:'0',bottom:'0'};const alignStyle=isAlignStart?alignStart:alignEnd;let start=0;let width='100%';let height='100%';if(state.targetRect&&state.settings.bubbles.align==='start'){width="".concat(state.targetRect.x+state.targetRect.width,"px");height="".concat(state.targetRect.y+state.targetRect.height,"px");}else if(state.targetRect&&state.settings.bubbles.align==='end'){start=isVertical?state.targetRect.x:state.targetRect.y;width="".concat(state.rect.width-start,"px");height="".concat(state.rect.height-start,"px");}if(!isAlignStart){pos-=borderHit;}// edge
	return h('div',{onmouseover(e){e.srcElement.children[0].style.backgroundColor='#000';e.srcElement.children[0].style[isVertical?'height':'width']='2px';},onmouseout(e){e.srcElement.children[0].style.backgroundColor=state.style.line.stroke;e.srcElement.children[0].style[isVertical?'height':'width']='1px';},'data-value':value,'data-key':[state.key,'edge',idx].join('-'),style:{cursor:isVertical?'ns-resize':'ew-resize',position:'absolute',left:isVertical?"".concat(start,"px"):"".concat(pos,"px"),top:isVertical?"".concat(pos,"px"):"".concat(start,"px"),height:isVertical?"".concat(borderHit,"px"):height,width:isVertical?width:"".concat(borderHit,"px"),pointerEvents:'auto'}},[// line
	h('div',{style:extend$1$1({backgroundColor:state.style.line.stroke,position:'absolute',height:isVertical?"".concat(1,"px"):'100%',width:isVertical?'100%':"".concat(1,"px"),pointerEvents:'none'},alignStyle)})]);}function buildBubble(_ref2){let{h,isVertical,label,otherValue,rangeIdx,idx,pos,align,state,value}=_ref2;const isAlignStart=align!=='end';const isOutside=state.settings.bubbles.placement==='outside';let outside='none';let bubbleDock;if(isVertical){bubbleDock=isAlignStart?'left':'right';if(isOutside){outside=isAlignStart?'translate(-100%,  0px)':'translate(100%,  0px)';}}else {bubbleDock=isAlignStart?'top':'bottom';if(isOutside){outside=isAlignStart?'translate(0px, -100%)':'translate(0px,  100%)';}}let inEdit=state.edit&&state.edit.rangeIdx===rangeIdx&&state.edit.bubbleIdx===idx;const bubbleStyle={position:'relative',borderRadius:"".concat(state.style.bubble.borderRadius,"px"),border:"".concat(state.style.bubble.strokeWidth,"px solid ").concat(state.style.bubble.stroke),backgroundColor:state.style.bubble.fill,color:state.style.bubble.color,fontFamily:state.style.bubble.fontFamily,fontSize:state.style.bubble.fontSize,padding:'4px 8px',textAlign:'center',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap',maxWidth:'150px',minWidth:'50px',minHeight:'1em',pointerEvents:'auto',transform:isVertical?'translate(0,-50%)':'translate(-50%,0)',cursor:isVertical?'ns-resize':'ew-resize'};let currentBorderColor=state.style.bubble.stroke;const bubble=inEdit?h('input',{type:'text',value,style:_objectSpread2$1(_objectSpread2$1({},bubbleStyle),{},{textAlign:'start',textOverflow:'',fontSize:'13px'// TODO - make it styleable
	}),onkeyup(e){if(e.key==='Enter'){e.preventDefault();e.stopPropagation();const newValue=parseFloat(e.target.value);if(isNaN(newValue)){currentBorderColor='rgba(230, 78, 78, 0.6)';e.target.style.border="".concat(state.style.bubble.strokeWidth,"px solid ").concat(currentBorderColor);}else {state.onEditConfirmed(rangeIdx,newValue,otherValue);}}else if(e.key==='Escape'){e.preventDefault();e.stopPropagation();state.onEditCanceled();}}}):h('div',{'data-key':[state.key,'bubble',rangeIdx,idx].join('-'),'data-other-value':otherValue,'data-idx':rangeIdx,'data-bidx':idx,style:bubbleStyle},[label]);// bubble wrapper
	return h('div',{style:{position:'absolute',[bubbleDock]:'0',[isVertical?'top':'left']:"".concat(pos,"px"),transform:outside}},[// bubble
	bubble]);}function buildArea(_ref3){let{h,isVertical,top,height,color,on,opacity}=_ref3;return h('div',extend$1$1({style:{backgroundColor:color,opacity,position:'absolute',left:isVertical?0:"".concat(top,"px"),top:isVertical?"".concat(top,"px"):0,height:isVertical?"".concat(height,"px"):'100%',width:isVertical?'100%':"".concat(height,"px"),pointerEvents:'auto'}},on),[]);}function buildRange(_ref4){let{borderHit,els,isVertical,state,vStart,vEnd,idx}=_ref4;let targetOffset=0;if(state.targetRect){targetOffset=isVertical?state.targetRect.y:state.targetRect.x;}const hasScale=!!state.scale;const start=hasScale?state.scale.norm(vStart)*state.size:vStart;const end=hasScale?state.scale.norm(vEnd)*state.size:vEnd;const height=Math.abs(start-end);const top=Math.min(start,end)+targetOffset;const bottom=top+height;if(state.targetRect){const target=state.targetFillRect||state.targetRect;const targetSize=isVertical?target.height:target.width;const targetStart=hasScale?state.scale.norm(vStart)*targetSize:vStart;const targetEnd=hasScale?state.scale.norm(vEnd)*targetSize:vEnd;const targetHeight=Math.abs(targetStart-targetEnd);const targetTop=Math.min(targetStart,targetEnd);const targetArea={h:state.h,isVertical,top:targetTop,height:targetHeight,color:state.style.target.fill,opacity:state.style.target.opacity};if(state.style.target.opacity<0.8){targetArea.on={onmouseover(e){e.srcElement.style.opacity=state.style.target.opacity+0.1;},onmouseout(e){e.srcElement.style.opacity=state.style.target.opacity;}};}els.push(state.h('div',{style:{position:'absolute',left:"".concat(target.x,"px"),top:"".concat(target.y,"px"),height:"".concat(target.height,"px"),width:"".concat(target.width,"px")}},[buildArea(targetArea)]));}// active range area
	// els.push(buildArea({
	//   h: state.h,
	//   isVertical,
	//   top,
	//   height,
	//   color: state.settings.fill
	// }));
	const valStart=start<end?vStart:vEnd;const valEnd=start<end?vEnd:vStart;const[min,max]=hasScale?state.scale.domain():[Math.min(vStart,vEnd),Math.max(vStart,vEnd)];const isStartVisible=valStart+1e-5>=min&&valStart-1e-5<=max;// accept minor floating point difference
	const isEndVisible=valEnd-1e-5<=max&&valEnd+1e-5>=min;if(isStartVisible){els.push(buildLine({h:state.h,isVertical,borderHit,value:valStart,pos:top,align:'start',state,idx}));}if(isEndVisible){els.push(buildLine({h:state.h,isVertical,borderHit,value:valEnd,pos:bottom,align:'end',state,idx}));}const bubbles=state.settings.bubbles;if(bubbles&&bubbles.show){bubbles.fontSize;bubbles.fontFamily;bubbles.fill;const range=[vStart,vEnd];if(isStartVisible){els.push(buildBubble({h:state.h,isVertical,align:bubbles.align,rangeIdx:idx,idx:0,otherValue:valEnd,value:valStart,label:"".concat(state.format(valStart,range)),pos:top,state}));}if(isEndVisible){els.push(buildBubble({h:state.h,isVertical,align:bubbles.align,rangeIdx:idx,idx:1,otherValue:valStart,value:valEnd,label:"".concat(state.format(valEnd,range)),pos:bottom,state}));}}}function getMoveDelta(state){const posDelta=state.active.limitHigh-state.active.end;const negDelta=state.active.limitLow-state.active.start;let delta=state.current-state.start;if(delta<0){delta=Math.max(delta,negDelta);}else {delta=Math.min(delta,posDelta);}return delta;}function nodes(state){let els=[];const isVertical=state.direction===VERTICAL;if(Array.isArray(state.ranges)){// add all other ranges
	state.ranges.forEach((r,i)=>{if(!state.active||i!==state.active.idx){buildRange({borderHit:TARGET_SIZE,els,isVertical,state,vStart:Math.min(r.min,r.max),vEnd:Math.max(r.min,r.max),idx:i});}});}if(state.active){// add active range
	let vStart=state.start;let vEnd=state.current;if(state.active.idx!==-1){if(state.active.mode==='foo'){vStart=Math.min(state.active.start,state.active.end);vEnd=Math.max(state.active.start,state.active.end);}else if(state.active.mode==='modify'){vStart=Math.min(state.start,state.current);vEnd=Math.max(state.start,state.current);}else {const delta=getMoveDelta(state);vStart=state.active.start+delta;vEnd=state.active.end+delta;}}buildRange({borderHit:TARGET_SIZE,els,isVertical,state,vStart,vEnd,idx:state.active.idx});}return els;}function rangelimits(state){return {min:state.scale.min(),max:state.scale.max()};}function areaLimits(state){return {min:0,max:state.direction?state.rect.width:state.rect.height};}function findActive(state,value,limits){let rs=state.ranges;let i;let activeIdx=-1;for(i=0;i<rs.length;i++){if(rs[i].min<=value&&value<=rs[i].max){activeIdx=i;limits.min=i?rs[i-1].max:limits.min;limits.max=i+1<rs.length?rs[i+1].min:limits.max;break;}else if(value<rs[i].min){limits.max=rs[i].min;limits.min=i?rs[i-1].max:limits.min;break;}}if(activeIdx===-1&&rs.length&&i>=rs.length){limits.min=rs[rs.length-1].max;}let activeRange;if(activeIdx!==-1){activeRange={idx:activeIdx,start:rs[activeIdx].min,end:rs[activeIdx].max,limitLow:limits.min,limitHigh:limits.max,mode:'foo'};}state.active=activeRange;}function startArea(_ref){let{state,e,renderer,ranges,targetSize}=_ref;if(state.started){return;}const x=e.center.x-e.deltaX;const y=e.center.y-e.deltaY;let target=document.elementFromPoint(x,y);if(!renderer.element().contains(target)){target=null;}const tempState={started:true};state.offset=renderer.element().getBoundingClientRect();state.ranges=ranges(state);const relX=x-state.offset.left;// coordinate relative renderer
	const relY=y-state.offset.top;const startPoint=e.center[state.cssCoord.coord]-e[state.cssCoord.pos]-state.offset[state.cssCoord.offset];const relStart=e.center[state.cssCoord.coord]-state.offset[state.cssCoord.offset];let v=relStart;let vStart=startPoint;tempState.start=startPoint;tempState.current=relStart;let rs=state.ranges;const limits=areaLimits(state);let i;let activeIdx=-1;if(target&&target.hasAttribute('data-idx')){activeIdx=parseInt(target.getAttribute('data-idx'),10);limits.min=activeIdx>0?rs[activeIdx-1].max:limits.min;limits.max=activeIdx+1<rs.length?rs[activeIdx+1].min:limits.max;}else {for(i=0;i<rs.length;i++){if(rs[i].min<=vStart&&vStart<=rs[i].max){activeIdx=i;limits.min=i?rs[i-1].max:limits.min;limits.max=i+1<rs.length?rs[i+1].min:limits.max;break;}else if(vStart<rs[i].min){limits.max=rs[i].min;limits.min=i?rs[i-1].max:limits.min;break;}}if(activeIdx===-1&&rs.length&&i>=rs.length){limits.min=rs[rs.length-1].max;}}if(activeIdx===-1&&!state.multi){tempState.ranges=[];limits.min=0;limits.max=state.direction?state.rect.width:state.rect.height;}let activeRange;if(activeIdx!==-1){activeRange={idx:activeIdx,start:rs[activeIdx].min,end:rs[activeIdx].max,limitLow:limits.min,limitHigh:limits.max,mode:'move'};if(target&&target.hasAttribute('data-other-value')){tempState.start=parseFloat(target.getAttribute('data-other-value'));activeRange.mode='modify';}else {let pxStart=activeRange.start;let pxEnd=activeRange.end;if(Math.abs(startPoint-pxStart)<=targetSize){tempState.start=activeRange.end;activeRange.mode='modify';}else if(Math.abs(startPoint-pxEnd)<=targetSize){tempState.start=activeRange.start;activeRange.mode='modify';}}}else {activeRange={idx:-1,start:vStart,end:v,limitLow:limits.min,limitHigh:limits.max,mode:'current'};}tempState.active=activeRange;if(activeRange.mode!=='modify'&&state.targetRect&&!testRectPoint(state.targetRect,{x:relX,y:relY}));else {Object.keys(tempState).forEach(key=>state[key]=tempState[key]);}}function start(_ref2){let{state,e,renderer,ranges,targetSize}=_ref2;if(state.started){return;}state.edit=null;const x=e.center.x-e.deltaX;const y=e.center.y-e.deltaY;let target=document.elementFromPoint(x,y);if(!renderer.element().contains(target)){target=null;}const tempState={started:true};state.offset=extend$1$1({},renderer.element().getBoundingClientRect());const relX=x-state.offset.left;// coordinate relative renderer
	const relY=y-state.offset.top;state.offset.left+=state.targetRect?state.targetRect.x:0;// make offset relative to targetRect
	state.offset.top+=state.targetRect?state.targetRect.y:0;state.ranges=ranges(state,state.fauxBrushInstance||state.brushInstance);const startPoint=e.center[state.cssCoord.coord]-e[state.cssCoord.pos]-state.offset[state.cssCoord.offset];const relStart=e.center[state.cssCoord.coord]-state.offset[state.cssCoord.offset];tempState.current=state.scale.normInvert(relStart/state.size);tempState.start=state.scale.normInvert(startPoint/state.size);let rs=state.ranges;const limits=rangelimits(state);let i;let activeIdx=-1;if(target&&target.hasAttribute('data-idx')){activeIdx=parseInt(target.getAttribute('data-idx'),10);limits.min=activeIdx>0?rs[activeIdx-1].max:limits.min;limits.max=activeIdx+1<rs.length?rs[activeIdx+1].min:limits.max;}else {for(i=0;i<rs.length;i++){if(rs[i].min<=tempState.start&&tempState.start<=rs[i].max){activeIdx=i;limits.min=i?rs[i-1].max:limits.min;limits.max=i+1<rs.length?rs[i+1].min:limits.max;break;}else if(tempState.start<rs[i].min){limits.max=rs[i].min;limits.min=i?rs[i-1].max:limits.min;break;}}if(activeIdx===-1&&rs.length&&i>=rs.length){limits.min=rs[rs.length-1].max;}}if(activeIdx===-1&&!state.multi){tempState.ranges=[];limits.min=state.scale.min();limits.max=state.scale.max();}let activeRange;if(activeIdx!==-1){activeRange={idx:activeIdx,start:rs[activeIdx].min,end:rs[activeIdx].max,limitLow:limits.min,limitHigh:limits.max,mode:'move'};if(target&&target.hasAttribute('data-other-value')){tempState.start=parseFloat(target.getAttribute('data-other-value'));activeRange.mode='modify';}else {let pxStart=state.scale.norm(activeRange.start)*state.size;let pxEnd=state.scale.norm(activeRange.end)*state.size;if(Math.abs(startPoint-pxStart)<=targetSize){tempState.start=activeRange.end;activeRange.mode='modify';}else if(Math.abs(startPoint-pxEnd)<=targetSize){tempState.start=activeRange.start;activeRange.mode='modify';}}}else {activeRange={idx:-1,start:tempState.start,end:tempState.current,limitLow:limits.min,limitHigh:limits.max,mode:'current'};}tempState.active=activeRange;if(activeRange.mode!=='modify'&&state.targetRect&&!testRectPoint(state.targetRect,{x:relX,y:relY}));else {Object.keys(tempState).forEach(key=>state[key]=tempState[key]);}}function end(state,ranges){state.started=false;state.ranges=ranges(state,state.fauxBrushInstance||state.brushInstance);const limits=rangelimits(state);findActive(state,state.current,limits);}function endArea(state,ranges){state.started=false;state.ranges=ranges(state);const limits=areaLimits(state);findActive(state,state.current,limits);}function move(state,e){const relY=e.center[state.cssCoord.coord]-state.offset[state.cssCoord.offset];const rel=relY/state.size;const v=state.scale.normInvert(rel);state.current=Math.max(Math.min(v,state.active.limitHigh),state.active.limitLow);}function moveArea(state,e){const rel=e.center[state.cssCoord.coord]-state.offset[state.cssCoord.offset];state.current=Math.max(Math.min(rel,state.active.limitHigh),state.active.limitLow);}function render$c(state){state.renderer.render(nodes(state));}function ranges$2(state,brush){if(!brush||!brush.isActive()){return [];}const sourceData=state.scale.data();const sourceFields=sourceData?sourceData.fields||[]:[];const sources=sourceFields.map(field=>field.id());const rangeBrush=brush.brushes().filter(f=>f.type==='range'&&sources.indexOf(f.id)!==-1)[0];if(!rangeBrush){return [];}return rangeBrush.brush.ranges();}function setRanges$1(state){let rs=state.ranges.map(r=>({min:r.min,max:r.max}));if(state.active.idx!==-1){if(state.active.mode==='modify'){rs[state.active.idx].min=Math.min(state.start,state.current);rs[state.active.idx].max=Math.max(state.start,state.current);}else {const delta=getMoveDelta(state);rs[state.active.idx].min+=delta;rs[state.active.idx].max+=delta;}}else {rs.push({min:Math.min(state.start,state.current),max:Math.max(state.start,state.current)});}const scaleData=state.scale.data();if(scaleData&&scaleData.fields){scaleData.fields.forEach(field=>{if(state.fauxBrushInstance){let ordRS=ranges$2(state,state.fauxBrushInstance);let oldValues=state.findValues(ordRS);let values=state.findValues(rs);let addedValues=values.filter(v=>oldValues.indexOf(v)===-1);let removedValues=oldValues.filter(v=>values.indexOf(v)===-1);let addItems=addedValues.map(v=>({key:field.id(),value:v}));let removeItems=removedValues.map(v=>({key:field.id(),value:v}));state.brushInstance.addAndRemoveValues(addItems,removeItems);state.fauxBrushInstance.setRange(field.id(),rs);}else {state.brushInstance.setRange(field.id(),rs);}});}}function setEditedRanges(state,idx,startValue,endValue){let rs=state.ranges.map(r=>({min:r.min,max:r.max}));const limitMin=state.scale.min();const limitMax=state.scale.max();rs[idx]={min:Math.max(limitMin,Math.min(startValue,endValue)),max:Math.min(limitMax,Math.max(startValue,endValue))};state.ranges[idx]=_objectSpread2$1({},rs[idx]);const scaleData=state.scale.data();if(scaleData&&scaleData.fields){scaleData.fields.forEach(field=>{if(!state.fauxBrushInstance){state.brushInstance.setRange(field.id(),rs);}});}}function findClosest(value,scale){let name;let minDist=Infinity;const domain=scale.domain();const halfBandwidth=scale.bandwidth()/2;for(let i=0;i<domain.length;++i){const d=Math.abs(value-halfBandwidth-scale(domain[i]));if(d<minDist){minDist=d;name=domain[i];}}return name;}function findClosestLabel(value,scale){const ticks=scale.ticks();const idx=scale.domain().indexOf(findClosest(value,scale));return idx!==-1?ticks[idx].label:'-';}function rangesOverlap(r1,r2){return Math.min(...r1)<=Math.max(...r2)&&Math.max(...r1)>=Math.min(...r2);}function findValues(rangesValues,scale){const domain=scale.domain();const scaleRange=scale.range();const values=[];rangesValues.forEach(range=>{if(!rangesOverlap(scaleRange,[range.min,range.max])){return;}const startIdx=domain.indexOf(findClosest(range.min,scale));const endIdx=domain.indexOf(findClosest(range.max,scale));values.push.apply(values,domain.slice(Math.min(startIdx,endIdx),Math.max(startIdx,endIdx)+1));/* eslint prefer-spread:0 */});return values;}function resolveNodeBounds(targetNodes){const points=targetNodes.reduce((ary,node)=>{ary.push(...rectToPoints(node.bounds));return ary;},[]);return pointsToRect(points);}function resolveTarget(ctx){const resolved={targetRect:null,targetFillRect:null,scale:null,size:null};const stngs=ctx.settings.settings;const targets=stngs.target&&(stngs.target.components||(stngs.target.component?[stngs.target.component]:[])).map(c=>ctx.chart.component(c)).filter(c=>!!c&&!!c.rect);const targetNodes=stngs.target&&stngs.target.selector?ctx.chart.findShapes(stngs.target.selector):[];const targetFillNodes=stngs.target&&stngs.target.fillSelector?ctx.chart.findShapes(stngs.target.fillSelector):[];if(targetNodes.length>0){const bounds=resolveNodeBounds(targetNodes);resolved.size=bounds[ctx.state.direction===VERTICAL?'height':'width'];resolved.scale=scaleWithSize(ctx.chart.scale(stngs.scale),resolved.size);resolved.targetRect=bounds;if(targetFillNodes.length>0){const fillBounds=resolveNodeBounds(targetFillNodes);resolved.targetFillRect=fillBounds;}}else if(targets&&targets.length>0){const targetRect=targets.slice(1).reduce((prev,curr)=>({x0:Math.min(prev.x0,curr.rect.computedInner.x),y0:Math.min(prev.y0,curr.rect.computedInner.y),x1:Math.max(prev.x1,curr.rect.computedInner.x+curr.rect.computedInner.width),y1:Math.max(prev.y1,curr.rect.computedInner.y+curr.rect.computedInner.height)}),{x0:targets[0].rect.computedInner.x,y0:targets[0].rect.computedInner.y,x1:targets[0].rect.computedInner.x+targets[0].rect.computedInner.width,y1:targets[0].rect.computedInner.y+targets[0].rect.computedInner.height});resolved.targetRect={x:targetRect.x0-ctx.state.rect.x,y:targetRect.y0-ctx.state.rect.y,width:targetRect.x1-targetRect.x0,height:targetRect.y1-targetRect.y0};}return resolved;}/**
	 * @typedef {object} ComponentBrushRange.settings
	 * @property {string|object} brush - Brush context to apply changes to
	 * @property {string} scale - Scale to extract data from
	 * @property {string} [direction=vertical] - Rendering direction [horizontal|vertical]
	 * @property {object} [bubbles]
	 * @property {boolean} [bubbles.show=true] - True to show label bubble, false otherwise
	 * @property {string} [bubbles.align=start] - Where to anchor bubble [start|end]
	 * @property {function} [bubbles.label] - Callback function for the labels
	 * @property {object} [target]
	 * @property {string[]} [target.components] - Render matching overlay on target components
	 * @property {string} [target.selector] - Instead of targeting a component, target one or more shapes
	 * @property {string} [target.fillSelector] - Target a subset of the selector as fill area. Only applicable if `selector` property is set
	 *//**
	 * @private
	 * @typedef {object} ComponentBrushRangeStyle
	 * @property {object} [bubble]
	 * @property {string} [bubble.fontSize]
	 * @property {string} [bubble.fontFamily]
	 * @property {string} [bubble.fill]
	 * @property {string} [bubble.color]
	 * @property {string} [bubble.stroke]
	 * @property {number} [bubble.strokeWidth]
	 * @property {number} [bubble.borderRadius]
	 * @property {object} [line]
	 * @property {string} [line.stroke]
	 * @property {number} [line.strokeWidth]
	 * @property {object} [target]
	 * @property {string} [target.fill]
	 * @property {number} [target.strokeWidth]
	 * @property {number} [target.opacity]
	 */const brushRangeComponent={require:['chart','settings','renderer'],defaultSettings:{settings:{bubbles:{show:true,align:'start'}},style:{bubble:'$label-overlay',line:'$shape-guide--inverted',target:'$selection-area-target'}},renderer:'dom',on:{rangeStart(e){this.start(e);},rangeMove(e){this.move(e);},rangeEnd(e){this.end(e);},rangeClear(e){this.clear(e);},bubbleStart(e){this.bubbleStart(e);}},created(){this.state={key:this.settings.key||'brush-range'};},beforeRender(opts){this.state.rect=opts.size.computedInner;},renderRanges(){if(!this.state.started){this.state.ranges=ranges$2(this.state,this.state.brushInstance);this.state.active=null;render$c(this.state);}},render(h){const stngs=this.settings.settings;this.state.direction=stngs.direction==='vertical'?VERTICAL:HORIZONTAL;const offset=this.renderer.element().getBoundingClientRect();const size=this.state.rect[this.state.direction===VERTICAL?'height':'width'];let scale=scaleWithSize(this.chart.scale(stngs.scale),size);const target=resolveTarget(this);scale=target.scale?target.scale:scale;this.state.targetRect=target.targetRect;this.state.targetFillRect=target.targetFillRect;this.state.size=target.size===null?size:target.size;this.state.settings=stngs;this.state.style=this.style;this.state.offset=offset;this.state.brush=typeof stngs.brush==='object'?stngs.brush.context:stngs.brush;this.state.brushInstance=this.chart.brush(this.state.brush);this.state.renderer=this.renderer;this.state.multi=!!stngs.multiple;this.state.h=h;this.state.onEditConfirmed=(rangeIdx,value,otherValue)=>{this.state.edit=null;setEditedRanges(this.state,rangeIdx,value,otherValue);this.emit('bubbleEnd');render$c(this.state);};this.state.onEditCanceled=()=>{this.state.edit=null;render$c(this.state);};this.state.cssCoord={offset:this.state.direction===VERTICAL?'top':'left',coord:this.state.direction===VERTICAL?'y':'x',pos:this.state.direction===VERTICAL?'deltaY':'deltaX'};this.state.format=typeof stngs.bubbles.label==='function'?(v,r)=>stngs.bubbles.label.call(undefined,{datum:v,data:r,scale,resources:{scale:this.chart.scale,formatter:this.chart.formatter}}):false;if(!{}.hasOwnProperty.call(scale,'norm')){// Non-linear scale if norm method is unavailable
	this.state.editable=false;this.state.scale=scaleLinear();this.state.scale.data=scale.data;if(!this.state.format){this.state.format=(v,r)=>{if(!rangesOverlap(scale.range(),r)){return '-';}return findClosestLabel(v,scale);};}this.state.fauxBrushInstance=brush();this.state.findValues=valueRanges=>findValues(valueRanges,scale);}else {this.state.editable=true;this.state.observeBrush=typeof stngs.brush==='object'?stngs.brush.observe:false;this.state.fauxBrushInstance=null;this.state.findValues=null;this.state.scale=scale;const scaleData=this.state.scale.data();if(!this.state.format&&scaleData&&scaleData.fields&&scaleData.fields[0]){this.state.format=scaleData.fields[0].formatter();}}this.state.ranges=ranges$2(this.state,this.state.brushInstance);return this.state.observeBrush||this.state.sourcedFromThisComponent?[nodes(this.state)]:[];},mounted(){if(this.state.observeBrush&&this.state.brushInstance){this.state.brushInstance.on('update',this.renderRanges);}},beforeDestroy(){if(this.state.observeBrush&&this.state.brushInstance){this.state.brushInstance.removeListener('update',this.renderRanges);}},start(e){start({e,state:this.state,renderer:this.renderer,ranges:ranges$2,targetSize:TARGET_SIZE});},end(){if(!this.state.started){return;}end(this.state,ranges$2);render$c(this.state);this.state.sourcedFromThisComponent=true;this.state.active=null;},move(e){if(!this.state.started){return;}move(this.state,e);setRanges$1(this.state);render$c(this.state);},clear(){if(this.state.fauxBrushInstance){this.state.fauxBrushInstance.clear();}this.state.renderer.render([]);this.state.started=false;this.state.active=null;this.state.sourcedFromThisComponent=false;},bubbleStart(e){if(!this.state.editable){return;}const ee=e.srcEvent||e;const target=ee.target;const ed={rangeIdx:parseInt(target.getAttribute('data-idx'),10),bubbleIdx:parseInt(target.getAttribute('data-bidx'),10)};if(isNaN(ed.rangeIdx)||JSON.stringify(ed)===JSON.stringify(this.state.edit)){return;}this.state.edit=ed;ee.stopPropagation();ee.stopImmediatePropagation();ee.preventDefault();const wrapper=target.parentNode;render$c(this.state);const inputEl=wrapper.querySelector('input');inputEl.focus();inputEl.select();}};function render$b(state){state.renderer.render(nodes(state));}function ranges$1(state){return state.rc.ranges();}function shapesFromRange(state,brushRange){const shapeAt={x:state.direction?brushRange.min+state.rect.x:state.rect.x,y:state.direction?state.rect.y:brushRange.min+state.rect.y,width:state.direction?brushRange.max-brushRange.min:state.rect.width+state.rect.x,height:state.direction?state.rect.height+state.rect.y:brushRange.max-brushRange.min};return state.chart.shapesAt(shapeAt,state.settings.brush);}function brushFromShape(state,newShapes){state.chart.brushFromShapes(newShapes,state.settings.brush);}function setRanges(state){const rs=state.ranges.map(r=>({min:r.min,max:r.max}));if(state.active.idx!==-1){if(state.active.mode==='modify'){rs[state.active.idx].min=Math.min(state.start,state.current);rs[state.active.idx].max=Math.max(state.start,state.current);}else {const delta=getMoveDelta(state);rs[state.active.idx].min=state.active.start+delta;rs[state.active.idx].max=state.active.end+delta;}}else {rs.push({min:Math.min(state.start,state.current),max:Math.max(state.start,state.current)});}state.rc.set(rs);let shapes=[];rs.forEach(range=>{shapes=[...shapes,...shapesFromRange(state,range)];});brushFromShape(state,shapes);}function getBubbleLabel(state,value,range){const min=Math.min(...range);const max=Math.max(...range);const shapeAt={x:state.direction?min+state.rect.x:state.rect.x,y:state.direction?state.rect.y:min+state.rect.y,width:state.direction?max-min:state.rect.width+state.rect.x,height:state.direction?state.rect.height+state.rect.y:max-min};const shapes=state.chart.shapesAt(shapeAt,state.settings.brush);if(shapes.length===0){return '-';}const labelShape=shapes.reduce((s0,s1)=>{// Min value
	const bounds0=s0.bounds;const bounds1=s1.bounds;if(value===min){if(bounds0[state.cssCoord.coord]<=bounds1[state.cssCoord.coord]){return s0;}return s1;}// Max value
	if(bounds0[state.cssCoord.coord]+bounds0[state.cssCoord.area]>=bounds1[state.cssCoord.coord]+bounds1[state.cssCoord.area]){return s0;}return s1;});const compConfig=state.settings.brush.components.reduce((c0,c1)=>c0.key===labelShape.key?c0:c1);if(typeof state.settings.bubbles.label==='function'){return state.settings.bubbles.label(labelShape.data);}if(Array.isArray(compConfig.data)&&compConfig.data.length){return labelShape.data[compConfig.data[0]].label;}return labelShape.data&&labelShape.data.label?labelShape.data.label:'-';}/**
	 * @typedef {object} ComponentBrushAreaDir.settings
	 * @property {object} brush
	 * @property {BrushTargetConfig[]} brush.components
	 * @property {string} [direction=vertical] - Rendering direction [horizontal|vertical]
	 * @property {object} [bubbles]
	 * @property {boolean} [bubbles.show=true] - True to show label bubble, false otherwise
	 * @property {string} [bubbles.align=start] - Where to anchor bubble [start|end]
	 * @property {function} [bubbles.label] - Callback function for the labels
	 * @property {object} [target]
	 * @property {string[]} [target.components] - Render matching overlay on target components
	 *//**
	 * @private
	 * @typedef {object} ComponentBrushAreaDirStyle
	 * @property {object} [bubble]
	 * @property {string} [bubble.fontSize]
	 * @property {string} [bubble.fontFamily]
	 * @property {string} [bubble.fill]
	 * @property {string} [bubble.color]
	 * @property {string} [bubble.stroke]
	 * @property {number} [bubble.strokeWidth]
	 * @property {number} [bubble.borderRadius]
	 * @property {object} [line]
	 * @property {string} [line.stroke]
	 * @property {number} [line.strokeWidth]
	 * @property {object} [target]
	 * @property {string} [target.fill]
	 * @property {number} [target.strokeWidth]
	 * @property {number} [target.opacity]
	 */const brushAreaDirectionalComponent={require:['chart','settings','renderer'],defaultSettings:{settings:{bubbles:{show:true,align:'start'}},style:{bubble:'$label-overlay',line:'$shape-guide--inverted',target:'$selection-area-target'}},renderer:'dom',on:{areaStart(e){this.start(e);},areaMove(e){this.move(e);},areaEnd(e){this.end(e);},areaClear(e){this.clear(e);}},created(){this.state={key:this.settings.key||'brush-area-dir'};},render(h){this.state.rect=this.rect;const stngs=this.settings.settings;const direction=stngs.direction==='vertical'?VERTICAL:HORIZONTAL;const size=this.state.rect[direction===VERTICAL?'height':'width'];const offset=this.renderer.element().getBoundingClientRect();const targets=(stngs.target?stngs.target.components||[stngs.target.component]:[]).map(c=>this.chart.component(c)).filter(c=>!!c&&!!c.rect);const targetRect=targets[0]?targets.slice(1).reduce((prev,curr)=>({x0:Math.min(prev.x0,curr.rect.x),y0:Math.min(prev.y0,curr.rect.y),x1:Math.max(prev.x1,curr.rect.x+curr.rect.width),y1:Math.max(prev.y1,curr.rect.y+curr.rect.height)}),{x0:targets[0].rect.x,y0:targets[0].rect.y,x1:targets[0].rect.x+targets[0].rect.width,y1:targets[0].rect.y+targets[0].rect.height}):null;this.state.targetRect=targetRect?{x:targetRect.x0-this.rect.x,y:targetRect.y0-this.rect.y,width:targetRect.x1-targetRect.x0,height:targetRect.y1-targetRect.y0}:null;this.state.style=this.style;this.state.chart=this.chart;this.state.direction=direction;this.state.settings=stngs;this.state.offset=offset;this.state.rc=rangeCollection();this.state.renderer=this.renderer;this.state.multi=!!stngs.multiple;this.state.h=h;this.state.size=size;this.state.cssCoord={offset:this.state.direction===VERTICAL?'top':'left',coord:this.state.direction===VERTICAL?'y':'x',pos:this.state.direction===VERTICAL?'deltaY':'deltaX',area:this.state.direction===VERTICAL?'height':'width'};this.state.format=function getFormat(v,r){return getBubbleLabel(this,v,r);};return [];},start(e){startArea({e,state:this.state,renderer:this.renderer,ranges:ranges$1,targetSize:TARGET_SIZE});},end(){if(!this.state.started){return;}endArea(this.state,ranges$1);render$b(this.state);},move(e){if(!this.state.started){return;}moveArea(this.state,e);setRanges(this.state);render$b(this.state);},clear(){if(this.state.rc){this.state.rc.clear();}this.state.renderer.render([]);}};/**
	 * @typedef {object} ComponentBrushAreaDir
	 * @extends ComponentSettings
	 * @property {'brush-area-dir'} type component type
	 *//**
	 * @typedef {object} ComponentBrushRange
	 * @extends ComponentSettings
	 * @property {'brush-range'} type component type
	 */function rangeBrush$1(picasso){picasso.component('brush-range',brushRangeComponent);picasso.component('brush-area-dir',brushAreaDirectionalComponent);}const FILL='#ccc';const OPACITY=1;function ranges(state){const brush=state.brush;if(!brush||!brush.isActive()){return [];}const sourceData=state.scale.data();const sourceFields=sourceData?sourceData.fields||[]:[];const sources=sourceFields.map(field=>field.id());const rangeBrush=brush.brushes().filter(f=>f.type==='range'&&sources.indexOf(f.id)!==-1)[0];if(!rangeBrush){return [];}return rangeBrush.brush.ranges();}function shapes(state){const isVertical=state.direction==='vertical';const size=state.rect[isVertical?'height':'width'];const otherSize=state.rect[isVertical?'width':'height'];return ranges(state).map(range=>{const start=state.scale(range.min)*size;const end=state.scale(range.max)*size;const low=Math.min(start,end);const s=Math.abs(start-end);return {type:'rect',fill:state.fill,opacity:state.opacity,x:isVertical?0:low,width:isVertical?otherSize:s,y:isVertical?low:0,height:isVertical?s:otherSize};});}function onStart(state){state.renderer.render(shapes(state));}function onUpdate(state){state.renderer.render(shapes(state));}function onEnd(state){state.renderer.render(shapes(state));}function setup$1(state,brush,scale,renderer){state.brush=brush;if(!brush){return;}function start(){onStart(state);}function update(){onUpdate(state);}function end(){onEnd(state);}brush.on('start',start);brush.on('update',update);brush.on('end',end);state.start=start;state.update=update;state.end=end;state.brush=brush;state.scale=scale;state.renderer=renderer;}function teardown(state){if(state.brush){state.brush.removeListener('start',state.start);state.brush.removeListener('update',state.update);state.brush.removeListener('end',state.end);}state.start=undefined;state.update=undefined;state.end=undefined;state.brush=undefined;state.scale=undefined;state.renderer=undefined;}/**
	 * @private
	 * @typedef {object} ComponentRange
	 * @extends ComponentSettings
	 *//**
	 * @typedef {object} ComponentRange.settings
	 * @property {string} brush - Name of brush instance
	 * @property {string} scale - Name of a scale
	 * @property {string} [direction='horizontal'] - Direction of the brush
	 * @property {string} [fill='#ccc'] - Fill color
	 * @property {number} [opacity=1] - Layer opacity
	 */const rangeComponent={require:['chart','settings','renderer'],defaultSettings:{settings:{}},preferredSize:()=>50,created(){this.state={};},render(){const stngs=this.settings.settings;const brush=this.chart.brush(stngs.brush);const direction=stngs.direction||'horizontal';const distance=direction==='horizontal'?this.rect.width:this.rect.height;const scale=scaleWithSize(this.chart.scale(stngs.scale),distance);teardown(this.state);setup$1(this.state,brush,scale,this.renderer);this.state.rect=this.rect;this.state.fill=stngs.fill||FILL;this.state.opacity=typeof stngs.opacity!=='undefined'?stngs.opacity:OPACITY;this.state.direction=direction;return shapes(this.state);},beforeDestroy(){teardown(this.state);}};function rangeBrush(picasso){picasso.component('range',rangeComponent);}function getPoint(rendererBounds,event){const eventOffsetX=event.center.x;const eventOffsetY=event.center.y;return {x:eventOffsetX-rendererBounds.left,y:eventOffsetY-rendererBounds.top};// return {
	//   x: Math.min(Math.max(eventOffsetX - rendererBounds.left, 0), rendererBounds.width),
	//   y: Math.min(Math.max(eventOffsetY - rendererBounds.top, 0), rendererBounds.height)
	// };
	}function withinThreshold(p,state,settings){const startPoint=state.points[0];const sqrDist=sqrDistance(p,startPoint);return sqrDist<settings.settings.snapIndicator.threshold**2;}function appendToPath(state,p){if(state.path.d==null){state.path.d="M".concat(p.x," ").concat(p.y," ");}else {state.path.d+="L".concat(p.x," ").concat(p.y," ");}state.points.push(p);}function render$a(state,renderer){const nodes=[state.startPoint,state.path,state.snapIndicator].filter(node=>node.visible);renderer.render(nodes);}function setSnapIndictor(_ref){let{state,start=null,end=null}=_ref;if(start!==null){state.snapIndicator.x1=start.x;state.snapIndicator.y1=start.y;}if(end!==null){state.snapIndicator.x2=end.x;state.snapIndicator.y2=end.y;}}function showSnapIndicator(state,show){state.snapIndicator.visible=show;}function setStartPoint(state,p){state.startPoint.cx=p.x;state.startPoint.cy=p.y;}function getComponentDelta(chart,rendererBounds){const chartBounds=chart.element.getBoundingClientRect();return {x:rendererBounds.left-chartBounds.left,y:rendererBounds.top-chartBounds.top};}function doLineBrush(state,chart){if(state.active){const p1=state.points[state.points.length-2];const p2=state.points[state.points.length-1];state.lineBrushShape.x1=p1.x+state.componentDelta.x;state.lineBrushShape.y1=p1.y+state.componentDelta.y;state.lineBrushShape.x2=p2.x+state.componentDelta.x;state.lineBrushShape.y2=p2.y+state.componentDelta.y;const shapes=chart.shapesAt(state.lineBrushShape,{components:state.brushConfig});chart.brushFromShapes(shapes,{components:state.brushConfig});}}function doPolygonBrush(state,chart){if(state.active){const dx=state.componentDelta.x;const dy=state.componentDelta.y;const vertices=state.points.map(p=>({x:p.x+dx,y:p.y+dy}));const shapes=chart.shapesAt({vertices},{components:state.brushConfig});chart.brushFromShapes(shapes,{components:state.brushConfig});}}function initPath(stgns){return {visible:true,type:'path',d:null,fill:stgns.fill,stroke:stgns.stroke,strokeWidth:stgns.strokeWidth,opacity:stgns.opacity,strokeDasharray:stgns.strokeDasharray,collider:{type:null}};}function initSnapIndicator(stgns){return {visible:false,type:'line',x1:0,y1:0,x2:0,y2:0,strokeDasharray:stgns.strokeDasharray,stroke:stgns.stroke,strokeWidth:stgns.strokeWidth,opacity:stgns.opacity,collider:{type:null}};}function initStartPoint(stgns){return {visible:true,type:'circle',cx:0,cy:0,r:stgns.r,fill:stgns.fill,opacity:stgns.opacity,stroke:stgns.stroke,strokeWidth:stgns.strokeWidth,collider:{type:null}};}function getBrushConfig$1(settings){return settings.settings.brush.components.map(b=>({key:b.key,contexts:b.contexts||['lassoBrush'],data:b.data||[''],action:b.action||'add'}));}function endBrush(state,chart){state.brushConfig.forEach(config=>{config.contexts.forEach(context=>{chart.brush(context).end();});});}function resetState$1(){return {points:[],active:false,path:null,snapIndicator:null,startPoint:null,rendererBounds:null,componentDelta:null,brushConfig:null,lineBrushShape:{x1:0,y1:0,x2:0,y2:0}// Keep a single shape instance to avoid instantiating a new object on each lookup
	};}/**
	 * @typedef {object} ComponentBrushLasso
	 * @extends ComponentSettings
	 * @property {'brush-lasso'} type component type
	 * @example
	 * {
	 *  type: 'brush-lasso',
	 *  settings: {
	 *    brush: {
	 *      components: [{ key: '<target-component>', contexts: ['<brush-context>'] }]
	 *    }
	 *  },
	 * }
	 *//**
	 * Component settings
	 * @typedef {object} ComponentBrushLasso.settings
	 * @property {object} [lasso] - Lasso style settings
	 * @property {string} [lasso.fill='transparent']
	 * @property {string} [lasso.stroke='black']
	 * @property {number} [lasso.strokeWidth=2]
	 * @property {number} [lasso.opacity=0.7]
	 * @property {number} [lasso.strokeDasharray]
	 * @property {object} [snapIndicator] - Snap indicator settings
	 * @property {number} [snapIndicator.threshold=75] - The distance in pixel to show the snap indicator, if less then threshold the indicator is dispalyed
	 * @property {string} [snapIndicator.strokeDasharray='5, 5']
	 * @property {string} [snapIndicator.stroke='black']
	 * @property {number} [snapIndicator.strokeWidth=2]
	 * @property {number} [snapIndicator.opacity=0.5]
	 * @property {object} [startPoint] - Start point style settings
	 * @property {number} [startPoint.r=10] - Circle radius
	 * @property {string} [startPoint.stroke='green']
	 * @property {number} [startPoint.strokeWidth=1]
	 * @property {number} [startPoint.opacity=1]
	 * @property {object} [brush]
	 * @property {object[]} brush.components - Array of components to brush on.
	 * @property {string} [brush.components[].component.key] - Component key
	 * @property {string[]} [brush.components[].component.contexts=['brushLasso']] - Name of the brushing contexts to affect
	 * @property {string[]} [brush.components[].component.data=['']] - The mapped data properties to add to the brush
	 * @property {string} [brush.components[].component.action='add'] - Type of action to respond with
	 */const brushLassoComponent={require:['chart','renderer','settings'],defaultSettings:{layout:{displayOrder:0},settings:{brush:{components:[]},snapIndicator:{threshold:75,strokeDasharray:'5, 5',stroke:'black',strokeWidth:2,opacity:0.5},lasso:{fill:'transparent',stroke:'black',strokeWidth:2,opacity:0.7,strokeDasharray:'20, 10'},startPoint:{r:10,fill:'green',stroke:'black',strokeWidth:1,opacity:1}}},on:{lassoStart(e){this.start(e);},lassoEnd(e){this.end(e);},lassoMove(e){this.move(e);},lassoCancel(){this.cancel();}},created(){this.state=resetState$1();},start(e){this.state.active=true;this.state.path=initPath(this.settings.settings.lasso);this.state.snapIndicator=initSnapIndicator(this.settings.settings.snapIndicator);this.state.startPoint=initStartPoint(this.settings.settings.startPoint);this.state.rendererBounds=this.renderer.element().getBoundingClientRect();this.state.componentDelta=getComponentDelta(this.chart,this.state.rendererBounds);this.state.brushConfig=getBrushConfig$1(this.settings);const p=getPoint(this.state.rendererBounds,e);appendToPath(this.state,p);setSnapIndictor({state:this.state,start:p});setStartPoint(this.state,p);},move(e){if(!this.state.active){return;}const p=getPoint(this.state.rendererBounds,e);if(withinThreshold(p,this.state,this.settings)){showSnapIndicator(this.state,true);}else {showSnapIndicator(this.state,false);}appendToPath(this.state,p);setSnapIndictor({state:this.state,end:p});render$a(this.state,this.renderer);doLineBrush(this.state,this.chart);},end(e){if(!this.state.active){return;}showSnapIndicator(this.state,false);const p=getPoint(this.state.rendererBounds,e);const shouldSnap=withinThreshold(p,this.state,this.settings);if(shouldSnap){doPolygonBrush(this.state,this.chart);}this.state=resetState$1();this.renderer.render([]);},cancel(){if(!this.state.active){return;}endBrush(this.state,this.chart);this.state=resetState$1();this.renderer.render([]);},render(){// Do nothing
	}};function lassoBrush(picasso){picasso.component('brush-lasso',brushLassoComponent);}/**
	 * Using the basic example found here: https://en.wikipedia.org/wiki/Binary_search_algorithm
	 *
	 * Finds the first node that may intersect the label.
	 * @private
	 */function binaryLeftSearch(labelBounds,ary,coord,side,extractBounds){let left=0;let right=ary.length-1;let bounds;while(left<right){let m=Math.floor((left+right)/2);bounds=extractBounds(ary[m]);if(bounds[coord]+bounds[side]<labelBounds[coord]){// label is on right side
	left=m+1;}else {// label is on the left side
	right=m;}}return left;}/**
	 * The purpose of this module is to act as a filtering function to remove any labels
	 * that meets one of the following criterias:
	 * -- The label is not fully inside the container, such that it would be fully or partially clipped if rendered
	 * -- The label overlaps another label
	 * -- The label overlaps another bar which is not the bar the label is originating from
	 *
	 * Assumes that the nodes are sorted from left/top to right/down, as that allows
	 * some optimizations to be performed.
	 * @private
	 * @returns {function} Filter function, returns false if label be removed and true otherwise
	 */function filterOverlappingLabels(_ref){let{orientation,targetNodes,labels,container}=_ref;let findLeft=arguments.length>1&&arguments[1]!==undefined?arguments[1]:binaryLeftSearch;const renderLabels=[];const coord=orientation==='v'?'x':'y';const side=orientation==='v'?'width':'height';const getTextBounds=item=>item.textBounds;const getNodeBounds=item=>item.node.localBounds;return (doNotUse,labelIndex)=>{const{textBounds:labelBounds,node:labelNode}=labels[labelIndex];// ### Test if label is not fully inside container based on the orientation ###
	if(labelBounds[coord]<container[coord]||labelBounds[coord]+labelBounds[side]>container[coord]+container[side]){return false;}// ### Test label to label collision ###
	const leftStartLabel=findLeft(labelBounds,renderLabels,coord,side,getTextBounds);for(let i=leftStartLabel;i<renderLabels.length;i++){if(testRectRect(labelBounds,renderLabels[i].textBounds)){return false;}}// ### Test label to node collision ###
	const leftStartNode=findLeft(labelBounds,targetNodes,coord,side,getNodeBounds);const labelRightBoundary=labelBounds[coord]+labelBounds[side];for(let i=leftStartNode;i<targetNodes.length;i++){const node=targetNodes[i].node;// Do not test beyond this node, as they are assumed to not collide with the label
	if(labelRightBoundary<node.localBounds[coord]){break;}if(testRectRect(labelBounds,node.localBounds)&&labelNode!==node){return false;}}// No collision occured, allow the label to be rendered
	renderLabels.push(labels[labelIndex]);return true;};}const PADDING=4;// const DOUBLE_PADDING = PADDING * 2;
	function cbContext$2(node,chart){return {node,data:node.data,scale:chart.scale,formatter:chart.formatter,dataset:chart.dataset};}function isValidText(text){const type=typeof text;return (type==='string'||type==='number')&&text!=='';}function toBackground(label){return _objectSpread2$1(_objectSpread2$1({type:'rect',rx:2,ry:2,fill:label.backgroundColor},label.backgroundBounds),{},{data:"".concat(label.data," ").concat(label.text),rotation:label.transform&&label.transform.match(/rotate/gi)?'rotated':'horizontal'});}function isTextWidthInRectWidth(rect,label,rotate){return rotate?rect.width>=label.height:rect.width>=label.width;}function isTextHeightInRectHeight(rect,label,rotate){return rotate?rect.height>=label.width:rect.height>=label.height;}function isGoodPlacement(orientation,rect,label,fitsHorizontally,overflow){let fitWidth;let fitHeight;if(orientation==='v'){fitWidth=fitsHorizontally||overflow||isTextWidthInRectWidth(rect,label,true);fitHeight=isTextHeightInRectHeight(rect,label,!fitsHorizontally);}else {fitWidth=isTextWidthInRectWidth(rect,label);fitHeight=overflow||isTextHeightInRectHeight(rect,label,false);}return fitWidth&&fitHeight;}function isTextInRect(rect,label,opts){return isTextWidthInRectWidth(rect,label,opts.rotate)&&isTextHeightInRectHeight(rect,label,opts.rotate);}function placeSegmentInSegment(majorSegmentPosition,majorSegmentSize,minorSegmentSize,align){const majorSegmentCenter=majorSegmentPosition+majorSegmentSize*0.5;const offset=(align-0.5)*(majorSegmentSize-minorSegmentSize);const minorSegmentCenter=majorSegmentCenter+offset;const minorSegmentPosition=minorSegmentCenter-minorSegmentSize*0.5;return minorSegmentPosition;}function placeTextInRect$2(rect,text,opts){const label={type:'text',text,maxWidth:opts.rotate?rect.height:rect.width,x:0,y:rect.y,dx:0,dy:0,fill:opts.fill,anchor:opts.rotate?'end':'start',baseline:'central',fontSize:"".concat(opts.fontSize,"px"),fontFamily:opts.fontFamily};const textMetrics=opts.textMetrics;if(!opts.overflow&&!isTextInRect(rect,textMetrics,opts)){return false;}const baseLineOffset=textMetrics.height*0.5;if(opts.rotate){label.x=placeSegmentInSegment(rect.x,rect.width,textMetrics.height,opts.align)+baseLineOffset;label.y=placeSegmentInSegment(rect.y,rect.height,textMetrics.width,opts.justify);if(opts.dock==='right'){label.transform="rotate(90, ".concat(label.x+label.dx,", ").concat(label.y+label.dy,") translate(").concat(textMetrics.width,", 0)");}else {label.transform="rotate(-90, ".concat(label.x+label.dx,", ").concat(label.y+label.dy,")");}}else {label.x=placeSegmentInSegment(rect.x,rect.width,textMetrics.width,opts.align);label.y=placeSegmentInSegment(rect.y,rect.height,textMetrics.height,opts.justify)+baseLineOffset;}return label;}function limitBounds(bounds,view){const minY=Math.max(0,Math.min(bounds.y,view.height));const maxY=Math.max(0,Math.min(bounds.y+bounds.height,view.height));const minX=Math.max(0,Math.min(bounds.x,view.width));const maxX=Math.max(0,Math.min(bounds.x+bounds.width,view.width));bounds.x=minX;bounds.width=maxX-minX;bounds.y=minY;bounds.height=maxY-minY;}function pad$1(bounds,measured){let padding=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const{top=PADDING,bottom=PADDING,left=PADDING,right=PADDING}=padding;const leftPadding=typeof left==='function'?left(measured):left;const rightPadding=typeof right==='function'?right(measured):right;const topPadding=typeof top==='function'?top(measured):top;const bottomPadding=typeof bottom==='function'?bottom(measured):bottom;bounds.x+=leftPadding;bounds.width-=leftPadding+rightPadding;bounds.y+=topPadding;bounds.height-=topPadding+bottomPadding;}function getBarRect(_ref){let{bar,view,direction,position,padding=PADDING,measured}=_ref;const bounds={};extend$1$1(bounds,bar);if(!position||position==='inside');else if(direction==='up'||direction==='down'){const start=Math.max(0,Math.min(bar.y,view.height));const end=Math.max(0,Math.min(bar.y+bar.height,view.height));if(position==='outside'&&direction==='up'||position==='opposite'&&direction==='down'){bounds.y=0;bounds.height=start;}else if(position==='outside'&&direction==='down'||position==='opposite'&&direction==='up'){bounds.y=end;bounds.height=view.height-end;}}else {const start=Math.max(0,Math.min(bar.x,view.width));const end=Math.max(0,Math.min(bar.x+bar.width,view.width));if(position==='outside'&&direction==='left'||position==='opposite'&&direction==='right'){bounds.x=0;bounds.width=start;}else if(position==='outside'&&direction==='right'||position==='opposite'&&direction==='left'){bounds.x=end;bounds.width=view.width-end;}}limitBounds(bounds,view);pad$1(bounds,measured,padding);return bounds;}function findBestPlacement$1(_ref2){let{direction,fitsHorizontally,// lblStngs,
	measured,node,orientation,// placements,
	placementSettings,rect}=_ref2;let barRect=arguments.length>1&&arguments[1]!==undefined?arguments[1]:getBarRect;let largest;let bounds;let placement;let testBounds;let p;const boundaries=[];const dimension=orientation==='h'?'width':'height';for(p=0;p<placementSettings.length;p++){placement=placementSettings[p];testBounds=barRect({bar:node.localBounds,view:rect,direction,position:placement.position,padding:placement.padding,measured});boundaries.push(testBounds);largest=!p||testBounds[dimension]>largest[dimension]?testBounds:largest;if(isGoodPlacement(orientation,testBounds,measured,fitsHorizontally,placement.overflow)){bounds=testBounds;break;}}// fallback strategy - place the text in the largest rectangle
	if(!bounds){bounds=largest;p=boundaries.indexOf(bounds);}placement=placementSettings[p];return {bounds,placement};}function approxTextBounds(label,textMetrics,rotated,rect){let padding=arguments.length>4&&arguments[4]!==undefined?arguments[4]:{};const{top=PADDING,bottom=PADDING,left=PADDING,right=PADDING}=padding;const leftPadding=typeof left==='function'?left(textMetrics):left;const rightPadding=typeof right==='function'?right(textMetrics):right;const topPadding=typeof top==='function'?top(textMetrics):top;const bottomPadding=typeof bottom==='function'?bottom(textMetrics):bottom;const x0=label.x+label.dx;const y0=label.y+label.dy;const height=rotated?Math.min(textMetrics.width,rect.height):Math.min(textMetrics.height,rect.width);const width=rotated?Math.min(textMetrics.height,rect.height):Math.min(textMetrics.width,rect.width);const offset=textMetrics.height*0.5;const PADDING_OFFSET=1e-9;// Needed to support a case when multiple bars are on the same location
	const x=rotated?x0-offset:x0;const y=rotated?y0:y0-offset;const bounds={x:x-leftPadding-PADDING_OFFSET,y:y-topPadding-PADDING_OFFSET,width:width+(leftPadding+rightPadding)-PADDING_OFFSET,height:height+(topPadding+bottomPadding)-PADDING_OFFSET};return bounds;}function placeInBars(_ref3){let{chart,targetNodes,rect,fitsHorizontally,collectiveOrientation}=_ref3;let findPlacement=arguments.length>1&&arguments[1]!==undefined?arguments[1]:findBestPlacement$1;let placer=arguments.length>2&&arguments[2]!==undefined?arguments[2]:placeTextInRect$2;let postFilter=arguments.length>3&&arguments[3]!==undefined?arguments[3]:filterOverlappingLabels;const labels=[];const postFilterContext={container:rect,targetNodes,labels:[],orientation:collectiveOrientation};let label;let target;let node;let text;let justify;let bounds;let fill;let measured;let direction;let lblStngs;let placement;let placements;let arg;let orientation;for(let i=0,len=targetNodes.length;i<len;i++){bounds=null;target=targetNodes[i];node=target.node;arg=cbContext$2(node,chart);direction=target.direction;orientation=direction==='left'||direction==='right'?'h':'v';for(let j=0;j<target.texts.length;j++){text=target.texts[j];if(!isValidText(text)){continue;}lblStngs=target.labelSettings[j];measured=target.measurements[j];placements=lblStngs.placements;const bestPlacement=findPlacement({direction,fitsHorizontally,lblStngs,measured,node,orientation,placements,placementSettings:target.placementSettings[j],rect});bounds=bestPlacement.bounds;placement=bestPlacement.placement;if(bounds&&placement){var _lblStngs$dock;justify=placement.justify;const linkData=typeof lblStngs.linkData==='function'?lblStngs.linkData(arg,i):undefined;const overflow=typeof placement.overflow==='function'?placement.overflow(arg,i):placement.overflow;if(direction==='up'){justify=1-justify;}if(placement.position==='opposite'){justify=1-justify;}if(direction==='left'){justify=1-justify;}const isRotated=!(collectiveOrientation==='h'||fitsHorizontally);label=placer(bounds,text,{justify:orientation==='h'?placement.align:justify,align:orientation==='h'?justify:placement.align,fontSize:lblStngs.fontSize,fontFamily:lblStngs.fontFamily,textMetrics:measured,rotate:isRotated,overflow:!!overflow,dock:(_lblStngs$dock=lblStngs.dock)!==null&&_lblStngs$dock!==void 0?_lblStngs$dock:'left'});if(label){const textBounds=approxTextBounds(label,measured,isRotated,bounds,placement.padding);fill=typeof placement.fill==='function'?placement.fill(_objectSpread2$1(_objectSpread2$1({},arg),{},{textBounds}),i):placement.fill;label.fill=fill;if(typeof linkData!=='undefined'){label.data=linkData;}if(typeof placement.background==='object'){label.backgroundColor=typeof placement.background.fill==='function'?placement.background.fill(_objectSpread2$1(_objectSpread2$1({},arg),{},{textBounds}),i):placement.background.fill;if(typeof label.backgroundColor!=='undefined'){label.backgroundBounds=approxTextBounds(label,measured,isRotated,bounds,placement.background.padding);}}labels.push(label);postFilterContext.labels.push({node,textBounds});}}}}const filteredLabels=labels.filter(postFilter(postFilterContext));const backgrounds=filteredLabels.filter(lb=>typeof lb.backgroundBounds!=='undefined').map(toBackground);return [...backgrounds,...filteredLabels];}function precalculate(_ref4){let{nodes,rect,chart,labelSettings,placementSettings,settings,renderer}=_ref4;const labelStruct={};const targetNodes=[];let target;let fitsHorizontally=true;let hasHorizontalDirection=false;let node;let text;let bounds;let measured;let lblStng;let direction;for(let i=0;i<nodes.length;i++){node=nodes[i];bounds=node.localBounds;if(!testRectRect(bounds,rect)){continue;}let arg=cbContext$2(node,chart);target={node,texts:[],measurements:[],labelSettings:[],placementSettings:[]// direction: 'up'
	};for(let j=0;j<labelSettings.length;j++){lblStng=labelSettings[j];text=typeof lblStng.label==='function'?lblStng.label(arg,i):undefined;if(!isValidText(text)){continue;// eslint-ignore-line
	}direction=typeof settings.direction==='function'?settings.direction(arg,i):settings.direction||'up';hasHorizontalDirection=hasHorizontalDirection||direction==='left'||direction==='right';labelStruct.fontFamily=lblStng.fontFamily;labelStruct.fontSize="".concat(lblStng.fontSize,"px");labelStruct.text=text;measured=renderer.measureText(labelStruct);target.measurements.push(measured);target.texts.push(text);target.labelSettings.push(lblStng);target.placementSettings.push(placementSettings[j]);target.direction=direction;fitsHorizontally=fitsHorizontally&&measured.width<=bounds.width-PADDING*2;}targetNodes.push(target);}return {targetNodes,fitsHorizontally,hasHorizontalDirection};}function getOrientation(_ref5){let{orientation='auto',defaultOrientation='h'}=_ref5;switch(orientation.toLocaleLowerCase()){case 'vertical':return 'v';case 'horizontal':return 'h';default:return defaultOrientation;}}/**
	 * @typedef {object} ComponentLabels~BarsLabelStrategy
	 * @property {'bar'} type Name of strategy
	 *//**
	 * Bars strategy settings
	 * @typedef {object} ComponentLabels~BarsLabelStrategy.settings
	 * @property {string|function} [direction='up'] - The direction in which the bars are growing: 'up', 'down', 'right' or 'left'.
	 * @property {string} [orientation='auto'] - Orientation of text: 'auto', 'horizontal' or 'vertical'
	 * @property {string} [fontFamily='Arial']
	 * @property {number} [fontSize=12]
	 * @property {Array<object>} labels
	 * @property {string|function} labels[].label - The text value
	 * @property {function} labels[].linkData - Link data to the label
	 * @property {string} [labels[].dock='left'] - When orientation is vertical, the label can be docked to the left or right of the bar. 'left' | 'right'.
	 * @property {Array<object>} labels[].placements
	 * @property {string} labels[].placements[].position - 'inside' | 'outside' | 'opposite'
	 * @property {number} [labels[].placements[].justify=0] - Placement of the label along the direction of the bar
	 * @property {number} [labels[].placements[].align=0.5] - Placement of the label along the perpendicular direction of the bar
	 * @property {string} [labels[].placements[].fill='#333'] - Color of the label
	 * @property {boolean} [labels[].placements[].overflow=false] - True if the label is allowed to overflow the bar
	 * @property {object} labels[].placements[].padding - Padding between the label and the bar
	 * @property {number|function} [labels[].placements[].padding.top=4] - Padding-top between the label and the bar. Can be a function, text dimensions object {width, height} is exposed as argument.
	 * @property {number|function} [labels[].placements[].padding.bottom=4] - Padding-bottom between the label and the bar. Can be a function, text dimensions object {width, height} is exposed as argument.
	 * @property {number|function} [labels[].placements[].padding.left=4] - Padding-left between the label and the bar. Can be a function, text dimensions object {width, height} is exposed as argument.
	 * @property {number|function} [labels[].placements[].padding.right=4] - Padding-right between the label and the bar. Can be a function, text dimensions object {width, height} is exposed as argument.
	 * @property {object} labels[].placements[].background - Background of the label
	 * @property {string|function} labels[].placements[].background.fill - Background color of the label
	 * @property {object} labels[].placements[].background.padding - Padding between the label and the background
	 * @property {number} [labels[].placements[].background.padding.top=4] - Padding-top between the label and the background
	 * @property {number} [labels[].placements[].background.padding.bottom=4] - Padding-bottom between the label and the background
	 * @property {number} [labels[].placements[].background.padding.left=4] - Padding-left between the label and the background
	 * @property {number} [labels[].placements[].background.padding.right=4] - Padding-right between the label and the background
	 */function bars(_ref6){let{settings,chart,nodes,rect,renderer,style}=_ref6;let placer=arguments.length>1&&arguments[1]!==undefined?arguments[1]:placeInBars;const defaults=extend$1$1({fontSize:12,fontFamily:'Arial',align:0.5,justify:0,fill:'#333'},style.label);defaults.fontSize=parseInt(defaults.fontSize,10);const labelSettings=settings.labels.map(labelSetting=>extend$1$1({},defaults,settings,labelSetting));const placementSettings=settings.labels.map(labelSetting=>labelSetting.placements.map(placement=>extend$1$1({},defaults,settings,labelSetting,placement)));const{fitsHorizontally,hasHorizontalDirection,targetNodes}=precalculate({nodes,chart,renderer,settings,rect,labelSettings,placementSettings});const orientation=getOrientation({orientation:settings.orientation,defaultOrientation:hasHorizontalDirection?'h':'v'});const coord=orientation==='h'?'y':'x';const side=orientation==='h'?'height':'width';targetNodes.sort((a,b)=>a.node.localBounds[coord]+a.node.localBounds[side]-(b.node.localBounds[coord]+b.node.localBounds[side]));return placer({chart,targetNodes,stngs:settings,rect,fitsHorizontally,collectiveOrientation:orientation});}const LABEL_OVERLAP_THRESHOLD_X=4;// When a label is animated, the label rect width should be bit larger than the measured text width,
	// otherwise the animated label will be ellipsed.
	const LABEL_RECT_WIDTH_PADDING=1;function normalize$2(angle){const PI2=Math.PI*2;return (angle%PI2+PI2)%PI2;// normalize
	}function pad$3(bounds,padding){bounds.x+=padding;bounds.width-=padding*2;bounds.y+=padding;bounds.height-=padding*2;}function getTopLeftBounds(bounds){const x=bounds.x;const y=bounds.y-bounds.height/2;return {x,y,width:bounds.width,height:bounds.height};}// assume 0 <= angle < (PI / 2)
	function getLineCircleIntersection(radius,offset,angle){let{x,y}=offset;if(x*x+y*y>radius*radius){return null;}let dx=Math.sin(angle);let dy=Math.cos(angle);let D=x*dy-y*dx;let d=radius*radius-D*D;if(d<0){return null;}let sqrtD=Math.sqrt(d);return {x:D*dy+dx*sqrtD,y:-(D*dx)+dy*sqrtD};}// assume 0 <= angle < (PI * 2)
	function getRectFromCircleIntersection(_ref){let{radius,size,angle}=_ref;let{width,height}=size;let lineOffset={x:width/2,y:height/2};let section=Math.floor(angle/(Math.PI/2));let intersection;let offset;switch(section){case 0:intersection=getLineCircleIntersection(radius,lineOffset,angle);if(!intersection){return null;}intersection.y*=-1;offset={x:-width,y:0};break;case 1:intersection=getLineCircleIntersection(radius,lineOffset,Math.PI-angle);if(!intersection){return null;}offset={x:-width,y:-height};break;case 2:intersection=getLineCircleIntersection(radius,lineOffset,angle-Math.PI);if(!intersection){return null;}intersection.x*=-1;offset={x:0,y:-height};break;case 3:intersection=getLineCircleIntersection(radius,lineOffset,2*Math.PI-angle);if(!intersection){return null;}intersection.x*=-1;intersection.y*=-1;offset={x:0,y:0};break;default:throw new Error('invalid angle');}let bounds={x:intersection.x+offset.x,y:intersection.y+offset.y,width,height};return bounds;}function getHorizontalInsideSliceRect(_ref2){let{slice,padding,measured,store}=_ref2;const{start,end,outerRadius}=slice;const middle=normalize$2((start+end)/2);const size={width:measured.width+padding*2+LABEL_RECT_WIDTH_PADDING,height:measured.height+padding*2};let bounds=getRectFromCircleIntersection({radius:outerRadius,size,angle:middle});if(!bounds){return null;}bounds.baseline='top';pad$3(bounds,padding);if(store.insideLabelBounds.some(rect=>testRectRect(rect,bounds))){return null;}store.insideLabelBounds.push({x:bounds.x-LABEL_OVERLAP_THRESHOLD_X,y:bounds.y,width:bounds.width+LABEL_OVERLAP_THRESHOLD_X*2,height:bounds.height});// Copy as bounds is mutated else where
	return bounds;}function getHorizontalIntoSliceRect(_ref3){let{slice,padding,measured}=_ref3;let{start,end,innerRadius,outerRadius}=slice;const middle=normalize$2((start+end)/2);let size={width:measured.width+padding*2+LABEL_RECT_WIDTH_PADDING,height:measured.height+padding*2};let bounds=getRectFromCircleIntersection({radius:outerRadius,size,angle:middle});if(!bounds){return null;}bounds.baseline='top';let startLine={x1:0,y1:0,x2:Math.sin(start)*outerRadius,y2:-Math.cos(start)*outerRadius};if(testRectLine(bounds,startLine)){return null;}let endLine={x1:0,y1:0,x2:Math.sin(end)*outerRadius,y2:-Math.cos(end)*outerRadius};if(testRectLine(bounds,endLine)){return null;}let circle={cx:0,cy:0,r:innerRadius};if(testCircleRect(circle,bounds)){return null;}pad$3(bounds,padding);return bounds;}// TODO: this case can support a justify setting
	function getRotatedInsideSliceRect(_ref4){let{slice,measured,padding}=_ref4;let{start,end,innerRadius,outerRadius}=slice;let maxWidth=outerRadius-innerRadius-padding*2;let size=end-start;if(size<Math.PI){let x=(measured.height/2+padding)/Math.tan(size/2);if(x>innerRadius){maxWidth=outerRadius-x-padding*2;}}if(maxWidth<0||maxWidth<measured.minReqWidth){return null;}const middle=normalize$2((start+end)/2);let r=outerRadius-padding;let bounds={x:Math.sin(middle)*r,y:-Math.cos(middle)*r,width:maxWidth,height:measured.height};if(middle<Math.PI){bounds.angle=middle-Math.PI/2;bounds.anchor='end';}else {bounds.angle=middle+Math.PI/2;bounds.anchor='start';}return bounds;}function getRotatedOusideSliceRect(_ref5){let{slice,measured,padding,view}=_ref5;let{start,end,outerRadius,offset}=slice;let r=outerRadius+padding;let size=end-start;if(size<Math.PI){let minR=(measured.height/2+padding)/Math.tan(size/2);if(minR>r){return null;}}const middle=normalize$2((start+end)/2);let x=Math.sin(middle)*r;let y=-Math.cos(middle)*r;let maxWidth=measured.width+LABEL_RECT_WIDTH_PADDING;let v=middle%Math.PI;if(v>Math.PI/2){v=Math.PI-v;}if(Math.cos(v)>0.001){let edge=y<0?view.y:view.y+view.height;let d=Math.abs(edge-offset.y);let w=d/Math.cos(v)-Math.tan(v)*(measured.height/2)-padding*2-outerRadius;if(w<maxWidth){maxWidth=w;}}if(Math.sin(v)>0.001){let edge=x<0?view.x:view.x+view.width;let d=Math.abs(edge-offset.x);let w=d/Math.sin(v)-measured.height/2/Math.tan(v)-padding*2-outerRadius;if(w<maxWidth){maxWidth=w;}}if(maxWidth<=0||maxWidth<measured.minReqWidth){return null;}let bounds={x,y,width:maxWidth,height:measured.height};if(middle<Math.PI){bounds.angle=middle-Math.PI/2;bounds.anchor='start';}else {bounds.angle=middle+Math.PI/2;bounds.anchor='end';}return bounds;}function outOfSpace(context,section,view){switch(section){case 0:return context.q1maxY<0;case 1:return context.q2minY>view.height;case 2:return context.q3minY>view.height;case 3:return context.q4maxY<0;default:return true;}}function adjustBounds(bounds,context,slice){const LINE_PADDING=2;const LIMIT=1;const{start,end,offset,outerRadius}=slice;const middle=normalize$2((start+end)/2);let section=Math.floor(middle/(Math.PI/2));switch(section){case 0:if(context.q1maxY!==undefined){let y=Math.min(bounds.y,context.q1maxY-bounds.height);let dy=bounds.y-y;bounds.y=y;if(dy>LIMIT){let r=outerRadius+LINE_PADDING;bounds.line={type:'line',x1:bounds.x-LINE_PADDING,y1:bounds.y+LINE_PADDING,x2:offset.x+Math.sin(middle)*r,y2:offset.y-Math.cos(middle)*r,strokeWidth:1};}}break;case 1:if(context.q2minY!==undefined){let y=Math.max(bounds.y,context.q2minY);let dy=y-bounds.y;bounds.y=y;if(dy>LIMIT){let r=outerRadius+LINE_PADDING;bounds.line={type:'line',x1:bounds.x-LINE_PADDING,y1:bounds.y-LINE_PADDING,x2:offset.x+Math.sin(middle)*r,y2:offset.y-Math.cos(middle)*r,strokeWidth:1};}}break;case 2:if(context.q3minY!==undefined){let y=Math.max(bounds.y,context.q3minY);let dy=y-bounds.y;bounds.y=y;if(dy>LIMIT){let r=outerRadius+LINE_PADDING;bounds.line={type:'line',x1:bounds.x+LINE_PADDING,y1:bounds.y-LINE_PADDING,x2:offset.x+Math.sin(middle)*r,y2:offset.y-Math.cos(middle)*r,strokeWidth:1};}}break;case 3:if(context.q4maxY!==undefined){let y=Math.min(bounds.y,context.q4maxY-bounds.height);let dy=bounds.y-y;bounds.y=y;if(dy>LIMIT){let r=outerRadius+LINE_PADDING;bounds.line={type:'line',x1:bounds.x+LINE_PADDING,y1:bounds.y+LINE_PADDING,x2:offset.x+Math.sin(middle)*r,y2:offset.y-Math.cos(middle)*r,strokeWidth:1};}}break;}}function updateContext(_ref6){let{context,node,bounds}=_ref6;const PADDING=2;let{start,end}=node.desc.slice;const middle=normalize$2((start+end)/2);let section=Math.floor(middle/(Math.PI/2));switch(section){case 0:context.q1maxY=bounds.y-PADDING;if(context.q2minY===undefined){context.q2minY=bounds.y+bounds.height+PADDING;}break;case 1:context.q2minY=bounds.y+bounds.height+PADDING;break;case 2:context.q3minY=bounds.y+bounds.height+PADDING;break;case 3:context.q4maxY=bounds.y-PADDING;if(context.q3minY===undefined){context.q3minY=bounds.y+bounds.height+PADDING;}break;}}function getHorizontalOusideSliceRect(_ref7){let{slice,measured,padding,view,context}=_ref7;let{start,end,outerRadius,offset}=slice;const middle=normalize$2((start+end)/2);let section=Math.floor(middle/(Math.PI/2));if(outOfSpace(context,section,view)){return null;}let r=outerRadius+padding+measured.height/2;let x=Math.sin(middle)*r;let y=-Math.cos(middle)*r;let maxWidth=measured.width+LABEL_RECT_WIDTH_PADDING;if(middle<Math.PI){let w=Math.abs(view.x+view.width-(x+offset.x));if(w<maxWidth){maxWidth=w;}}else {let w=Math.abs(view.x-(x+offset.x));if(w<maxWidth){maxWidth=w;}}if(maxWidth<measured.minReqWidth){return null;}let bounds={x,y,width:maxWidth,height:measured.height};if(middle<Math.PI){bounds.anchor='start';}else {bounds.anchor='end';}return bounds;}function cbContext$1(node,chart){return {node,data:node.data,scale:chart.scale,formatter:chart.formatter,dataset:chart.dataset};}function placeTextOnPoint(rect,text,opts){const label={type:'text',text,maxWidth:rect.width,x:rect.x,y:rect.y+(rect.baseline==='top'?rect.height/2:0),fill:opts.fill,anchor:rect.anchor||'start',baseline:'middle',fontSize:"".concat(opts.fontSize,"px"),fontFamily:opts.fontFamily};if(!isNaN(rect.angle)){let angle=rect.angle*(360/(Math.PI*2));label.transform="rotate(".concat(angle,", ").concat(label.x,", ").concat(label.y,")");}return label;}function getSliceRect(_ref8){let{slice,direction,position,padding,measured,view,context,store}=_ref8;let{start,end,innerRadius,offset}=slice;let bounds;let s;switch(position){case 'into':if(direction==='rotate'){bounds=getRotatedInsideSliceRect({slice,measured,padding});}else {bounds=getHorizontalIntoSliceRect({slice,measured,padding});}break;case 'inside':s={start,end,innerRadius:0,outerRadius:innerRadius};if(direction==='rotate'){bounds=getRotatedInsideSliceRect({slice:s,measured,padding});}else {bounds=getHorizontalInsideSliceRect({slice:s,measured,padding,store});}break;case 'outside':if(direction==='rotate'){bounds=getRotatedOusideSliceRect({slice,measured,padding,view});}else {bounds=getHorizontalOusideSliceRect({slice,measured,padding,view,context});}break;default:throw new Error('not implemented');}if(bounds){bounds.x+=offset.x;bounds.y+=offset.y;if(position==='outside'&&direction!=='rotate'){adjustBounds(bounds,context,slice);}}return bounds;}function findBestPlacement(_ref9){let{context,direction,measured,node,placementSettings,rect,store}=_ref9;let sliceRect=arguments.length>1&&arguments[1]!==undefined?arguments[1]:getSliceRect;for(let p=0;p<placementSettings.length;p++){let placement=placementSettings[p];let bounds=sliceRect({context,slice:node.desc.slice,view:rect,direction,position:placement.position,measured,padding:placement.padding,store});if(!bounds){continue;}return {bounds,placement};}return {bounds:null,placement:null};}/*
	 * Sorts the nodes so that
	 *   in each quarter sort nodes from the center (in y) outwards
	 *   first quarter before the second
	 *   forth quarter before the third
	 */function sortNodes(nodes){const q1=[];const q2=[];const q3=[];const q4=[];for(let i=0;i<nodes.length;++i){const{start,end}=nodes[i].desc.slice;const middle=normalize$2((start+end)/2);let section=Math.floor(middle/(Math.PI/2));switch(section){case 0:q1.push(nodes[i]);break;case 1:q2.push(nodes[i]);break;case 2:q3.push(nodes[i]);break;case 3:q4.push(nodes[i]);break;}}const sortFn=(a,b)=>{const middleA=normalize$2((a.desc.slice.start+a.desc.slice.end)/2);const middleB=normalize$2((b.desc.slice.start+b.desc.slice.end)/2);return middleA-middleB;};const reverseSortFn=(a,b)=>sortFn(b,a);q1.sort(reverseSortFn);q2.sort(sortFn);q3.sort(reverseSortFn);q4.sort(sortFn);return q1.concat(q2,q4,q3);}function measureText$1(text,stgns,renderer){const fontFamily=stgns.fontFamily;const fontSize="".concat(stgns.fontSize,"px");const metrics=renderer.measureText({text,fontFamily,fontSize});metrics.minReqWidth=Math.min(metrics.width,renderer.measureText({text:"".concat(text[0],"\u2026"),fontFamily,fontSize}).width);return metrics;}/**
	 * @typedef {object} ComponentLabels~SlicesLabelStrategy
	 * @property {'slice'} type Name of strategy
	 *//**
	 * Slices strategy settings
	 * @typedef {object} ComponentLabels~SlicesLabelStrategy.settings
	 * @property {string|function} [direction='horizontal'] - The direction of the text: 'horizontal' or 'rotate'.
	 * @property {string} [fontFamily='Arial']
	 * @property {number} [fontSize=12]
	 * @property {Array<object>} labels
	 * @property {string|function} labels[].label - The text value
	 * @property {function} labels[].linkData - Link data to the label
	 * @property {Array<object>} labels[].placements
	 * @property {string} [labels[].placements[].position='into'] - 'inside' | 'into' | 'outside' (outside is not implmented yet)
	 * @property {string} [labels[].placements[].fill='#333'] - Color of the label
	 */function slices(_ref10){let{settings,chart,nodes,rect,renderer,style}=_ref10;let findPlacement=arguments.length>1&&arguments[1]!==undefined?arguments[1]:findBestPlacement;let placer=arguments.length>2&&arguments[2]!==undefined?arguments[2]:placeTextOnPoint;const defaults=extend$1$1({fontSize:12,fontFamily:'Arial',fill:'#333',padding:4,position:'into'},style.label);defaults.fontSize=parseInt(defaults.fontSize,10);const labelSettings=settings.labels.map(labelSetting=>extend$1$1({},defaults,settings,labelSetting));const placementSettings=settings.labels.map(labelSetting=>labelSetting.placements.map(placement=>extend$1$1({},defaults,settings,labelSetting,placement)));const labels=[];const store={insideLabelBounds:[]};nodes=sortNodes(nodes);const context={};for(let i=0,len=nodes.length;i<len;i++){const node=nodes[i];const arg=cbContext$1(node,chart);for(let j=0;j<labelSettings.length;j++){const lblStngs=labelSettings[j];const text=typeof lblStngs.label==='function'?lblStngs.label(arg,i):'';if(!text){continue;}const direction=typeof lblStngs.direction==='function'?lblStngs.direction(arg,i):lblStngs.direction||'horizontal';const linkData=typeof lblStngs.linkData==='function'?lblStngs.linkData(arg,i):undefined;const measured=measureText$1(text,lblStngs,renderer);const bestPlacement=findPlacement({context,direction,lblStngs,measured,node,placementSettings:placementSettings[j],rect,store});const bounds=bestPlacement.bounds;const placement=bestPlacement.placement;if(bounds&&placement){if(placement.position==='outside'&&direction!=='rotate'){updateContext({context,node,bounds});const topLeftBounds=getTopLeftBounds(bounds);if(!rectContainsRect(topLeftBounds,rect)){continue;}}const fill=typeof placement.fill==='function'?placement.fill(arg,i):placement.fill;const label=placer(bounds,text,{fill,fontSize:lblStngs.fontSize,fontFamily:lblStngs.fontFamily,textMetrics:measured});if(label){if(typeof linkData!=='undefined'){label.data=linkData;}labels.push(label);if(bounds.line){bounds.line.stroke=fill;labels.push(bounds.line);}}}}}return labels;}const LINEBREAK_REGEX=/\n+|\r+|\r\n/;const WHITESPACE_REGEX=/\s/;const HYPHEN_REGEX=/[a-zA-Z\u00C0-\u00F6\u00F8-\u00FF\u00AD]/;const NO_BREAK=0;const MANDATORY=1;const BREAK_ALLOWED=2;function includesLineBreak(c){if(typeof c==='string'){return c.search(LINEBREAK_REGEX)!==-1;}return String(c).search(LINEBREAK_REGEX)!==-1;}function includesWhiteSpace(c){return c.search(WHITESPACE_REGEX)!==-1;}function hyphenationAllowed(c){/* Latin character set. Excluding numbers, sign and symbol characters, but including soft hyphen */return c.search(HYPHEN_REGEX)!==-1;}function resolveBreakOpportunity(chunk,i,chunks,mandatory,noBreakAllowed){if(mandatory.some(fn=>fn(chunk,i,chunks))){return MANDATORY;}if(noBreakAllowed.some(fn=>fn(chunk,i,chunks))){return NO_BREAK;}return BREAK_ALLOWED;}function cleanEmptyChunks(chunks){if(chunks[0]===''){chunks.shift();}if(chunks[chunks.length-1]===''){chunks.pop();}}function clamp(val,min,max){return Math.max(min,Math.min(max,val));}function stringTokenizer(){let{string,separator='',reverse=false,measureText=text=>({width:text.length,height:1}),mandatoryBreakIdentifiers=[includesLineBreak],noBreakAllowedIdentifiers=[],suppressIdentifier=[includesWhiteSpace,includesLineBreak,chunk=>chunk===''],hyphenationIdentifiers=[hyphenationAllowed]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const chunks=String(string).split(separator);cleanEmptyChunks(chunks);const length=chunks.length;const isNotDone=reverse?p=>p>=0:p=>p<length;let position=reverse?length:-1;// Set init position 1 step before or after to make first next call go to first position
	function peek(peekAt){const i=clamp(peekAt,0,length-1);const chunk=chunks[i];const textMeasure=measureText(chunk);const opportunity=resolveBreakOpportunity(chunk,i,chunks,mandatoryBreakIdentifiers,noBreakAllowedIdentifiers);return {index:i,value:chunk,breakOpportunity:opportunity,suppress:suppressIdentifier.some(fn=>fn(chunk,i,chunks)),hyphenation:hyphenationIdentifiers.some(fn=>fn(chunk,i,chunks)),width:textMeasure.width,height:textMeasure.height,done:false};}function next(jumpToPosition){if(isNaN(jumpToPosition)){if(reverse){position--;}else {position++;}}else {position=clamp(jumpToPosition,0,length-1);}if(isNotDone(position)){return peek(position);}return {done:true};}return {next,peek,length};}const HYPHENS_CHAR='\u2010';const ELLIPSIS_CHAR='…';const BASE=24;const PAD=4;const BUMP=1e-12;const DEFAULT_FONT_HEIGHT=16;const DEFAULT_LINE_HEIGHT=1.2;const TEXT_REGEX=/^\s*\d+(\.\d+)?px\s*$/i;function isValidFontSize(val){const type=typeof val;if(type==='string'){return TEXT_REGEX.test(val);}return false;}function fontSizeToHeight(fontSize){if(isValidFontSize(fontSize)){const size=parseFloat(fontSize);const m=PAD*Math.ceil((size+BUMP)/BASE);return size+m;}return DEFAULT_FONT_HEIGHT;}function fontSizeToLineHeight(node){const fontSize=node['font-size']||node.fontSize;if(isValidFontSize(fontSize)){return parseFloat(fontSize)*Math.max(isNaN(node.lineHeight)?DEFAULT_LINE_HEIGHT:node.lineHeight,0);}return DEFAULT_FONT_HEIGHT*DEFAULT_LINE_HEIGHT;}function resolveMaxAllowedLines(node){const maxHeight=node.maxHeight;const maxLines=Math.max(node.maxLines,1)||Infinity;if(isNaN(maxHeight)){return maxLines;}const computedLineHeight=fontSizeToLineHeight(node);return Math.max(1,Math.min(Math.floor(maxHeight/computedLineHeight),maxLines));}function initState$1(node,measureText){return {lines:[],line:'',width:0,maxLines:resolveMaxAllowedLines(node),maxWidth:node.maxWidth,hyphens:{enabled:node.hyphens==='auto',char:HYPHENS_CHAR,metrics:measureText(HYPHENS_CHAR)}};}function newLine(state){state.lines.push(state.line);state.line='';state.width=0;}function appendToLine(state,token){state.line+=token.value;state.width+=token.width;}function insertHyphenAndJump(state,token,iterator){if(token.width>state.maxWidth){return token;}const startIndex=token.index;for(let i=1;i<5;i++){const pairToken=iterator.peek(token.index-1);if(!token.hyphenation||!pairToken.hyphenation||token.index===0){return token;}if(state.width+state.hyphens.metrics.width<=state.maxWidth){state.line+=state.hyphens.char;return token;}if(state.line.length===1){return token;}token=iterator.next(startIndex-i);state.line=state.line.slice(0,-1);state.width-=token.width;}return token;}function breakSequence(state,token,measureText){const charTokenIterator=stringTokenizer({string:token.value,measureText});while(state.lines.length<state.maxLines){let charToken=charTokenIterator.next();if(charToken.done){break;}else if(state.width+charToken.width>state.maxWidth&&charToken.breakOpportunity===BREAK_ALLOWED&&state.line.length>0){charToken=state.hyphens.enabled?insertHyphenAndJump(state,charToken,charTokenIterator):charToken;newLine(state);appendToLine(state,charToken);}else {appendToLine(state,charToken);}}}function breakAll(node,measureText){const text=node.text;const iterator=stringTokenizer({string:text,separator:'',measureText,noBreakAllowedIdentifiers:[(chunk,i)=>i===0]});const state=initState$1(node,measureText);let reduced=true;while(state.lines.length<state.maxLines){let token=iterator.next();if(token.done){newLine(state);reduced=false;break;}else if(token.breakOpportunity===MANDATORY){newLine(state);}else if(state.width+token.width>state.maxWidth&&token.breakOpportunity===BREAK_ALLOWED){if(token.suppress){// Token is suppressable and can be ignored
	state.width+=token.width;}else {token=state.hyphens.enabled?insertHyphenAndJump(state,token,iterator):token;newLine(state);appendToLine(state,token);}}else {appendToLine(state,token);}}return {lines:state.lines,reduced};}function breakWord(node,measureText){const text=node.text;const iterator=stringTokenizer({string:text,separator:/(\s|-|\u2010)/,measureText});const state=initState$1(node,measureText);let reduced=true;while(state.lines.length<state.maxLines){let token=iterator.next();if(token.done){newLine(state);reduced=false;break;}else if(token.breakOpportunity===MANDATORY){newLine(state);}else if(state.width+token.width>state.maxWidth&&token.breakOpportunity===BREAK_ALLOWED){if(token.suppress){// Token is suppressable and can be ignored
	newLine(state);}else if(token.width>state.maxWidth){// Single sequence is wider then maxWidth, break sequence into multiple lines
	breakSequence(state,token,measureText);}else {newLine(state);appendToLine(state,token);}}else {appendToLine(state,token);}}return {lines:state.lines,reduced};}function generateLineNodes(result,item,halfLead,height){const container={type:'container',children:[]};if(typeof item.id!=='undefined'){// TODO also inherit data attribute and more?
	container.id=item.id;}let currentY=0;result.lines.forEach((line,i)=>{const node=extend$1$1({},item);node.text=line;node._lineBreak=true;// Flag node as processed to avoid duplicate linebreak run
	currentY+=halfLead;// leading height above
	if(result.reduced&&i===result.lines.length-1){node.text+=ELLIPSIS_CHAR;}else {delete node.maxWidth;}node.dy=isNaN(node.dy)?currentY:node.dy+currentY;currentY+=height;currentY+=halfLead;// Leading height below
	container.children.push(node);});return container;}function shouldLineBreak(item){// If type text and not already broken into lines
	return item.type==='text'&&!item._lineBreak;}function wrappedMeasureText(node,measureText){return text=>measureText({text,fontSize:node.fontSize,fontFamily:node.fontFamily});}function resolveLineBreakAlgorithm(node){const WORDBREAK={'break-all':breakAll,'break-word':breakWord};return WORDBREAK[node.wordBreak];}/**
	 * Apply wordBreak rules to text nodes.
	 * @ignore
	 * @param {function} measureText
	 * @returns {function} Event function to convert a text node into multiple nodes
	 */function onLineBreak(measureText){return state=>{const item=state.node;if(shouldLineBreak(item)){const wordBreakFn=resolveLineBreakAlgorithm(item);if(!wordBreakFn){return;}const tm=measureText(item);if(tm.width>item.maxWidth||includesLineBreak(item.text)){const diff=fontSizeToLineHeight(item)-tm.height;const halfLead=diff/2;const result=wordBreakFn(item,wrappedMeasureText(item,measureText));state.node=generateLineNodes(result,item,halfLead,tm.height);// Convert node to container
	}}};}function ellipsText(label,measureText){// eslint-disable-line import/prefer-default-export
	const fontFamily=label['font-family']||label.fontFamily;const fontSize=label['font-size']||label.fontSize;const text=typeof label.text==='string'?label.text:"".concat(label.text);const{maxWidth}=label;if(maxWidth===undefined){return text;}let textWidth=measureText({text,fontSize,fontFamily}).width;if(textWidth<=maxWidth){return text;}let min=0;let max=text.length-1;while(min<=max){let reduceIndex=Math.floor((min+max)/2);let reduceText=text.substr(0,reduceIndex)+ELLIPSIS_CHAR;textWidth=measureText({text:reduceText,fontSize,fontFamily}).width;if(textWidth<=maxWidth){min=reduceIndex+1;}else {// textWidth > maxWidth
	max=reduceIndex-1;}}return text.substr(0,max)+ELLIPSIS_CHAR;}/**
	 * Currently some browsers, IE11 and Edge confirmed, doesn't support the dominant-baseline svg-attribute and
	 * the browser that does, have different implementations. Thus giving an unpredictable result when rendering'
	 * text and predicting it's position (ex. in collision detection).
	 *
	 * To supplement and the aid in aligning/positioning text with various items, this function can be used
	 * to follow a common heuristic across supported renderers.
	 * @ignore
	 * @param {object} textNode
	 * @param {string|number} [textNode['font-size']=0] - String in px format or number
	 * @param {string} [textNode['dominant-baseline']] - If baseline is omitted dominant-baseline is used
	 * @param {string} [textNode.baseline]
	 * @returns {number} Delta-y required to adjust for baseline
	 */function baselineHeuristic(textNode){const baseline=textNode.baseline||textNode['dominant-baseline'];let dy=0;const fontSize=parseInt(textNode.fontSize||textNode['font-size'],10)||0;switch(baseline){case 'hanging':dy=fontSize*0.75;break;case 'text-before-edge':dy=fontSize*0.85;break;case 'middle':dy=fontSize*0.25;break;case 'central':dy=fontSize*0.35;break;case 'mathemetical':dy=fontSize/2;break;case 'text-after-edge':case 'ideographic':dy=-fontSize*0.2;break;default:dy=0;break;}return dy;}const heightCache={};const widthCache={};const contextCache={fontSize:undefined,fontFamily:undefined};let context;function setContext(){context=context||document.createElement('canvas').getContext('2d');}function isEqual(s1,s2){return !s1&&!s2||s1===s2;}function setFont(_ref){let{fontWeight,fontSize,fontFamily}=_ref;if(isEqual(contextCache.fontWeight,fontWeight)&&isEqual(contextCache.fontSize,fontSize)&&isEqual(contextCache.fontFamily,fontFamily)){return;}context.font=[fontWeight,fontSize,fontFamily].filter(value=>!!value).join(' ');// eslint-disable-line
	contextCache.fontWeight=fontWeight;contextCache.fontSize=fontSize;contextCache.fontFamily=fontFamily;}function measureTextWidth(_ref2){let{text,fontWeight,fontSize,fontFamily}=_ref2;const key="".concat(text," ").concat(fontWeight," ").concat(fontSize," ").concat(fontFamily);if(typeof widthCache[key]!=='number'){setContext();setFont({fontWeight,fontSize,fontFamily});widthCache[key]=context.measureText(text).width;}return widthCache[key];}function measureTextHeight(fontSize){if(typeof heightCache[fontSize]!=='number'){heightCache[fontSize]=fontSizeToHeight(fontSize);}return heightCache[fontSize];}/**
	 * @private
	 * @param {object} opts
	 * @param {string} opts.text - Text to measure
	 * @param {string} opts.fontWeight - Font weight, e.g. 'bold'
	 * @param {string} opts.fontSize - Font size with a unit definition, ex. 'px' or 'em'
	 * @param {string} opts.fontFamily - Font family
	 * @return {object} Width and height of text in pixels
	 * @example
	 * measureText({
	 *  text: 'my text',
	 *  fontSize: '12px',
	 *  fontFamily: 'Arial'
	 * }); // returns { width: 20, height: 12 }
	 */function measureText(_ref3){let{text,fontWeight,fontSize,fontFamily}=_ref3;const w=measureTextWidth({text,fontWeight,fontSize,fontFamily});const h=measureTextHeight(fontSize);return {width:w,height:h};}/**
	 * Calculates the bounding rectangle of a text node.
	 * The bounding rectangle is a approximate of the "em square" seen here (http://www.w3resource.com/html5-canvas/html5-canvas-text.php)
	 * @ignore
	 * @param {object} attrs - Text node definition
	 * @param {number} [attrs.x] - X-coordinate
	 * @param {number} [attrs.y] - Y-coordinate
	 * @param {number} [attrs.dx] - Delta x-coordinate
	 * @param {number} [attrs.dy] - Delta y-coordinate
	 * @param {string} [attrs.anchor] - Text anchor
	 * @param {number} [attrs.maxWidth] - Maximum allowed text width
	 * @return {object} The bounding rectangle
	 */function calcTextBounds(attrs){let measureFn=arguments.length>1&&arguments[1]!==undefined?arguments[1]:measureText;const fontSize=attrs['font-size']||attrs.fontSize;const fontFamily=attrs['font-family']||attrs.fontFamily;const textMeasure=measureFn({text:attrs.text,fontFamily,fontSize});const calWidth=Math.min(attrs.maxWidth||textMeasure.width,textMeasure.width);// Use actual value if max is not set
	const x=attrs.x||0;const y=attrs.y||0;const dx=attrs.dx||0;const dy=(attrs.dy||0)+baselineHeuristic(attrs);const boundingRect={x:0,y:y+dy-textMeasure.height*0.75,// Magic number for alphabetical baseline
	width:calWidth,height:textMeasure.height};const anchor=attrs['text-anchor']||attrs.anchor;if(anchor==='middle'){boundingRect.x=x+dx-calWidth/2;}else if(anchor==='end'){boundingRect.x=x+dx-calWidth;}else {boundingRect.x=x+dx;}return boundingRect;}/**
	 * Calculates the bounding rectangle of a text node. Including any line breaks.
	 * @ignore
	 * @param {object} node
	 * @param {string} node.text - Text to measure
	 * @param {number} [node.x=0] - X-coordinate
	 * @param {number} [node.y=0] - Y-coordinate
	 * @param {number} [node.dx=0] - Delta x-coordinate
	 * @param {number} [node.dy=0] - Delta y-coordinate
	 * @param {string} [node.anchor='start'] - Text anchor
	 * @param {string} [node.fontSize] - Font size
	 * @param {string} [node.fontFamily] - Font family
	 * @param {string} [node['font-size']] - Font size
	 * @param {string} [node['font-family']] - Font family
	 * @param {string} [node.wordBreak] - Word-break option
	 * @param {number} [node.maxWidth] - Maximum allowed text width
	 * @param {number} [node.maxHeight] - Maximum allowed text height. If both maxLines and maxHeight are set, the property that results in the fewest number of lines is used
	 * @param {number} [node.maxLines] - Maximum number of lines allowed.
	 * @param {number} [node.lineHeight=1.2] - Line height
	 * @param {function} [measureFn] - Optional text measure function
	 * @return {object} The bounding rectangle
	 */function textBounds(node){let measureFn=arguments.length>1&&arguments[1]!==undefined?arguments[1]:measureText;const lineBreakFn=resolveLineBreakAlgorithm(node);const fontSize=node['font-size']||node.fontSize;const fontFamily=node['font-family']||node.fontFamily;const tm=measureFn({text:node.text,fontFamily,fontSize});if(lineBreakFn&&(tm.width>node.maxWidth||includesLineBreak(node.text))){const resolvedLineBreaks=lineBreakFn(node,text=>measureFn({text,fontFamily,fontSize}));const nodeCopy=extend$1$1({},node);let maxWidth=0;let widestLine='';for(let i=0,len=resolvedLineBreaks.lines.length;i<len;i++){let line=resolvedLineBreaks.lines[i];line+=i===len-1&&resolvedLineBreaks.reduced?ELLIPSIS_CHAR:'';const width=measureFn({text:line,fontSize,fontFamily}).width;if(width>=maxWidth){maxWidth=width;widestLine=line;}}nodeCopy.text=widestLine;const bounds=calcTextBounds(nodeCopy,measureFn);bounds.height=fontSizeToLineHeight(node)*resolvedLineBreaks.lines.length;return bounds;}return calcTextBounds(node,measureFn);}const LINE_HEIGHT=1.2;const CIRCLE_FACTOR=0.9;function cbContext(node,chart){return {node,data:node.data,scale:chart.scale,formatter:chart.formatter,dataset:chart.dataset};}function placeTextInRect$1(rect,text,opts){const label={type:'text',text,maxWidth:rect.width,x:0,y:rect.y,dx:0,dy:0,fill:opts.fill,anchor:'start',baseline:'alphabetical',fontSize:"".concat(opts.fontSize,"px"),fontFamily:opts.fontFamily};const textMetrics=opts.textMetrics;if(rect.width<opts.fontSize){return false;}const wiggleWidth=Math.max(0,rect.width-textMetrics.width);label.x=rect.x+opts.align*wiggleWidth;label.y=rect.y+textMetrics.height/LINE_HEIGHT;return label;}function getRectFromCircle(_ref){let{cx,cy,r}=_ref;return {type:'circle',bounds:{cx,cy,r}};}function getSliceBounds(slice){const EPSILON=1e-12;let{start,end,innerRadius,outerRadius,offset}=slice;if(Math.abs(start+2*Math.PI-end)>EPSILON){return {type:null,bounds:null};}let r=innerRadius!==0?innerRadius:outerRadius;return getRectFromCircle({cx:offset.x,cy:offset.y,r});}function getBounds(node){if(node.desc&&node.desc.slice){return getSliceBounds(node.desc.slice);}if(node.type==='circle'){return getRectFromCircle(node.attrs);}if(node.type==='rect'){return {type:'rect',bounds:node.bounds};}// defualt to node.bounds ?
	return {type:null,bounds:null};}/**
	 * @typedef {object} ComponentLabels~RowsLabelStrategy
	 * @property {'rows'} type Name of strategy
	 *//**
	 * Rows strategy settings
	 * @typedef {object} ComponentLabels~RowsLabelStrategy.settings
	 * @property {string} [fontFamily='Arial']
	 * @property {number} [fontSize=12]
	 * @property {number} [justify=0.5]
	 * @property {number} [padding=4]
	 * @property {Array<object>} labels
	 * @property {string|function} labels[].label - The text value
	 * @property {function} labels[].linkData - Link data to the label
	 * @property {number} [labels[].align=0.5]
	 * @property {string|function} [labels[].fill='#333']
	 */function rows(_ref2){let{settings,chart,nodes,renderer,style}=_ref2;let placer=arguments.length>1&&arguments[1]!==undefined?arguments[1]:placeTextInRect$1;const defaults=extend$1$1({fontSize:12,fontFamily:'Arial',fill:'#333',padding:4,align:0.5,justify:0.5},style.label);defaults.fontSize=parseInt(defaults.fontSize,10);const rowSettings=extend$1$1({},defaults,settings);const labelSettings=settings.labels.map(labelSetting=>extend$1$1({},rowSettings,labelSetting));const labelStruct={};const labels=[];for(let i=0,len=nodes.length;i<len;i++){let node=nodes[i];let arg=cbContext(node,chart);let{type,bounds}=getBounds(node);if(!bounds){continue;}let totalHeight=0;let measurements=[];let texts=[];let maxHeight=type==='circle'?2*bounds.r*CIRCLE_FACTOR:bounds.height;totalHeight+=rowSettings.padding;let j;for(j=0;j<labelSettings.length;j++){let lblStngs=labelSettings[j];let text=typeof lblStngs.label==='function'?lblStngs.label(arg,i):'';labelStruct.fontFamily=lblStngs.fontFamily;labelStruct.fontSize="".concat(lblStngs.fontSize,"px");labelStruct.text=text;let measured=renderer.measureText(labelStruct);totalHeight+=measured.height+lblStngs.padding;if(totalHeight>maxHeight){break;}texts.push(text);measurements.push(measured);}const labelCount=j;const wiggleHeight=Math.max(0,maxHeight-totalHeight);let currentY;if(type==='circle'){currentY=bounds.cy-bounds.r*CIRCLE_FACTOR;}else {currentY=bounds.y;}currentY+=rowSettings.justify*wiggleHeight+rowSettings.padding;for(j=0;j<labelCount;j++){let lblStngs=labelSettings[j];let rect;if(type==='circle'){let maxYDistToCenter=Math.max(Math.abs(currentY-bounds.cy),Math.abs(currentY+measurements[j].height-bounds.cy));let halfWidth=Math.sqrt(bounds.r*bounds.r-maxYDistToCenter*maxYDistToCenter);rect={x:bounds.cx-halfWidth+rowSettings.padding,y:currentY,width:2*halfWidth-2*rowSettings.padding,height:measurements[j].height};}else {rect={x:bounds.x+rowSettings.padding,y:currentY,width:bounds.width-2*rowSettings.padding,height:measurements[j].height};}currentY+=measurements[j].height+rowSettings.padding;let fill=typeof lblStngs.fill==='function'?lblStngs.fill(arg,i):lblStngs.fill;const linkData=typeof lblStngs.linkData==='function'?lblStngs.linkData(arg,i):undefined;let label=placer(rect,texts[j],{fill,align:lblStngs.align,fontSize:lblStngs.fontSize,fontFamily:lblStngs.fontFamily,textMetrics:measurements[j]});if(label){if(label.text&&label.text!==ELLIPSIS_CHAR){const ellipsed=ellipsText(label,renderer.measureText);if(ELLIPSIS_CHAR===ellipsed){// don't include label if it's only an ellipsis
	continue;}label.ellipsed=ellipsed;}if(typeof linkData!=='undefined'){label.data=linkData;}labels.push(label);}}}return labels;}var strategies={bar:bars,slice:slices,rows};/**
	 * @typedef {object} ComponentLabels
	 * @extends ComponentSettings
	 * @property {'labels'} type component type
	 * @example
	{
	  type: 'labels',
	  settings: {
	    sources: [
	      {
	        component: 'bars',
	        selector: 'rect', // select all 'rect' shapes from the 'bars' component
	        strategy: {
	          type: 'bar', // the strategy type
	          settings: {
	            labels: [
	              {
	                label({ data }) {
	                  return data ? data.end.label : '';
	                },
	                placements: [
	                  // label placements in prio order. Label will be placed in the first place it fits into
	                  { position: 'inside', fill: '#fff' },
	                  { position: 'outside', fill: '#666' },
	                ],
	              },
	            ],
	          },
	        },
	      },
	    ],
	  },
	}
	 *//**
	 * Component settings
	 * @typedef {object} ComponentLabels.settings
	 * @property {Array<ComponentLabels~Source>} sources Source settings
	 *//**
	 * @typedef {object} ComponentLabels~Source
	 * @property {string} component Key of target component
	 * @property {string} selector Shape selector
	 * @property {ComponentLabels~BarsLabelStrategy|ComponentLabels~RowsLabelStrategy|ComponentLabels~SlicesLabelStrategy} strategy Strategy settings
	 */function strategy(_ref,fn){let{chart,source,rect,renderer,style}=_ref;const component=chart.component(source.component);if(!component){return [];}const nodes=chart.findShapes(source.selector).filter(n=>n.key===source.component);return fn({chart,settings:source.strategy.settings,nodes,rect:{x:0,y:0,width:rect.width,height:rect.height},renderer,style});}const labelsComponent={require:['chart','renderer','settings'],defaultSettings:{settings:{},style:{label:'$label'}},render(){const stngs=this.settings.settings;const labels=[];(stngs.sources||[]).forEach(source=>{if(source.strategy&&strategies[source.strategy.type]&&source.component){labels.push(...strategy({chart:this.chart,rect:this.rect,renderer:this.renderer,source,style:this.style},strategies[source.strategy.type]));}});return labels;}};function labels$1(picasso){picasso.component('labels',labelsComponent);}/**
	 * Component settings
	 * @typedef {object=}
	 * @alias ComponentLegendCat.settings
	 */const DEFAULT_SETTINGS$2={/**
	   * @typedef {object=}
	   */layout:{/**
	     * Maximum number of columns (vertical) or rows (horizontal)
	     * @type {number=}
	     */size:1,/**
	     * Layout direction. Either `'ltr'` or `'rtl'`
	     * @type {string=}
	     */direction:'ltr',/** Initial scroll offset
	     * @type {number=} */scrollOffset:0},/**
	   * Settings applied per item
	   * @typedef {object=}
	   */item:{/** Whether to show the current item
	     * @type {boolean=} */show:true,/**
	     * @typedef {object=} */label:{/** Font size in pixels
	       * @type {string=} */fontSize:'12px',/** Font family
	       * @type {string=} */fontFamily:'Arial',fill:'#595959',/** Word break rule, how to apply line break if label text overflows its maxWidth property. Either `'break-word'` or `'break-all'`
	       * @type {string=} */wordBreak:'none',/** Max number of lines allowed if label is broken into multiple lines (only applicable with wordBreak)
	       * @type {number=} */maxLines:2,/** Maximum width of label, in px
	       * @type {number=} */maxWidth:136,/** Line height as a multiple of the font size
	       * @type {number=} */lineHeight:1.2},/**
	     * @typedef {object=} */shape:{/**
	       * Type of shape
	       * @type {string=} */type:'square',/**
	       * Size of shape in pixels
	       * @type {number=} */size:12}},/**
	   * @typedef {object=} */title:{/** Whether to show the title
	     * @type {boolean=} */show:true,/** Title text. Defaults to the title of the provided data field
	     * @type {string=} */text:undefined,/** Horizontal alignment of the text. Allowed values are `'start'`, `'middle'` and `'end'`
	     * @type {string}
	     */anchor:'start',/** Font size in pixels
	     * @type {string=} */fontSize:'16px',/** Font family
	     * @type {string=} */fontFamily:'Arial',/** Title color
	     * @type {string=} */fill:'#595959',/** Word break rule, how to apply line break if label text overflows its maxWidth property. Either `'break-word'` or `'break-all'`
	     * @type {string=} */wordBreak:'none',/** Max number of lines allowed if label is broken into multiple lines, is only appled when `wordBreak` is not set to `'none'`
	     * @type {number=} */maxLines:2,/** Maximum width of title, in px
	     * @type {number=} */maxWidth:156,/** Line height as a multiple of the font size
	     * @type {number=} */lineHeight:1.25}};/**
	 * Resolve settings based on input, defaults, and data
	 *
	 * @ignore
	 * @param {legendComponent} comp - The component instance
	 */function resolveSettings(comp){const domain=comp.scale.domain();let data={items:[]};const dock=comp.settings.layout.dock;if(comp.scale.type==='threshold-color'){const fields=comp.scale.data().fields;const sourceField=fields[0];let formatter=v=>String(v);if(comp.settings.formatter){formatter=comp.chart.formatter(comp.settings.formatter);}else if(sourceField){formatter=sourceField.formatter();}for(let i=0;i<domain.length-1;i++){const it={value:domain[i],label:"".concat(formatter(domain[i])," - < ").concat(formatter(domain[i+1]))};if(sourceField){it.source={field:sourceField.id()};}data.items.push(it);}const orientation=dock==='top'||dock==='bottom'?'horizontal':'vertical';if(orientation==='vertical'){data.items.reverse();}}else {const labels=comp.scale.labels?comp.scale.labels():null;data.items=domain.map((d,idx)=>{const datum=comp.scale.datum?extend$1$1({},comp.scale.datum(d)):{value:d};datum.value=d;if(comp.scale.label){datum.label=comp.scale.label(d);}else if(labels){datum.label=labels[idx];}return datum;});}const title=comp.resolver.resolve({data:{fields:comp.scale.data().fields},defaults:extend$1$1(true,{},DEFAULT_SETTINGS$2.title,comp.style.title),settings:comp.settings.settings.title});const layout=comp.resolver.resolve({data:{fields:comp.scale.data().fields},defaults:DEFAULT_SETTINGS$2.layout,settings:comp.settings.settings.layout});const labels=comp.resolver.resolve({data,defaults:extend$1$1(true,{},DEFAULT_SETTINGS$2.item.label,comp.style.item.label),settings:(comp.settings.settings.item||{}).label});const shapeSettings=extend$1$1(true,{},(comp.settings.settings.item||{}).shape);if(typeof shapeSettings.fill==='undefined'&&comp.settings.scale){shapeSettings.fill={scale:comp.settings.scale};}const symbols=comp.resolver.resolve({data,defaults:extend$1$1(true,{},DEFAULT_SETTINGS$2.item.shape,comp.style.item.shape),settings:shapeSettings});const items=comp.resolver.resolve({data,defaults:extend$1$1(true,{},{show:DEFAULT_SETTINGS$2.item.show}),settings:{show:(comp.settings.settings.item||{}).show}});function range(item,i){let v=item.data.value;let next=domain[i+1];item.data.value=[v,next];}if(comp.scale.type==='threshold-color'){const orientation=dock==='top'||dock==='bottom'?'horizontal':'vertical';if(orientation==='vertical'){items.items.reverse().forEach(range);items.items.reverse();}else {items.items.forEach(range);}}return {title,labels,symbols,items,layout};}/* eslint no-mixed-operators:0 */function placeTextInRect(rect,label,opts){const textMetrics=opts.textMetrics;if(rect.height<textMetrics.height){return false;}const wiggleWidth=Math.max(0,rect.width-textMetrics.width);label.baseline='text-before-edge';const wiggleHeight=Math.max(0,rect.height-textMetrics.height);label.x=rect.x+opts.align*wiggleWidth;label.y=rect.y+opts.justify*wiggleHeight+parseInt(label.fontSize,10)*0.175;// 0.175 - basline offset
	return label;}function wiggleSymbol(container,size,opts){const wiggleWidth=Math.max(0,container.width-size);const wiggleHeight=Math.max(0,container.height-size);return {x:container.x+size/2+opts.align*wiggleWidth,y:container.y+size/2+opts.justify*wiggleHeight};}function createRenderItem(_ref){let{x=0,y,item,globalMetrics,createSymbol,direction='ltr'}=_ref;let label=item.label.displayObject;let labelBounds=item.label.bounds;let symbolItem=item.symbol.meta;const rtl=direction==='rtl';let labelRect={x:rtl?x+globalMetrics.maxLabelBounds.width:x+globalMetrics.maxSymbolSize+globalMetrics.spacing,y,width:globalMetrics.maxLabelBounds.width,height:Math.max(globalMetrics.maxSymbolSize,globalMetrics.maxLabelBounds.height)};let wiggled=wiggleSymbol({x:rtl?x+globalMetrics.maxLabelBounds.width+globalMetrics.spacing:x,y,width:globalMetrics.maxSymbolSize,height:labelRect.height},symbolItem.size,{align:typeof symbolItem.align==='undefined'?0.5:symbolItem.align,justify:typeof symbolItem.justify==='undefined'?0.5:symbolItem.justify});const symbol=createSymbol(extend$1$1({},symbolItem,wiggled));delete symbol.collider;label.anchor=rtl?'end':'start';placeTextInRect(labelRect,label,{textMetrics:labelBounds,fontSize:parseInt(label.fontSize,10),align:0.0,justify:0.5});let container={type:'container',data:item.label.displayObject.data,children:[symbol,label],collider:{type:'rect',x,y,width:globalMetrics.maxItemBounds.width,height:globalMetrics.maxItemBounds.height}};return {item:container,metrics:labelRect};}function getItemsToRender(_ref2,rect,_ref3){let{viewRect}=_ref2;let{itemized,create=createRenderItem,parallels,createSymbol}=_ref3;const direction=itemized.layout.direction;const globalMetrics=itemized.globalMetrics;const legendItems=itemized.items;const isHorizontal=itemized.layout.orientation==='horizontal';let s=0;const renderItems=[];const fixedHeight=globalMetrics.maxItemBounds.height;const fixedWidth=globalMetrics.maxItemBounds.width;const rowHeight=itemized.layout.margin.vertical+fixedHeight;const columnWidth=itemized.layout.margin.horizontal+fixedWidth;let x=rect.x;let y=rect.y;let shift=viewRect.x-rect.x;for(let i=0;i<legendItems.length;i++){let renderItem=create({y,x:direction==='rtl'?viewRect.x+shift+viewRect.width-fixedWidth-(x-rect.x):x,item:legendItems[i],globalMetrics,direction,createSymbol});if(isHorizontal&&x>=viewRect.x-fixedWidth||!isHorizontal&&y>=viewRect.y-fixedHeight){renderItems.push(renderItem.item);}s++;if(s>=parallels){s=0;if(isHorizontal){x+=columnWidth;// next column
	y=rect.y;// reset y to first row
	}else {y+=rowHeight;// next row
	x=rect.x;// reset x to first column
	}}else if(isHorizontal){y+=rowHeight;// next row
	}else {x+=columnWidth;// next column
	}if(!isHorizontal&&y>viewRect.y+viewRect.height){break;}else if(isHorizontal&&x>viewRect.x+viewRect.width){break;}}return renderItems;}function itemize$2(_ref4,renderer){let{resolved,dock}=_ref4;let label;let items=[];let item;let sourceItems=resolved.items.items;let sourceSymbols=resolved.symbols.items;let sourceLabels=resolved.labels.items;let maxSymbolSize=0;let maxLabelWidth=0;let maxLabelHeight=0;for(let i=0;i<sourceItems.length;i++){if(sourceItems[i].show===false){continue;}const text=typeof sourceLabels[i].text!=='undefined'?sourceLabels[i].text:sourceLabels[i].data.label||'';label=extend$1$1({},sourceLabels[i],{// create the displayObject here in order to measure it
	type:'text',fontSize:"".concat(parseInt(sourceLabels[i].fontSize,10),"px"),text,title:text});item={symbol:{// can't create a displayObject here due to need to wiggle the center position of the symbol later on,
	// just store the object needed later on
	meta:sourceSymbols[i]},label:{displayObject:label,bounds:renderer.textBounds(label)}};items.push(item);maxSymbolSize=Math.max(sourceSymbols[i].size,maxSymbolSize);maxLabelWidth=Math.max(item.label.bounds.width,maxLabelWidth);maxLabelHeight=Math.max(item.label.bounds.height,maxLabelHeight);}return {items,globalMetrics:{spacing:8,maxSymbolSize,maxItemBounds:{height:Math.max(maxSymbolSize,maxLabelHeight),width:maxSymbolSize+8+maxLabelWidth},maxLabelBounds:{width:maxLabelWidth,height:maxLabelHeight}},layout:{margin:{vertical:typeof resolved.layout.item.vertical!=='undefined'?resolved.layout.item.vertical:4,horizontal:typeof resolved.layout.item.horizontal!=='undefined'?resolved.layout.item.horizontal:4},mode:resolved.layout.item.mode,size:resolved.layout.item.size,orientation:dock==='top'||dock==='bottom'?'horizontal':'vertical',direction:resolved.layout.item.direction,scrollOffset:resolved.layout.item.scrollOffset}};}function extent(itemized,parallels){const count=itemized.items.length;const size=Math.ceil(count/parallels);const property=itemized.layout.orientation==='horizontal'?'width':'height';const margin=property==='width'?'horizontal':'vertical';return itemized.globalMetrics.maxItemBounds[property]*size+(size-1)*itemized.layout.margin[margin];}function spread(itemized,parallels){const size=parallels;const property=itemized.layout.orientation==='horizontal'?'height':'width';const margin=property==='width'?'horizontal':'vertical';return itemized.globalMetrics.maxItemBounds[property]*size+// expected vertical size of items
	(size-1)*itemized.layout.margin[margin];// expected spacing between items
	}function parallelize(availableExtent,availableSpread,itemized){const count=itemized.items.length;const extentProperty=itemized.layout.orientation==='horizontal'?'width':'height';const margin=extentProperty==='width'?'horizontal':'vertical';const extentInPx=itemized.globalMetrics.maxItemBounds[extentProperty]*count+(count-1)*itemized.layout.margin[margin];let numNeeded=Math.ceil(extentInPx/availableExtent);if(availableSpread!=null){const spreadProperty=itemized.layout.orientation==='horizontal'?'height':'width';const spreadMargin=spreadProperty==='width'?'horizontal':'vertical';const spreadMarginSize=itemized.layout.margin[spreadMargin]||4;const numAllowed=Math.floor((availableSpread+spreadMarginSize)/(spreadMarginSize+itemized.globalMetrics.maxItemBounds[spreadProperty]));numNeeded=Math.min(numNeeded,numAllowed);}const numInput=isNaN(itemized.layout.size)?1:itemized.layout.size;return Math.max(1,Math.min(numNeeded,numInput));}function itemRenderer(legend,_ref5){let{onScroll=()=>{}}=_ref5;let itemized;let parallels;let viewRect;let containerRect;let offset=null;let overflow=0;const api={itemize:obj=>{itemized=itemize$2(obj,legend.renderer);offset=!isNaN(itemized.layout.scrollOffset)?itemized.layout.scrollOffset:offset;// Set the initial offset
	},getItemsToRender:obj=>{viewRect=obj.viewRect;overflow=api.getContentOverflow(viewRect);const ext=api.extent();offset=Math.max(0,Math.min(offset,overflow));containerRect=extend$1$1({},viewRect);const offsetProperty=api.orientation()==='horizontal'?'x':'y';containerRect[offsetProperty]-=offset;containerRect[offsetProperty==='x'?'width':'height']=ext;return getItemsToRender(obj,containerRect,{itemized,parallels,createSymbol:legend.symbol});},parallelize:(availableExtent,availableSpread)=>{parallels=parallelize(availableExtent,availableSpread,itemized);return parallels;},hasContentOverflow:()=>{const property=itemized.layout.orientation==='horizontal'?'width':'height';return extent(itemized,parallels)>viewRect[property];},getContentOverflow:function(){let rect=arguments.length>0&&arguments[0]!==undefined?arguments[0]:viewRect;const property=itemized.layout.orientation==='horizontal'?'width':'height';return Math.max(0,extent(itemized,parallels)-rect[property]);},getNextSize:()=>{// TODO - calculate the actual size to next item to ensure alignment
	const property=itemized.layout.orientation==='horizontal'?'width':'height';const margin=property==='width'?'horizontal':'vertical';return itemized.globalMetrics.maxItemBounds[property]+itemized.layout.margin[margin];},getPrevSize:()=>{// TODO - calculate the actual size to next item to ensure alignment
	const property=itemized.layout.orientation==='horizontal'?'width':'height';const margin=property==='width'?'horizontal':'vertical';return itemized.globalMetrics.maxItemBounds[property]+itemized.layout.margin[margin];},hasNext:()=>{if(api.orientation()==='horizontal'){return viewRect.x+viewRect.width<containerRect.x+containerRect.width;}return viewRect.y+viewRect.height<containerRect.y+containerRect.height;},hasPrev:()=>{if(api.orientation()==='horizontal'){return containerRect.x<viewRect.x;}return containerRect.y<viewRect.y;},next:()=>{api.scroll(-api.getNextSize());},prev:()=>{api.scroll(api.getPrevSize());},scroll:delta=>{const current=Math.max(0,Math.min(overflow,offset-delta));if(current===offset){return;}offset=current;onScroll();},offset:()=>offset,orientation:()=>itemized.layout.orientation,direction:()=>itemized.layout.direction,extent:()=>extent(itemized,parallels),// total amount of space along orientation
	spread:()=>spread(itemized,parallels)// total amount of space perpendicular to orientation
	};return api;}/**
	 * Concatenate object keys into a space separated string. Use for transforming a 'class name map' into a class string
	 * @private
	 * @param  {Object} classMap Object with class names as keys and true or false values depending on if they should be in the returned class string or not
	 * @return {String} Space separated string with class names
	 */function classString(classMap){return Object.keys(classMap).filter(className=>classMap[className]).join(' ');}const DIR={up:'\u25B2',right:'\u25B6',down:'\u25BC',left:'\u25C0'};function itemize$1(_ref){let{// resolved,
	dock,navigation}=_ref;return {layout:{orientation:dock==='top'||dock==='bottom'?'vertical':'horizontal'},navigation};}function btn(h,_ref2){let{size,isActive,direction,nav,attrs}=_ref2;let c={};let content='';const attrsMerged=attrs;if(nav&&nav.button){if(typeof nav.button.class==='function'){c=nav.button.class({direction});}else if(nav.button.class){c=nav.button.class;}if(typeof nav.button.content==='function'){content=nav.button.content(h,{direction});}if(nav.button.tabIndex!==undefined){attrsMerged.tabindex=nav.button.tabIndex;}}const style={width:"".concat(size,"px"),minWidth:"".concat(size,"px"),height:"".concat(size,"px")};if(!Object.keys(c).length){// if no classes are set, add some basic styling
	style.border='0';style.background='none';}if(!isActive||nav&&nav.disabled){attrsMerged.disabled='disabled';}return h('button',extend$1$1({class:classString(c),style},attrsMerged),[content||h('span',{style:{pointerEvents:'none'}},[DIR[direction]])]);}function render$9(renderer,_ref3,itemized,legend){let{rect,itemRenderer}=_ref3;if(!renderer||!renderer.renderArgs){return;}renderer.size(rect);const h=renderer.renderArgs[0];const isVertical=itemized.layout.orientation==='vertical';// orientation of the navigation (not the legend)
	const isRtl=itemRenderer.direction()==='rtl';const hasNext=itemRenderer.hasNext();const hasPrev=itemRenderer.hasPrev();if(!hasPrev&&!hasNext){renderer.render([]);return;}const buttonSize=32;const order=isVertical?['right','left']:['down','up'];if(isRtl&&isVertical){order.reverse();}const nodes=[h('div',{style:{position:'relative',display:'flex','flex-direction':isVertical?'column':'row','justify-content':'center',height:'100%',pointerEvents:'auto'},dir:isRtl&&!isVertical?'rtl':'ltr'},[btn(h,{size:buttonSize,isActive:hasNext,direction:order[0],attrs:{'data-action':'next','data-component-key':legend.settings.key},nav:itemized.navigation}),btn(h,{size:buttonSize,isActive:hasPrev,direction:order[1],attrs:{'data-action':'prev','data-component-key':legend.settings.key},nav:itemized.navigation})])];renderer.render(nodes);}function navRenderer(legend){let itemized;const nav={itemize:obj=>{itemized=itemize$1(obj);},render:obj=>render$9(nav.renderer,obj,itemized,legend),extent:()=>32,spread:()=>64};return nav;}function itemize(_ref,legend){let{resolved}=_ref;if(resolved.title.item.show===false){return null;}const t=extend$1$1({},resolved.title.item,{type:'text'});if(resolved.layout.item.direction==='rtl'){if(!t.anchor||t.anchor==='start'){t.anchor='end';}else if(t.anchor==='end'){t.anchor='start';}}if(typeof resolved.title.settings.text==='undefined'){const fields=legend.scale.data().fields;t.text=fields&&fields[0]?fields[0].title():'';}return {displayObject:t,bounds:legend.renderer.textBounds(t)};}function render$8(_ref2,renderer,itemized){let{rect}=_ref2;if(!renderer){return;}const nodes=[];renderer.size(rect);if(itemized){const align={start:0,end:rect.width,middle:rect.width/2};nodes.push(extend$1$1({},itemized.displayObject,{x:align[itemized.displayObject.anchor]||0,y:0,baseline:'text-before-edge',title:itemized.displayObject.text}));}renderer.render(nodes);}function titleRenderer(legend){let itemized;const api={itemize:obj=>{itemized=itemize(obj,legend);},render:obj=>{render$8(obj,api.renderer,itemized);},spread:()=>itemized?itemized.bounds.height:0,extent:()=>itemized?itemized.bounds.width:0};return api;}/* eslint no-mixed-operators:0 */function layout(rect,display,orientation,_ref){let{itemRenderer,navigationRenderer,titleRenderer,isPreliminary=false}=_ref;let title;let content;let navigation;let preferredSize=0;const paddedRect={x:display.spacing,y:display.spacing,width:rect.width-2*display.spacing,height:rect.height-2*display.spacing};title={x:paddedRect.x,y:paddedRect.y,width:paddedRect.width,height:titleRenderer.spread()};if(orientation==='horizontal'){// const titleAtTop = false;
	// if (titleAtTop) { // this might be a nicer layout sometimes
	//   // |------------------|
	//   // |title             |
	//   // |------------|-----|
	//   // |content     | nav |
	//   // |------------|-----|
	//   // available space for items without navigation UI
	//   const availableExtentForItems = paddedRect.width;
	//   const availableSpreadForItems = paddedRect.height - (title.y + title.height) + 8;
	//   const isRtl = itemRenderer.direction() === 'rtl';
	//   itemRenderer.parallelize(availableExtentForItems, isPreliminary ? undefined : availableSpreadForItems);
	//   const navigationSize = itemRenderer.extent() > availableExtentForItems ? navigationRenderer.extent() : 0;
	//   content = {
	//     x: paddedRect.x,
	//     y: title.y + title.height,
	//     width: paddedRect.width - navigationSize,
	//     height: availableSpreadForItems
	//   };
	//   navigation = {
	//     x: content.x + content.width,
	//     y: title.y + title.height,
	//     width: navigationSize,
	//     height: paddedRect.height - (title.y + title.height) + 8
	//   };
	//   if (isRtl) { // switch navigation and content
	//     navigation.x = content.x;
	//     content.x = navigation.x + navigation.width;
	//     // totalContent.x = navigation.x;
	//   }
	//   preferredSize = title.height + Math.max(navigationRenderer.spread(), itemRenderer.spread());
	// } else {
	// |-----|------------|-----|
	// |title|content     | nav |
	// |-----|------------|-----|
	title={x:paddedRect.x,y:paddedRect.y,width:titleRenderer.extent(),height:titleRenderer.spread()};// available space for items without navigation UI
	const availableExtentForItems=paddedRect.width-title.width-(title.width?display.spacing:0);const availableSpreadForItems=paddedRect.height;itemRenderer.parallelize(availableExtentForItems,isPreliminary?undefined:availableSpreadForItems);const navigationSize=itemRenderer.extent()>availableExtentForItems?navigationRenderer.extent():0;const spread=itemRenderer.spread();const navigationSpread=navigationSize?navigationRenderer.spread():0;content={x:title.x+title.width+(title.width?display.spacing:0),y:paddedRect.y+Math.max(0,(navigationSpread-spread)/2),width:paddedRect.width-navigationSize-title.width-(navigationSize?display.spacing:0)-(title.width?display.spacing:0),height:availableSpreadForItems};navigation={x:content.x+content.width+(navigationSize?display.spacing:0),y:paddedRect.y,width:navigationSize,height:paddedRect.height};title.y=content.y;const isRtl=itemRenderer.direction()==='rtl';if(isRtl){// switch title, content and navigation
	navigation.x=paddedRect.x;content.x=navigation.x+navigation.width+(navigation.width?display.spacing:0);title.x=content.x+content.width+(title.width?display.spacing:0);}preferredSize=Math.max(title.height,navigationSpread,itemRenderer.spread());// }
	}else {// |------------|
	// |title       |
	// |------------|
	// |content     |
	// |------------|
	// |navigation  |
	// |------------|
	const availableExtentForItems=paddedRect.height-title.height-(title.height?display.spacing:0);const availableSpreadForItems=paddedRect.width;itemRenderer.parallelize(availableExtentForItems,isPreliminary?undefined:availableSpreadForItems);const navigationSize=itemRenderer.extent()>availableExtentForItems?navigationRenderer.extent():0;navigation={x:paddedRect.x,y:paddedRect.y+paddedRect.height-navigationSize,width:paddedRect.width,height:navigationSize};content={x:paddedRect.x,y:title.y+title.height+(title.height?display.spacing:0),width:paddedRect.width,height:paddedRect.height-title.height-(title.height?display.spacing:0)-navigation.height-(navigation.height?display.spacing:0)};preferredSize=Math.max(titleRenderer.extent(),navigationSize?navigationRenderer.spread():0,itemRenderer.spread());}content=extend$1$1({},rect,{x:rect.x+content.x,y:rect.y+content.y,width:content.width,height:content.height});navigation.x+=rect.x;navigation.y+=rect.y;title.x+=rect.x;title.y+=rect.y;return {title:extend$1$1({},rect,title),content:extend$1$1({},rect,content),navigation:extend$1$1({},rect,navigation),orientation,preferredSize};}function update(comp){comp.state.resolved=resolveSettings(comp);comp.titleRenderer.itemize({resolved:comp.state.resolved,dock:comp.settings.layout.dock||'center'});comp.itemRenderer.itemize({resolved:comp.state.resolved,dock:comp.settings.layout.dock||'center'});comp.navigationRenderer.itemize({resolved:comp.state.resolved,dock:comp.settings.layout.dock||'center',navigation:comp.settings.settings.navigation});comp.state.display={spacing:8};}function preferredSize(comp,size){let s=0;const dock=comp.settings.layout.dock||'center';const orientation=dock==='top'||dock==='bottom'?'horizontal':'vertical';const d=comp.state.display;const tempLayout=layout(size.inner,d,orientation,{itemRenderer:comp.itemRenderer,navigationRenderer:comp.navigationRenderer,titleRenderer:comp.titleRenderer,isPreliminary:true});s+=d.spacing;// start padding in both vertical and horizontal mode
	s+=tempLayout.preferredSize;s+=d.spacing;// end padding in both vertical and horizontal mode
	return s;}function render$7(legend){const{rect,settings,state,itemRenderer,navigationRenderer,titleRenderer}=legend;const dock=settings.layout.dock;const orientation=dock==='top'||dock==='bottom'?'horizontal':'vertical';const l=layout(rect,state.display,orientation,{itemRenderer,navigationRenderer,titleRenderer});legend.renderer.size(l.content);// l.content.x = 0;
	// l.content.y = 0;
	// l.navigation.x += rect.x;
	// l.navigation.y += rect.y;
	// l.title.x += rect.x;
	// l.title.y += rect.y;
	let contentItems=itemRenderer.getItemsToRender({viewRect:extend$1$1({},l.content,{x:0,y:0})});navigationRenderer.render({rect:l.navigation,itemRenderer});titleRenderer.render({rect:l.title});legend.state.views={layout:l};return contentItems;}const component$1={require:['chart','settings','renderer','update','resolver','registries','symbol'],defaultSettings:{settings:{},style:{item:{label:'$label',shape:'$shape'},title:'$title'}},mounted(renderElement){if(renderElement&&renderElement.parentNode){this.navigationRenderer.renderer.appendTo(renderElement.parentNode);this.titleRenderer.renderer.appendTo(renderElement.parentNode);renderElement.parentNode.insertBefore(this.navigationRenderer.renderer.element(),renderElement);renderElement.parentNode.insertBefore(this.titleRenderer.renderer.element(),renderElement);}this.navigationRenderer.render({rect:this.state.views.layout.navigation,itemRenderer:this.itemRenderer});this.titleRenderer.render({rect:this.state.views.layout.title});},beforeUnmount(){this.navigationRenderer.renderer.clear();this.titleRenderer.renderer.clear();},on:{panstart(){if(this.state.interaction.started){return;}const contentOverflow=this.itemRenderer.getContentOverflow();if(!contentOverflow){return;}this.state.interaction.started=true;this.state.interaction.delta=0;},panmove(e){if(!this.state.interaction.started){return;}const delta=this.itemRenderer.orientation()==='horizontal'?(this.itemRenderer.direction()==='rtl'?-1:1)*e.deltaX:e.deltaY;this.itemRenderer.scroll(delta-this.state.interaction.delta);this.state.interaction.delta=delta;},panend(){this.state.interaction.started=false;},scroll(delta){this.itemRenderer.scroll(-delta);},next(){this.itemRenderer.next();},prev(){this.itemRenderer.prev();}},created(){this.state={interaction:{}};this.onScroll=()=>{const items=render$7(this);this.update(items);};this.itemRenderer=itemRenderer(this,{onScroll:this.onScroll});this.navigationRenderer=navRenderer(this);this.titleRenderer=titleRenderer(this);this.navigationRenderer.renderer=this.registries.renderer('dom')();this.titleRenderer.renderer=this.registries.renderer(this.settings.renderer)();update(this);},preferredSize(obj){return preferredSize(this,obj);},beforeUpdate(){update(this);},render(){return render$7(this);},beforeDestroy(){this.navigationRenderer.renderer.destroy();this.titleRenderer.renderer.destroy();},additionalElements(){return [this.titleRenderer.renderer.element(),this.navigationRenderer.renderer.element()];},_DO_NOT_USE_getInfo(){return {offset:this.itemRenderer.offset()};}};/**
	 * @typedef {object} ComponentLegendCat
	 * @extends ComponentSettings
	 * @property {'legend-cat'} type component type
	 * @property {string} scale Reference to categorical color scale
	 * @example
	{
	  type: 'legend-cat',
	  scale: '<categorical-color-scale>',
	}
	 */const type$1='legend-cat';function categoricalLegend(picasso){picasso.component(type$1,component$1);}function applyAlignJustify(ctx,node){let wiggle=0;const cmd={type:ctx.state.isVertical?'justify':'align',coord:ctx.state.isVertical?'y':'x',pos:ctx.state.isVertical?'height':'width',fn:ctx.state.isVertical?'requiredHeight':'requiredWidth'};wiggle=ctx.state.rect[cmd.pos]-ctx.state.legend.length()-ctx.state.title[cmd.fn]();wiggle*=Math.min(1,Math.max(ctx.stgns[cmd.type],0));node[cmd.coord]+=wiggle;}function generateStopNodes(ctx){const fillScale=ctx.state.legend.fillScale;const majorScale=ctx.state.legend.majorScale;const stops=fillScale.domain().map(d=>({type:'stop',color:fillScale(d),offset:Math.min(1,Math.max(0,majorScale.norm(d)))}));return stops.sort((a,b)=>a.offset-b.offset);}function createTitleNode(ctx){const state=ctx.state;const settings=ctx.stgns;const isTickLeft=state.ticks.anchor==='left';const isTickTop=state.ticks.anchor==='top';let x=state.rect.x;let y=state.rect.y;let textAnchor='start';if(state.title.anchor==='left'){x+=state.title.requiredWidth()-settings.title.padding;y+=state.title.textMetrics.height;y+=isTickTop?state.rect.height-state.title.textBounds.height:0;textAnchor='end';}else if(state.title.anchor==='right'){x+=state.legend.length();x+=settings.title.padding;y+=state.title.textMetrics.height;y+=isTickTop?state.rect.height-state.title.textBounds.height:0;}else if(state.title.anchor==='top'){x+=isTickLeft?state.rect.width:0;y+=state.title.textMetrics.height;textAnchor=isTickLeft?'end':'start';}const node={tag:'legend-title',type:'text',x,y:Math.min(y,state.rect.y+state.rect.height),text:settings.title.text,fill:settings.title.fill,fontSize:settings.title.fontSize,fontFamily:settings.title.fontFamily,maxWidth:settings.title.maxLengthPx,maxLines:settings.title.maxLines,wordBreak:settings.title.wordBreak,hyphens:settings.title.hyphens,lineHeight:settings.title.lineHeight,anchor:textAnchor,title:settings.title.text};applyAlignJustify(ctx,node);return node;}function createLegendRectNode(ctx,stops){const state=ctx.state;const settings=ctx.stgns;const container=state.rect;let x=container.x;let y=container.y;let width=state.isVertical?settings.size:state.legend.length();let height=state.isVertical?state.legend.length():settings.size;if(state.ticks.anchor==='left'){x+=state.rect.width-settings.size;}else if(state.ticks.anchor==='top'){y+=state.rect.height-settings.size;}if(state.title.anchor==='top'){y+=state.title.requiredHeight();}else if(state.title.anchor==='left'){x+=state.title.requiredWidth();}const node={type:'rect',x,y,width,height,fill:{type:'gradient',stops,degree:state.isVertical?90:180}};applyAlignJustify(ctx,node);return node;}function createTickNodes(ctx,legendNode){const state=ctx.state;const settings=ctx.stgns;let anchor='start';const rangeSelectorRect={type:'rect',x:legendNode.x,y:legendNode.y,width:state.isVertical?0:legendNode.width,height:state.isVertical?legendNode.height:0,fill:'transparent'};const nodes=state.ticks.values.map(tick=>{let x=0;let y=0;let dx=0;let dy=0;let baseline='alphabetical';if(state.isVertical){y=legendNode.y+legendNode.height*tick.pos;baseline=tick.pos===0?'text-before-edge':'text-after-edge';}else {x=legendNode.x+legendNode.width*tick.pos;}if(state.ticks.anchor==='right'){x=legendNode.x+settings.size+settings.tick.padding;rangeSelectorRect.x=legendNode.x+legendNode.width;}else if(state.ticks.anchor==='left'){x=legendNode.x-settings.tick.padding;anchor='end';}else if(state.ticks.anchor==='top'){y=legendNode.y-settings.tick.padding;dy-=tick.textMetrics.height*0.25;anchor=tick.pos===0?'start':'end';}else if(state.ticks.anchor==='bottom'){y=legendNode.y+legendNode.height+settings.tick.padding;dy=tick.textMetrics.height*0.8;anchor=tick.pos===0?'start':'end';rangeSelectorRect.y=legendNode.y+legendNode.height;}const node={type:'text',x,y,dx,dy,text:tick.label,fontSize:settings.tick.fontSize,fontFamily:settings.tick.fontFamily,fill:settings.tick.fill,maxWidth:state.isVertical?settings.tick.maxLengthPx:Math.min(settings.tick.maxLengthPx,state.legend.length()/2),anchor,textBoundsFn:ctx.renderer.textBounds,title:tick.label,baseline};return node;});return {type:'container',id:'legend-seq-ticks',children:[...nodes,rangeSelectorRect]};}function resolveAnchor(dock,anchor,map){const mapped=map[dock];if(typeof mapped==='object'){if(mapped.valid.indexOf(anchor)!==-1){return anchor;}return mapped.default;}return map.default;}function resolveTickAnchor(settings){const dock=settings.layout.dock;const anchor=settings.settings.tick.anchor;const dockAnchorMap={left:{valid:['left','right'],default:'left'},right:{valid:['left','right'],default:'right'},top:{valid:['top','bottom'],default:'top'},bottom:{valid:['top','bottom'],default:'bottom'},default:'right'};return resolveAnchor(dock,anchor,dockAnchorMap);}function resolveTitleAnchor(settings){const dockAnchorMap={left:{valid:['top'],default:'top'},right:{valid:['top'],default:'top'},top:{valid:['left','right'],default:'left'},bottom:{valid:['left','right'],default:'left'},default:'top'};const dock=settings.layout.dock;const anchor=settings.settings.title.anchor;return resolveAnchor(dock,anchor,dockAnchorMap);}function initRect(ctx,size){const rect={x:0,y:0,width:0,height:0};const padding=ctx.stgns.padding;rect.x=padding.left;rect.y=padding.top;rect.width=size.width-padding.left-padding.right;rect.height=size.height-padding.top-padding.bottom;return rect;}function getTicks(ctx,majorScale){const values=majorScale.domain();let labels=values;let labelFn=ctx.stgns.tick.label;if(!labelFn&&ctx.formatter){labelFn=ctx.formatter;}else if(!labelFn&&majorScale.data().fields){labelFn=majorScale.data().fields[0].formatter();}if(typeof labelFn==='function'){labels=values.map(labelFn).map(String);}const ticks=values.map((value,i)=>{const label=labels[i];return {value,label,pos:majorScale.norm(parseFloat(value,10)),textMetrics:ctx.renderer.measureText({text:label,fontSize:ctx.stgns.tick.fontSize,fontFamily:ctx.stgns.tick.fontFamily})};});return ticks;}function initState(ctx){const isVertical=ctx.settings.layout.dock!=='top'&&ctx.settings.layout.dock!=='bottom';const titleStgns=ctx.stgns.title;const fillScale=ctx.chart.scale(ctx.stgns.fill);const majorScale=ctx.chart.scale(ctx.stgns.major);const tickValues=getTicks(ctx,majorScale);const tickAnchor=resolveTickAnchor(ctx.settings);if(typeof titleStgns.text==='undefined'){const fields=majorScale.data().fields;titleStgns.text=fields&&fields[0]?fields[0].title():'';}const titleTextMetrics=ctx.renderer.measureText({text:titleStgns.text,fontSize:titleStgns.fontSize,fontFamily:titleStgns.fontFamily});const titleTextBounds=ctx.renderer.textBounds({text:titleStgns.text,fontSize:titleStgns.fontSize,fontFamily:titleStgns.fontFamily,maxLines:titleStgns.maxLines,maxWidth:titleStgns.maxLengthPx,wordBreak:titleStgns.wordBreak,hyphens:titleStgns.hyphens,lineHeight:titleStgns.lineHeight});const state={isVertical,nodes:[],title:{anchor:resolveTitleAnchor(ctx.settings),textMetrics:titleTextMetrics,textBounds:titleTextBounds,requiredWidth:()=>{if(!titleStgns.show){return 0;}let w=titleTextBounds.width;let mw=titleStgns.maxLengthPx;if(!isVertical){w+=titleStgns.padding;mw+=titleStgns.padding;}return Math.min(w,mw,state.rect.width);},requiredHeight:()=>{if(!titleStgns.show){return 0;}let h=titleTextBounds.height;if(isVertical){h+=titleStgns.padding;}return Math.min(h,state.rect.height);}},ticks:{values:tickValues,anchor:tickAnchor,length:Math.min(Math.max(...tickValues.map(t=>t.textMetrics.width)),ctx.stgns.tick.maxLengthPx),requiredHeight:()=>tickAnchor==='top'?Math.max(...state.ticks.values.map(t=>t.textMetrics.height))+ctx.stgns.tick.padding:0,height:Math.max(...tickValues.map(t=>t.textMetrics.height))},legend:{fillScale,majorScale,length:()=>{const pos=isVertical?'height':'width';const fnPos=isVertical?'requiredHeight':'requiredWidth';const len=Math.min(state.rect[pos],state.rect[pos]*ctx.stgns.length)-state.title[fnPos]();return Math.max(0,Math.min(len,ctx.stgns.maxLengthPx));}}};return state;}/**
	 * Component settings
	 * @typedef {object} ComponentLegendSeq.settings
	 * @property {string} fill - Reference to definition of sequential color scale
	 * @property {string} major - Reference to definition of linear scale
	 * @property {number} [size=15] - Size in pixels of the legend, if vertical is the width and height otherwise
	 * @property {number} [length=1] - A value in the range 0-1 indicating the length of the legend node
	 * @property {number} [maxLengthPx=250] - Max length in pixels
	 * @property {number} [align=0.5] - A value in the range 0-1 indicating horizontal alignment of the legend's content. 0 aligns to the left, 1 to the right.
	 * @property {number} [justify=0] - A value in the range 0-1 indicating vertical alignment of the legend's content. 0 aligns to the top, 1 to the bottom.
	 * @property {object} [padding]
	 * @property {number} [padding.left=5] - Size in pixels
	 * @property {number} [padding.right=5] - Size in pixels
	 * @property {number} [padding.top=5] - Size in pixels
	 * @property {number} [padding.bottom=5] - Size in pixels
	 * @property {object} [tick]
	 * @property {function} [tick.label] - Function applied to all tick values. Return value should be a string and is used as label
	 * @property {string} [tick.fill='#595959'] - Tick color
	 * @property {string} [tick.fontSize='12px'] - Font size in pixels
	 * @property {string} [tick.fontFamily='Arial'] - Font family
	 * @property {number} [tick.maxLengthPx=150] - Max length in pixels
	 * @property {string} [tick.anchor=''] - Where to anchor the tick in relation to the legend node, supported values are [top, bottom, left and right] or empty string to auto anchor
	 * @property {number} [tick.padding=5] - padding in pixels to the legend node
	 * @property {object} [title] - Title settings
	 * @property {boolean} [title.show=true] - Toggle title on/off
	 * @property {string} [title.text=''] - Title text. Defaults to the title of the provided data field
	 * @property {string} [title.fill='#595959'] - Title color
	 * @property {string} [title.fontSize='12px'] - Font size in pixels
	 * @property {string} [title.fontFamily='Arial'] - Font family
	 * @property {number} [title.maxLengthPx=100] - Max length in pixels
	 * @property {number} [title.padding=5] - padding in pixels to the legend node
	 * @property {string} [title.anchor=''] - Where to anchor the title in relation to the legend node, supported values are [top, left and right] or empty string to auto anchor
	 * @property {string} [title.wordBreak='none'] - How overflowing title is handled, if it should insert line breaks at word boundries (break-word) or character boundries (break-all)
	 * @property {string} [title.hyphens='auto'] - How words should be hyphenated when text wraps across multiple lines (only applicable with wordBreak)
	 * @property {number} [title.maxLines=2] - Number of allowed lines if title contains line breaks (only applicable with wordBreak)
	 * @property {number} [title.lineHeight=1.2] - A multiplier defining the distance between lines (only applicable with wordBreak)
	 */const legendDef={require:['chart','settings','renderer'],defaultSettings:{layout:{displayOrder:0,dock:'right'},settings:{size:15,length:0.5,maxLengthPx:250,align:0.5,justify:0,padding:{left:5,right:5,top:5,bottom:5},tick:{label:null,fill:'#595959',fontSize:'12px',fontFamily:'Arial',maxLengthPx:100,anchor:null,// Use default based on dock
	padding:5},title:{show:true,text:undefined,fill:'#595959',fontSize:'12px',fontFamily:'Arial',maxLengthPx:100,padding:5,maxLines:2,wordBreak:'none',lineHeight:1.2,hyphens:'auto',anchor:null// Use default based on dock
	}}},preferredSize(opts){const state=this.state;state.rect=initRect(this,opts.inner);// Init with size of legend
	let prefSize=this.stgns.size;// Append paddings
	const paddings=state.isVertical?this.stgns.padding.left+this.stgns.padding.right:this.stgns.padding.top+this.stgns.padding.bottom;prefSize+=paddings;// Append tick size
	const maxSize=Math.max(opts.inner.width,opts.inner.height);if(state.ticks.anchor==='left'||state.ticks.anchor==='right'){const tHeight=state.ticks.values.reduce((sum,t)=>sum+t.textMetrics.height,0);if(tHeight>this.state.legend.length()){return maxSize;}prefSize+=state.ticks.length;}else {const tWidth=state.ticks.length;if(tWidth>this.state.legend.length()){return maxSize;}prefSize+=Math.max(...state.ticks.values.map(t=>t.textMetrics.height));}prefSize+=this.stgns.tick.padding;// Append or use title size
	if(this.stgns.title.show){if(state.title.anchor==='left'||state.title.anchor==='right'){prefSize=Math.max(state.title.textBounds.height+paddings,prefSize);}else {prefSize=Math.max(prefSize,state.title.requiredWidth()+paddings);}}this.state.preferredSize=prefSize;return prefSize;},created(){this.stgns=this.settings.settings;this.state=initState(this);},beforeUpdate(opts){this.stgns=opts.settings.settings;this.state=initState(this);},beforeRender(opts){this.state.nodes=[];this.state.rect=initRect(this,opts.size);if(this.stgns.title.show){const titleNode=createTitleNode(this);this.state.nodes.push(titleNode);}const stopNodes=generateStopNodes(this);const rectNode=createLegendRectNode(this,stopNodes);const tickNodes=createTickNodes(this,rectNode);const targetNode={// The target node enables range selection component to limit its range to a specific area
	id:'legend-seq-target',type:'container',children:[rectNode,tickNodes]};this.state.nodes.push(targetNode);},render(){return this.state.nodes;}};/**
	 * @typedef {object} ComponentLegendSeq
	 * @extends ComponentSettings
	 * @property {'legend-seq'} type component type
	 * @example
	{
	  type: 'legend-seq',
	  settings: {
	    fill: '<sequential-color-scale>',
	    major: '<linear-scale>',
	  }
	}
	 */function sequentialLegend$1(picasso){picasso.component('legend-seq',legendDef);}/**
	 * Callback function for layer sort
	 * @callback ComponentLine~LayerSort
	 * @param {object} a
	 * @param {string} a.id
	 * @param {Array<DatumExtract>} a.data
	 * @param {object} b
	 * @param {string} b.id
	 * @param {Array<DatumExtract>} b.data
	 *//**
	 * Component settings
	 * @typedef {object}
	 * @alias ComponentLine.settings
	 */const SETTINGS={/**
	   * @typedef {object}
	   */coordinates:{/**
	     * @type {number} */minor:0.5,/**
	     * @type {number} */major:0.5,/**
	     * @type {number=} */layerId:0,/**
	     * @type {DatumBoolean=} */defined:true},/**
	   * @typedef {object} */layers:{/**
	     * @type {string=} */curve:'linear',/**
	     * @type {boolean=} */show:true,/**
	     * @typedef {object} */line:{/**
	       * @type {string=} */stroke:'#ccc',/**
	       * @type {number=} */strokeWidth:1,/**
	       * @type {string=} */strokeLinejoin:'miter',/**
	       * @type {string=} */strokeDasharray:undefined,/**
	       * @type {number=} */opacity:1,/**
	       * @type {boolean=} */show:true,/**
	       * @type {boolean=} */showMinor0:true},/**
	     * @typedef {object} */area:{/**
	       * @type {string=} */fill:'#ccc',/**
	       * @type {number=} */opacity:0.8,/**
	       * @type {boolean=} */show:true}}};function createDisplayLayer(points,_ref){let{generatorType,item,data,major,minor,layerObj,stngs}=_ref;let fill=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'';const d={type:'path',points,generatorType,major,minor,layerObj,stngs,opacity:item.opacity,stroke:item.stroke,strokeWidth:item.strokeWidth,strokeLinejoin:item.strokeLinejoin,fill:fill||item.fill,data};if(item.strokeDasharray){d.strokeDasharray=item.strokeDasharray;}return d;}function createDisplayLayers(layers,_ref2){let{width,height,missingMinor0,stngs}=_ref2;const nodes=[];const layerStngs=stngs.layers||{};layers.forEach(layer=>{const{lineObj,layerObj,areaObj,points}=layer;let minor={size:height,p:'y'};let major={size:width,p:'x'};if(stngs.orientation==='vertical'){const temp=extend$1$1(true,{},major);major=extend$1$1(true,{},minor);minor=extend$1$1(true,{},temp);}// area layer
	if(layerStngs.area&&areaObj.show!==false){nodes.push(createDisplayLayer(points,{data:layer.consumableData,item:areaObj,generatorType:'area',major,minor,layerObj,stngs}));}// main line layer
	if(lineObj&&lineObj.show!==false){nodes.push(createDisplayLayer(points,{data:layer.consumableData,item:lineObj,generatorType:"line".concat(minor.p.toUpperCase(),"1"),major,minor,layerObj,stngs},'none'));// secondary line layer, used only when rendering area
	if(!missingMinor0&&layerStngs.area&&areaObj.show!==false&&lineObj.showMinor0!==false){nodes.push(createDisplayLayer(points,{data:layer.consumableData,item:lineObj,generatorType:"line".concat(minor.p.toUpperCase(),"0"),major,minor,layerObj,stngs},'none'));}}});return nodes;}function resolve$2(_ref3){let{data,stngs,rect,resolver,style,domain}=_ref3;const{width,height}=rect;const coordinates=resolver.resolve({data,defaults:SETTINGS.coordinates,settings:stngs.coordinates||{},scaled:{major:stngs.orientation==='vertical'?height:width,minor:stngs.orientation==='vertical'?width:height}});// there are two cases when a line should be interrupted:
	// 1. When the minor value is undefined (this case is easily handled by the lineGenerator.defined).
	// 2. When a line is moving over a domain that may not coincide with the domain on the major scale.
	// For the second case, dummy points need to be injected in order to create values which will cause gaps as they fulfill the first case.
	// These dummy points need to be injected only when: the domain is discrete, connect !== false and multiple layers are defined
	const injectDummy=!stngs.connect&&domain.length>2&&(typeof stngs.coordinates.layerId==='function'||typeof stngs.coordinates.layerId==='object');// collect points into layers
	const layerIds={};let numLines=0;for(let i=0;i<coordinates.items.length;i++){let p=coordinates.items[i];let lid=p.layerId;if(injectDummy){// inject dummy if the previous point on the major domain is not the same as the prev point on the line's domain.
	// this works only if a datum's value property is the same primitive as in the domain.
	const lastItem=layerIds[lid]?layerIds[lid].items[layerIds[lid].items.length-1]:null;const lastOrderIdx=lastItem?domain.indexOf(lastItem.data.major?lastItem.data.major.value:lastItem.data.value):null;if(lastItem&&domain.indexOf(p.data.major?p.data.major.value:p.data.value)-1!==lastOrderIdx){layerIds[lid].items.push({dummy:true});}}layerIds[lid]=layerIds[lid]||{order:numLines++,id:lid,items:[],dataItems:[],consumableData:{}};layerIds[lid].dataItems.push(p.data);layerIds[lid].items.push(p);}const metaLayers=Object.keys(layerIds).map(lid=>{layerIds[lid].consumableData=_objectSpread2$1({points:layerIds[lid].dataItems},layerIds[lid].dataItems[0]);return layerIds[lid];});const layersData={items:metaLayers.map(layer=>layer.consumableData)};const layerStngs=stngs.layers||{};const layersResolved=resolver.resolve({data:layersData,defaults:{curve:SETTINGS.layers.curve,show:SETTINGS.layers.show},settings:{curve:layerStngs.curve,show:layerStngs.show}});const linesResolved=resolver.resolve({data:layersData,defaults:extend$1$1({},SETTINGS.layers.line,style.line),settings:layerStngs.line});const areasResolved=resolver.resolve({data:layersData,defaults:extend$1$1({},SETTINGS.layers.area,style.area),settings:layerStngs.area});return {coordinates,metaLayers,layers:layersResolved,lines:linesResolved,areas:areasResolved};}function calculateVisibleLayers(opts){const{metaLayers,coordinates,layers,lines,areas}=resolve$2(opts);const visibleLayers=[];metaLayers.forEach((layer,ix)=>{const layerObj=layers.items[ix];if(layerObj.show===false){return;}// layerObj.points = [];
	layerObj.datum=layerObj.data;layerObj.data=[];layerObj.id=layer.id;const values=[];const points=[];let point;let pData;for(let i=0;i<layer.items.length;i++){point=layer.items[i];pData=point.data;if(!point.dummy){if(isNaN(point.major)){continue;}if(opts.missingMinor0){point.minor0=coordinates.settings.minor.scale?coordinates.settings.minor.scale(pData.minor0?pData.minor0.value:0):0;}if(!isNaN(point.minor)){values.push(point.minor);}layerObj.data.push(point.data);}points.push(point);}const median=values.sort((a,b)=>a-b)[Math.floor((values.length-1)/2)];visibleLayers.push({layerObj,lineObj:lines.items[ix],areaObj:areas.items[ix],median,points,consumableData:layer.consumableData});});return visibleLayers;}const lineMarkerComponent={require:['chart','resolver'],defaultSettings:{style:{area:'$shape',line:'$shape-outline'}},created(){},render(_ref4){let{data}=_ref4;// console.log("DATA", data);
	const{width,height}=this.rect;this.stngs=this.settings.settings||{};const missingMinor0=!this.stngs.coordinates||typeof this.stngs.coordinates.minor0==='undefined';const visibleLayers=calculateVisibleLayers({data,stngs:this.stngs,rect:this.rect,resolver:this.resolver,style:this.style,missingMinor0,domain:this.stngs.coordinates&&this.stngs.coordinates.major&&this.stngs.coordinates.major.scale?this.chart.scale(this.stngs.coordinates.major.scale).domain():[]});if(this.stngs.layers&&this.stngs.layers.sort){const sortable=visibleLayers.map(v=>({id:v.layerObj.id,data:v.layerObj.data})).sort(this.stngs.layers.sort).map(s=>s.id);visibleLayers.sort((a,b)=>sortable.indexOf(a.layerObj.id)-sortable.indexOf(b.layerObj.id));}else {visibleLayers.sort((a,b)=>a.median-b.median);}// generate visuals
	return createDisplayLayers(visibleLayers,{width,height,missingMinor0,stngs:this.stngs});}};/**
	 * @typedef {object} ComponentLine
	 * @extends ComponentSettings
	 * @property {'line'} type component type
	 * @example
	{
	  type: "line",
	  data: {
	    extract: {
	      field: "Year",
	      props: {
	        sales: { field: "Sales" },
	      },
	    },
	  },
	  settings: {
	    coordinates: {
	      major: { scale: "t" },
	      minor: { scale: "y", ref: "sales" },
	    },
	  },
	}
	 */const type='line';function line(picasso){picasso.component(type,lineMarkerComponent);}/**
	 * @typedef {object}
	 * @alias ComponentBrushArea.settings
	 */const DEFAULT_SETTINGS$1={/**
	   * @type {object}
	   */brush:{/**
	     * @type {Array<BrushTargetConfig>}
	     */components:[]}};/**
	 * Transform the incoming event into point in the local coordinate system. That is the coordinate system of the component.
	 * @private
	 * @param {object} ctx - Context
	 * @param {object} event - Incoming event, either native event or hammer event
	 * @param {boolean} clamp - True to clamp the point inside the component bounds
	 * @returns {point}
	 */function getLocalPoint(ctx,event){let clamp=arguments.length>2&&arguments[2]!==undefined?arguments[2]:true;let x;let y;if(typeof event.center==='object'){x=event.center.x;y=event.center.y;}else {x=event.clientX;y=event.clientY;}const localX=x-ctx.state.boundingRect.left;const localY=y-ctx.state.boundingRect.top;return {x:clamp?Math.max(0,Math.min(localX,ctx.rect.width)):localX,y:clamp?Math.max(0,Math.min(localY,ctx.rect.height)):localY};}/**
	 * Transform a local point into a point in the chart coordinate system.
	 * @private
	 * @param {object} ctx - Context
	 * @param {object} p - Point to transform
	 * @returns {point}
	 */function localToChartPoint(ctx,p){return {x:p.x+ctx.rect.x,y:p.y+ctx.rect.y};}/**
	 * Extract and apply default brush configuration.
	 * @private
	 * @param {object} settings
	 * @returns {object[]} An Array of brush configurations
	 */function getBrushConfig(settings){return settings.settings.brush.components.map(b=>({key:b.key,contexts:b.contexts,data:b.data,action:b.action||'set'}));}/**
	 * End all active brush contexts.
	 * @private
	 * @param {oject} state
	 * @param {object} chart - Chart instance
	 */function doEndBrush(state,chart){state.brushConfig.forEach(config=>{if(Array.isArray(config.contexts)){config.contexts.forEach(context=>{chart.brush(context).end();});}});}/**
	 * Convert two points into a rectangle.
	 * @private
	 * @param {Point} p0
	 * @param {Point} p1
	 * @returns {Rect}
	 */function toRect(p0,p1){const xMin=Math.min(p0.x,p1.x);const yMin=Math.min(p0.y,p1.y);const xMax=Math.max(p0.x,p1.x);const yMax=Math.max(p0.y,p1.y);return {x:xMin,y:yMin,width:xMax-xMin,height:yMax-yMin};}/**
	 * Perform a brush on the given area.
	 * @private
	 * @param {object} ctx
	 */function doAreaBrush(ctx){if(ctx.state.active){const start=localToChartPoint(ctx,ctx.state.start);const end=localToChartPoint(ctx,ctx.state.end);const shapes=ctx.chart.shapesAt(toRect(start,end),{components:ctx.state.brushConfig});ctx.chart.brushFromShapes(shapes,{components:ctx.state.brushConfig});}}function render$6(ctx){ctx.renderer.render([extend$1$1({type:'rect'},toRect(ctx.state.start,ctx.state.end),ctx.style.area)]);}function resetState(){return {start:{x:0,y:0},end:{x:0,y:0},active:false};}const definition={require:['chart','renderer'],defaultSettings:{layout:{displayOrder:99},settings:DEFAULT_SETTINGS$1,style:{area:'$selection-area-target'}},on:{areaStart(e){this.start(e);},areaMove(e){this.move(e);},areaEnd(e){this.end(e);},areaCancel(){this.cancel();}},created(){this.state=resetState();},preferredSize(){return 0;},render(){},start(e){this.state.boundingRect=this.renderer.element().getBoundingClientRect();const p=getLocalPoint(this,e,false);// Require event to be inside the component bounds
	if(!testRectPoint({x:0,y:0,width:this.rect.width,height:this.rect.height},p)){return;}this.state.brushConfig=getBrushConfig(this.settings);this.state.start=getLocalPoint(this,e);this.state.active=true;},move(e){if(!this.state.active){return;}this.state.end=getLocalPoint(this,e);doAreaBrush(this);render$6(this);},end(){if(!this.state.active){return;}this.state=resetState();this.renderer.render([]);},cancel(){if(!this.state.active){return;}doEndBrush(this.state,this.chart);this.state=resetState();this.renderer.render([]);}};/**
	 * A component that can brush a rectangular area
	 * @typedef {object} ComponentBrushArea
	 * @extends ComponentSettings
	 * @property {'brush-area'} type component type
	 * @example
	 * {
	 *  type: 'brush-area',
	 *  brush: {
	 *    components: [{ key: '<target-component>', contexts: ['highlight'] }]
	 *  }
	 * }
	 */function areaBrush(picasso){picasso.component('brush-area',definition);}function extractor(nodes,_ref){let{chart,scale,props,h}=_ref;const dataCtx={resources:{dataset:chart.dataset,scale:chart.scale,formatter:chart.formatter},scale,h};const data=[];nodes.forEach(node=>{if(typeof props.extract==='function'){const ctx=extend$1$1({node},dataCtx);data.push(props.extract(ctx));}});return data;}function resolveClasses(props,opts){return {tooltip:typeof props.tooltipClass==='function'?props.tooltipClass({dock:opts.dock}):props.tooltipClass,content:typeof props.contentClass==='function'?props.contentClass({dock:opts.dock}):props.contentClass,arrow:typeof props.arrowClass==='function'?props.arrowClass({dock:opts.dock}):props.arrowClass};}function resolveContent(h,data,style,props){return props.content({h,style,data});}function render$5(data,placement,_ref){let{renderer,style,props,h}=_ref;const classes=resolveClasses(props,placement);const content=resolveContent(h,data,style,props);const tooltipDefaultStyle={position:'relative',display:'inline-block'};const tooltipNode=h("div",{dir:props.direction,class:classString(extend$1$1({'pic-tooltip':true},classes.tooltip)),style:extend$1$1(tooltipDefaultStyle,placement.computedTooltipStyle)},h("div",{style:style.content,class:classString(extend$1$1({'pic-tooltip-content':true},classes.content))},content),h("div",{class:classString(extend$1$1({'pic-tooltip-arrow':true},classes.arrow)),style:extend$1$1({},style.arrow,style["arrow-".concat(placement.dock)],placement.computedArrowStyle)}));renderer.render(tooltipNode);return renderer.element().children[0];}// Successfull flow: pending -> active -> fulfilled (only with duration)
	// Cancelled flow: pending -> active -> cancelled
	// Rejected flow: pending -> rejected
	// Debounced flow: pending -> debounced -> pending -> [rejected|fulfilled]
	function dispatcherState(){const fn=function fn(){};const on={pending:[],debounced:[],active:[],cancelled:[],rejected:[],fulfilled:[]};let state;fn.set=s=>{state=s;on[state].forEach(event=>event(s));};fn.on=(key,event)=>{if(Array.isArray(key)){key.forEach(k=>on[k].push(event));}else {on[key].push(event);}};fn.destroy=()=>{Object.keys(on).forEach(key=>{on[key].length=0;});};// fn.on(['pending', 'debounced', 'active', 'cancelled', 'rejected', 'fulfilled'], (e) => {
	//   console.log(e);
	// });
	return fn;}function timeSpanDispatcher(_ref){let{defaultDuration,defaultDelay}=_ref;let actionId=null;let fulfilledId=null;let isActive=false;const state=dispatcherState();const fn=function fn(){};const fulfilled=()=>{actionId=null;fulfilledId=null;isActive=false;state.set('fulfilled');};fn.invoke=function(action){let duration=arguments.length>1&&arguments[1]!==undefined?arguments[1]:defaultDuration;let delay=arguments.length>2&&arguments[2]!==undefined?arguments[2]:defaultDelay;if(actionId){clearTimeout(actionId);state.set('debounced');}state.set('pending');actionId=setTimeout(()=>{action();isActive=true;actionId=null;state.set('active');},delay);if(duration>0){if(fulfilledId){clearTimeout(fulfilledId);}fulfilledId=setTimeout(fulfilled,duration+Math.max(delay,0));}};fn.clear=()=>{if(isActive){state.set('cancelled');}else if(actionId){clearTimeout(actionId);state.set('rejected');}if(fulfilledId){clearTimeout(fulfilledId);}actionId=null;fulfilledId=null;isActive=false;};fn.on=(key,event)=>{state.on(key,event);};fn.destroy=()=>{fn.clear();state.destroy();};return fn;}function getDockTransform(){let offset=arguments.length>0&&arguments[0]!==undefined?arguments[0]:0;return {left:"translate(-100%,-50%) translateX(".concat(-offset,"px)"),right:"translate(".concat(offset,"px, -50%)"),top:"translate(-50%, -100%) translateY(".concat(-offset,"px)"),bottom:"translate(-50%, ".concat(offset,"px)"),inside:"translate(-50%, -50%)"};}function getDockOffset(width,height){let offset=arguments.length>2&&arguments[2]!==undefined?arguments[2]:0;return {left:{x:-width-offset,y:-height/2},right:{x:offset,y:-height/2},top:{x:-width/2,y:-height-offset},bottom:{x:-width/2,y:offset},inside:{x:-width/2,y:-height/2}};}function getTooltipLeft(_ref){let{options,docks,dockOffsets,targetBounds,area,width}=_ref;const dock='top';const vx=options.area==='target'?docks[dock].x:targetBounds.left+docks[dock].x;const vy=options.area==='target'?docks[dock].y:targetBounds.top+docks[dock].y;const offset=dockOffsets[dock];const rect={x:vx+offset.x,y:vy+offset.y,width};let left=docks.top.x;if(rect.x<0&&rect.x+rect.width>area.width){return left;}if(rect.x<0){left-=rect.x;}else if(rect.x+rect.width>area.width){left-=rect.x+rect.width-area.width;}return left;}function getComputedArrowStyle(offset,borderWidth){const sign=offset>0?'-':'+';offset=Math.abs(offset);if(borderWidth===undefined){borderWidth=offset;}return {left:{left:'100%',top:"calc(50% ".concat(sign," ").concat(offset,"px)"),borderWidth:"".concat(borderWidth,"px")},right:{left:"".concat(-offset*2,"px"),top:"calc(50% ".concat(sign," ").concat(offset,"px)"),borderWidth:"".concat(borderWidth,"px")},top:{left:"calc(50% ".concat(sign," ").concat(offset,"px)"),top:'100%',borderWidth:"".concat(borderWidth,"px")},bottom:{left:"calc(50% ".concat(sign," ").concat(offset,"px)"),top:"".concat(-offset*2,"px"),borderWidth:"".concat(borderWidth,"px")},inside:{left:'0px',top:'0px',borderWidth:'0px'}};}function isInsideArea(area,vx,vy,width,height,offset){const rect={x:vx+offset.x,y:vy+offset.y,width,height};if(rect.x<0||rect.y<0){return false;}if(rect.x+rect.width>area.width||rect.y+rect.height>area.height){return false;}return true;}/**
	 * @private
	 * @param {vx} vx X-coordinate realative to the area
	 * @param {vy} vy Y-coordinate realative to the area
	 */function calcOffset(_ref2){let{area,vx,vy,width,height,offset}=_ref2;const rect={x:vx+offset.x,y:vy+offset.y,width,height};let offsetX=rect.x<0?-rect.x:0;let offsetY=rect.y<0?-rect.y:0;offsetX+=rect.x+rect.width>area.width?-(rect.x+rect.width-area.width):0;offsetY+=rect.y+rect.height>area.height?-(rect.y+rect.height-area.height):0;return {x:offsetX,y:offsetY};}function alignToBounds(_ref3){let{resources,nodes,pointer,width:elmWidth,height:elmHeight,options}=_ref3;const{targetBounds}=pointer;const{x,y,width,height}=resources.getNodeBoundsRelativeToTarget(nodes[0]);const docks={left:{x,y:y+height/2},right:{x:x+width,y:y+height/2},top:{x:x+width/2,y},bottom:{x:x+width/2,y:y+height},inside:{x:x+width/2,y:y+height/2}};// Check if explicit dock
	const dockTransforms=getDockTransform(options.offset);const transform=dockTransforms[options.dock];if(transform){return {computedTooltipStyle:{left:"".concat(docks[options.dock].x,"px"),top:"".concat(docks[options.dock].y,"px"),transform},computedArrowStyle:getComputedArrowStyle(options.offset)[options.dock],dock:options.dock};}const area={width:options.area==='target'?targetBounds.width:window.innerWidth,height:options.area==='target'?targetBounds.height:window.innerHeight};const dockOffsets=getDockOffset(elmWidth,elmHeight,options.offset);const dockOrder=['top','left','right','bottom','inside'];for(let i=0;i<dockOrder.length;i+=1){const dock=dockOrder[i];const vx=options.area==='target'?docks[dock].x:targetBounds.left+docks[dock].x;const vy=options.area==='target'?docks[dock].y:targetBounds.top+docks[dock].y;if(isInsideArea(area,vx,vy,elmWidth,elmHeight,dockOffsets[dock])){return {computedTooltipStyle:{left:"".concat(docks[dock].x,"px"),top:"".concat(docks[dock].y,"px"),transform:dockTransforms[dock]},computedArrowStyle:getComputedArrowStyle(options.offset)[dock],dock};}}const left=getTooltipLeft({options,docks,dockOffsets,targetBounds,area,width:elmWidth});return {computedTooltipStyle:{left:"".concat(left,"px"),top:"".concat(docks.top.y,"px"),transform:dockTransforms.top},computedArrowStyle:getComputedArrowStyle(options.offset+left-docks.top.x,options.offset).top,dock:'top'};}function alignToPoint(_ref4){let{options,pointer,width,height,dockOrder,x,y}=_ref4;const{targetBounds}=pointer;// Check if explicit dock
	const dockTransforms=getDockTransform(options.offset);const transform=dockTransforms[options.dock];if(transform){return {computedTooltipStyle:{left:"".concat(x,"px"),top:"".concat(y,"px"),transform},computedArrowStyle:getComputedArrowStyle(options.offset)[options.dock],dock:options.dock};}const area={width:options.area==='target'?targetBounds.width:window.innerWidth,height:options.area==='target'?targetBounds.height:window.innerHeight};const dockOffsets=getDockOffset(width,height,options.offset);const results=[];const edgeMargin=20;const vx=options.area==='target'?x:targetBounds.left+x;const vy=options.area==='target'?y:targetBounds.top+y;for(let i=0;i<dockOrder.length;i+=1){const dock=dockOrder[i];const offset=calcOffset({area,vx,vy,width,height,offset:dockOffsets[dock]});const computedTooltipStyle={left:"".concat(x,"px"),top:"".concat(y,"px"),transform:dockTransforms[dock]};const computedArrowStyle=getComputedArrowStyle(options.offset)[dock];if(offset.x!==0){computedTooltipStyle.width="".concat(width-edgeMargin-Math.abs(offset.x),"px");if(dock==='top'||dock==='bottom'){computedTooltipStyle.left="".concat(x+offset.x,"px");computedArrowStyle.left="calc(50% ".concat(offset.x>0?'-':'+'," ").concat(Math.abs(offset.x),"px)");}}const result={computedTooltipStyle,computedArrowStyle,dock,rect:{width,height}};if(offset.x===0&&offset.y===0){return result;}result.offset=offset;results.push(result);}results.sort((a,b)=>Math.abs(a.offset.x)-Math.abs(b.offset.x));return results[0];}function alignToPointer(_ref5){let{options,pointer,width,height}=_ref5;const{x,y}=pointer;return alignToPoint({x,y,pointer,width,height,options,dockOrder:['top','left','right','bottom']});}function alignToSlice(_ref6){let{options,pointer,width,height,nodes,resources}=_ref6;const node=nodes[0];const{dx,dy}=pointer;const componentBounds=resources.getComponentBoundsFromNode(node);// cx and cy relative to targetBounds
	const center={x:dx+componentBounds.x+componentBounds.width/2,y:dy+componentBounds.y+componentBounds.height/2};const{start,end,outerRadius}=node.desc.slice;// Node origin is at 12 o clock, clockwise, but Math uses 3 a clock, so it's transformed to origin at 3 a clock
	const middle=(start+end)/2-Math.PI/2;const PI2=Math.PI*2;const radians=(middle%PI2+PI2)%PI2;let dockOrder=['top','left','right','bottom'];if(options.dock==='auto'){if(radians<=Math.PI/4||radians>=Math.PI*7/4){dockOrder=['right','top','bottom','left'];}else if(radians<=Math.PI*3/4){dockOrder=['bottom','left','right','top'];}else if(radians<=Math.PI*5/4){dockOrder=['left','top','bottom','right'];}else {dockOrder=['top','left','right','bottom'];}}return alignToPoint({x:center.x+outerRadius*componentBounds.scaleRatio.x*Math.cos(radians),y:center.y+outerRadius*componentBounds.scaleRatio.y*Math.sin(radians),pointer,width,height,options,dockOrder});}function getComponentBoundsFromNode(node,pointer,chart){const comp=node.key?chart.component(node.key):chart.componentsFromPoint({x:pointer.clientX,y:pointer.clientY})[0];if(!comp){return {x:0,y:0,width:0,height:0,scaleRatio:{x:1,y:1}};}const componentSize=comp.rect;return extend$1$1({scaleRatio:componentSize.scaleRatio},componentSize.computedInner);}function getNodeBoundsRelativeToTarget(node,pointer,chart){const componentBounds=getComponentBoundsFromNode(node,pointer,chart);const bounds=node.bounds;return {x:componentBounds.x+pointer.dx+bounds.x,y:componentBounds.y+pointer.dy+bounds.y,width:bounds.width,height:bounds.height};}const STRATEGIES={bounds:alignToBounds,pointer:alignToPointer,slice:alignToSlice};function placement(_ref7,_ref8){let{width,height}=_ref7;let{chart,state,props}=_ref8;const propCtx={resources:{formatter:chart.formatter,scale:chart.scale,component:chart.component,getComponentBoundsFromNode:node=>getComponentBoundsFromNode(node,state.pointer,chart),getNodeBoundsRelativeToTarget:node=>getNodeBoundsRelativeToTarget(node,state.pointer,chart)},nodes:state.activeNodes,pointer:state.pointer,width,height};const type=typeof props.placement;if(type==='object'&&typeof props.placement.fn==='function'){// Custom placement strategy function
	return props.placement.fn(propCtx);}let opts={type:'pointer',offset:8,dock:'auto',area:'viewport'};if(type==='function'){// Custom placement function
	opts=extend$1$1(opts,props.placement(propCtx));}if(type==='object'&&STRATEGIES[props.placement.type]){// Predefined placement function with options
	opts=extend$1$1(opts,props.placement);}else if(type==='string'&&STRATEGIES[props.placement]){// Predefined placement function without options
	opts=extend$1$1(opts,{type:props.placement});}propCtx.options=opts;const plcm=STRATEGIES[opts.type](propCtx);let{x:minX,y:minY,width:maxX,height:maxY}=propCtx.resources.getComponentBoundsFromNode(propCtx.nodes[0]);minX+=propCtx.pointer.dx;maxX+=minX;minY+=propCtx.pointer.dy;maxY+=minY;// Clamp tooltip position
	plcm.computedTooltipStyle.left="".concat(Math.min(Math.max(0,minX,parseFloat(plcm.computedTooltipStyle.left)),maxX),"px");plcm.computedTooltipStyle.top="".concat(Math.min(Math.max(0,minY,parseFloat(plcm.computedTooltipStyle.top)),maxY),"px");return plcm;}let instance;function setActive(action){instance=action;}function removeActive(action){if(instance===action){instance=null;return true;}return false;}function cancelActive(a){if(instance&&instance!==a){instance();}}function remove(){instance=null;}/**
	 * @typedef {object}
	 * @alias ComponentTooltip.settings
	 */const DEFAULT_SETTINGS={/**
	   * How long the tooltip is visible, in milliseconds
	   * @type {number=}
	   */duration:8000,/**
	   * Delay before the tooltip is rendered, in milliseconds
	   * @type {number=}
	   */delay:500,/**
	   * Callback function to filter incoming nodes to only a set of applicable nodes. Is called as a part of the `show` event.
	   *
	   * Should return an array of SceneNodes.
	   * @type {function=}
	   * @callback
	   * @param {SceneNode[]} nodes Array of SceneNodes
	   * @returns {SceneNode[]} An array of SceneNodes
	   * @example
	   * filter: (nodes) => nodes.filter((node) => node.data && typeof node.data.value !== 'undefined')
	   */filter:nodes=>nodes.filter(node=>node.data&&typeof node.data.value!=='undefined'),/**
	   * Callback function called for each node to extract data. Can return any type.
	   * @type {function=}
	   * @callback
	   * @param {object} ctx Callback context
	   * @param {SceneNode} ctx.node Node
	   * @returns {any} Return data
	   * @example
	   * (ctx) => ctx.node.data.value
	   */extract:ctx=>ctx.node.data.value,/**
	   * Callback function to generate content. Should return an array of Virtual DOM Elements.
	   * @type {function=}
	   * @callback
	   * @param {object} ctx Callback context
	   * @param {any[]} ctx.data An array of data generated from the `extract` function
	   * @param {object} ctx.h A function for creating Virtual DOM Elements. See API reference for preactjs `h` function
	   * @returns {object[]} An array of Virtual DOM Elements
	   * @example
	   * ({ h, data }) => data.map((datum) => h('div', {}, datum))
	   */content:_ref=>{let{h,data}=_ref;return data.map(datum=>h('div',{},datum));},/**
	   * Comparison function. If evaluted to true, the incoming nodes in the `show` event are ignored. If evaluated to false, any active tooltip is cleared and a new tooltip is queued.
	   *
	   * The function gets two parameters, the first is the currently active set of nodes, if any, and the second is the incoming set of nodes. By default the two set of nodes are considered equal if their data attributes are the same.
	   * @type {function=}
	   * @callback
	   * @param {SceneNode[]} prev Previous array of SceneNodes
	   * @param {SceneNode[]} curr Current array of SceneNodes
	   * @returns {boolean}
	   */isEqual:(prev,curr)=>prev.length&&prev.length===curr.length&&prev.every((p,i)=>curr[i]&&JSON.stringify(p.data)===JSON.stringify(curr[i].data)),/**
	   * @typedef {object=}
	   */placement:{/**
	     * Available types: [pointer | bounds | slice]
	     * @type {string=}
	     */type:'pointer',/**
	     * Docking position of the tooltip. Available positions: [left | right | top | bottom | auto]
	     * @type {string=}
	     */dock:'auto',/**
	     * Distance from the content area to the tooltip position, in px.
	     * @type {number=}
	     */offset:8,/**
	     * Specify the limiting area, where target is the component area unless the appendTo property is set, in which case it referes to the appendTo element. Viewport is the browser viewport.
	     *
	     * Available options are: [viewport | target]
	     * @type {number=}
	     */area:'viewport'},/**
	   * Set tooltip class.
	   * @type {object<string, boolean>=}
	   */tooltipClass:{},/**
	   * Set content class.
	   * @type {object<string, boolean>=}
	   */contentClass:{},/**
	   * Set arrow class.
	   * @type {object<string, boolean>=}
	   */arrowClass:{},/**
	   * Content direction [ltr | rtl]
	   * @type {string=}
	   */direction:'ltr',/**
	   * Explicitly set a target element. This allows the tooltip to attach itself outside the picasso container.
	   * @type {HTMLElement=}
	   */appendTo:undefined,/**
	   * Component lifecycle hook. Called before the tooltip is displayed.
	   * @type {function=}
	   * @callback
	   */beforeShow:undefined,/**
	   * Component lifecycle hook. Called after the tooltip have been displayed.
	   * @type {function=}
	   * @callback
	   */afterShow:undefined,/**
	   * Component lifecycle hook. Called before the tooltip is hidden.
	   * @type {function=}
	   * @callback
	   * @param {object} ctx Callback paramater
	   * @param {HTMLElement} ctx.element The element the tooltip is appended to
	   */beforeHide:undefined,/**
	   * Component lifecycle hook. Called when the toolip is hidden. By default this deletes the tooltip element.
	   * @type {function=}
	   * @callback
	   * @param {object} ctx Callback paramater
	   * @param {HTMLElement} ctx.element The element the tooltip is appended to
	   */onHide:undefined,/**
	   * Component lifecycle hook. Called after the tooltip is hidden.
	   * @type {function=}
	   * @callback
	   */afterHide:undefined};const DEFAULT_STYLE={tooltip:{},content:{backgroundColor:'$gray-25',color:'$font-color--inverted',fontFamily:'$font-family',fontSize:'$font-size',lineHeight:'$line-height',borderRadius:'4px',padding:'8px',opacity:0.9},arrow:{position:'absolute',width:'0px',height:'0px',borderStyle:'solid',color:'$gray-25',opacity:0.9},'arrow-bottom':{borderTopColor:'transparent',borderLeftColor:'transparent',borderRightColor:'transparent'},'arrow-top':{borderBottomColor:'transparent',borderLeftColor:'transparent',borderRightColor:'transparent'},'arrow-right':{borderTopColor:'transparent',borderLeftColor:'transparent',borderBottomColor:'transparent'},'arrow-left':{borderTopColor:'transparent',borderBottomColor:'transparent',borderRightColor:'transparent'}};function toPoint(event,_ref2){let{chart,state}=_ref2;let x=0;let y=0;if(event.center){x+=event.center.x;y+=event.center.y;}else {x+=event.clientX;y+=event.clientY;}// TODO Don't do getBoundingClientRect lookup here. It's performance heavy.
	const chartBounds=chart.element.getBoundingClientRect();const targetBounds=state.targetElement.getBoundingClientRect();const clientX=x;const clientY=y;const dx=chartBounds.left-targetBounds.left;const dy=chartBounds.top-targetBounds.top;const cx=x-chartBounds.left;const cy=y-chartBounds.top;x-=targetBounds.left;y-=targetBounds.top;return {x,// Target point relative to the target bounds
	y,dx,// Delta from target bounds to the chart bounds
	dy,cx,// Target point relative to the chart bounds
	cy,clientX,clientY,targetBounds,// Target bounding rect
	chartBounds// Chart bounding rect
	};}const component={require:['chart','renderer'],defaultSettings:{settings:DEFAULT_SETTINGS,style:DEFAULT_STYLE},renderer:'dom',on:{hide(){this.hide();},show(event){let opts=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};this.show(event,opts);},prevent(p){this.prevent(p);}},hide(){this.dispatcher.clear();this.state.activeNodes=[];this.state.pointer={};},show(event){let{nodes,duration,delay}=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};if(this.state.prevent||!this.state.targetElement){return;}// Set pointer here to always expose latest pointer to invokeRenderer
	this.state.pointer=toPoint(event,this);let fNodes;if(Array.isArray(nodes)){fNodes=this.props.filter(nodes);}else {fNodes=this.props.filter(this.chart.shapesAt({x:this.state.pointer.cx,y:this.state.pointer.cy}));}if(this.props.isEqual(this.state.activeNodes,fNodes)){return;}this.dispatcher.clear();this.state.activeNodes=fNodes;if(this.state.activeNodes.length){this.dispatcher.invoke(()=>this.invokeRenderer(this.state.activeNodes),duration,delay);}},prevent(p){this.state.prevent=!!p;},init(settings){this.state={activeNodes:[],pointer:{},targetElement:null,prevent:false};this.props=settings.settings;this.dispatcher=timeSpanDispatcher({defaultDuration:this.props.duration,defaultDelay:this.props.delay});const instanceId=this.dispatcher.clear;this.dispatcher.on('pending',()=>{// Cancel only if the active is another instance
	cancelActive(instanceId);setActive(instanceId);if(typeof this.props.beforeShow==='function'){this.props.beforeShow.call(undefined,{resources:{formatter:this.chart.formatter,scale:this.chart.scale}});}});this.dispatcher.on(['cancelled','fulfilled'],()=>{const listenerCtx={resources:{formatter:this.chart.formatter,scale:this.chart.scale}};if(typeof this.props.beforeHide==='function'){this.props.beforeHide.call(undefined,extend$1$1({element:this.state.tooltipElm},listenerCtx));}if(typeof this.props.onHide==='function'){this.props.onHide.call(undefined,extend$1$1({element:this.state.tooltipElm},listenerCtx));}else {this.renderer.clear([]);// Hide tooltip
	}if(typeof this.props.afterHide==='function'){this.props.afterHide.call(undefined,listenerCtx);}removeActive(instanceId);this.state.tooltipElm=undefined;});this.dispatcher.on('active',()=>{if(typeof this.props.afterShow==='function'){this.props.afterShow.call(undefined,{element:this.state.tooltipElm,resources:{formatter:this.chart.formatter,scale:this.chart.scale}});}});},created(){this.init(this.settings);},beforeUpdate(_ref3){let{settings}=_ref3;if(this.dispatcher){this.dispatcher.destroy();remove();}this.init(settings);},render(h){this.h=h;return [];// Nothing to render initially.
	},beforeDestroy(){this.dispatcher.destroy();remove();},appendTo(){if(this.props.appendTo){this.state.targetElement=typeof this.props.appendTo==='function'?this.props.appendTo({resources:{formatter:this.chart.formatter,scale:this.chart.scale}}):this.props.appendTo;const{width,height}=this.state.targetElement.getBoundingClientRect();this.renderer.destroy();this.renderer.size({width,height});this.renderer.appendTo(this.state.targetElement);}else {this.state.targetElement=this.renderer.element();}},mounted(){this.appendTo();},updated(){// Append here to, otherwise the picasso displayOrder logic screw things up
	this.appendTo();},invokeRenderer(nodes){const items=extractor(nodes,this);const pseudoElement=render$5(items,{},this);const pos=placement(pseudoElement.getBoundingClientRect(),this);this.state.tooltipElm=render$5(items,pos,this);}};/**
	 * @typedef {object} ComponentTooltip
	 * @extends ComponentSettings
	 * @property {'tooltip'} type component type
	 * @example
	 * picasso.chart({
	  settings: {
	    interactions: [{
	      type: 'native',
	      events: {
	        mousemove(e) {
	          const tooltip = this.chart.component('<tooltip-key>');
	          tooltip.emit('show', e);
	        },
	        mouseleave(e) {
	          const tooltip = this.chart.component('<tooltip-key>');
	          tooltip.emit('hide');
	        }
	      }
	    }],
	    components: [
	      {
	        key: '<tooltip-key>',
	        type: 'tooltip'
	      }
	    ]
	  },
	  ...
	});
	 */function addTooltip(picasso){picasso.component('tooltip',component);}const debugColliderDef={require:['renderer','chart'],defaultSettings:{settings:{target:'',selector:'*',fill:'rgba(0, 255, 0, 0.1)',stroke:'lime',opacity:1,useOuterRect:false}},on:{update(){this.draw();}},draw(){const shapes=this.chart.findShapes(this.props.selector).filter(s=>s.key===this.props.target);// Find all shapes
	const colliders=shapes.filter(s=>s.collider).map(s=>s.collider);colliders.forEach(c=>{c.fill=this.props.fill;c.stroke=this.props.stroke;c.opacity=this.props.opacity;c.collider={type:null};});this.renderer.render(colliders);},created(){this.props=this.settings.settings;},resize(_ref){let{outer,inner}=_ref;if(this.props.useOuterRect){return outer;}return inner;},render(){},mounted(){this.draw();},updated(){this.props=this.settings.settings;this.draw();}};// src/parse-path.ts
	var ARG_LENGTH={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0};var SEGMENT_PATTERN=/([astvzqmhlc])([^astvzqmhlc]*)/gi;var NUMBER=/-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/gi;function parseValues(args){const numbers=args.match(NUMBER);return numbers?numbers.map(Number):[];}function parsePath(path){const data=[];const p=String(path).trim();if(p[0]!=="M"&&p[0]!=="m"){return data;}p.replace(SEGMENT_PATTERN,(_,command,args)=>{const theArgs=parseValues(args);let type=command.toLowerCase();let theCommand=command;if(type==="m"&&theArgs.length>2){data.push([theCommand,...theArgs.splice(0,2)]);type="l";theCommand=theCommand==="m"?"l":"L";}if(theArgs.length<ARG_LENGTH[type]){return "";}data.push([theCommand,...theArgs.splice(0,ARG_LENGTH[type])]);while(theArgs.length>=ARG_LENGTH[type]&&theArgs.length&&ARG_LENGTH[type]){data.push([theCommand,...theArgs.splice(0,ARG_LENGTH[type])]);}return "";});return data;}const PI_X2=Math.PI*2;/**
	 * Implementation of F.6.5 https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
	 * @ignore
	 * @param {number} rx - Arc x-radius
	 * @param {number} ry - Arc y-radius
	 * @param {number} rotation - Arc rotation in degrees (0-360)
	 * @param {boolean} largeArcFlag
	 * @param {boolean} sweepFlag
	 * @param {number} endX - X-coordinate for end of arc
	 * @param {number} endY - Y-coordinate for end of arc
	 * @param {number} startX - X-coordinate for start of arc
	 * @param {number} startY - Y-coordinate for start of arc
	 * @returns {object}
	 */function arcToCenter(rx,ry,rotation,largeArcFlag,sweepFlag,endX,endY,startX,startY){let startAngle;let endAngle;let sweepAngle;let cx;let cy;let radiusRatio;const rad=toRadians(rotation%360);// F.6.5.1
	const cos=Math.cos(rad);const sin=Math.sin(rad);const hdx=(startX-endX)/2;const hdy=(startY-endY)/2;const x1d=cos*hdx+sin*hdy;const y1d=cos*hdy-sin*hdx;// F.6.6
	rx=Math.abs(rx);ry=Math.abs(ry);radiusRatio=x1d**2/rx**2+y1d**2/ry**2;if(radiusRatio>1){radiusRatio=Math.sqrt(radiusRatio);rx*=radiusRatio;ry*=radiusRatio;}// F.6.5.2
	const rxry=rx*ry;const rxy1d=rx*y1d;const ryx1d=ry*x1d;const den=rxy1d**2+ryx1d**2;const num=rxry**2-den;let frac=Math.sqrt(Math.max(num/den,0));if(largeArcFlag===sweepFlag){frac=-frac;}const cxd=frac*(rxy1d/ry);const cyd=frac*-(ryx1d/rx);// F.6.5.3
	const mx=(startX+endX)/2;const my=(startY+endY)/2;cx=cos*cxd-sin*cyd+mx;cy=sin*cxd+cos*cyd+my;// F.6.5.6 clockwise angle
	const ux=(x1d-cxd)/rx;const uy=(y1d-cyd)/ry;const vx=(-x1d-cxd)/rx;const vy=(-y1d-cyd)/ry;startAngle=Math.atan2(uy,ux);startAngle+=startAngle<0?PI_X2:0;endAngle=Math.atan2(vy,vx);endAngle+=endAngle<0?PI_X2:0;sweepAngle=endAngle-startAngle;if(!sweepFlag&&startAngle<endAngle){sweepAngle-=PI_X2;}else if(sweepFlag&&endAngle<startAngle){sweepAngle+=PI_X2;}sweepAngle%=PI_X2;return {startAngle,sweepAngle,cx,cy,rx,ry};}/**
	 * Measure the flatnass of a cubic bezier curve
	 * @ignore
	 * @param {Point} s - Start point
	 * @param {Point} cp1 - First control point
	 * @param {Point} cp2 - Second control point
	 * @param {Point} e - End point
	 */function flatness(s,cp1,cp2,e){const ux=Math.abs(s.x+cp2.x-(cp1.x+cp1.x));const uy=Math.abs(s.y+cp2.y-(cp1.y+cp1.y));const vx=Math.abs(cp1.x+e.x-(cp2.x+cp2.x));const vy=Math.abs(cp1.y+e.y-(cp2.y+cp2.y));return ux+uy+vx+vy;}function mid(p0,p1){return {x:(p0.x+p1.x)*0.5,y:(p0.y+p1.y)*0.5};}function interpolate(t,s,cp1,cp2,e){const td=1-t;const t0=td**3*s;const t1=3*td**2*t*cp1;const t2=3*td*t**2*cp2;const t3=t**3*e;return t0+t1+t2+t3;}/**
	 * Recursive subdivision of a curve using de Casteljau algorithm.
	 * Splits the curve into multiple line segments where each segments is choosen based on a level of flatness.
	 *
	 * At most it will be able to generate 2**maxNbrOfSplits + 1 = 257 points
	 * @ignore
	 * @param {Point} s - Start point
	 * @param {Point} cp1 - First control point
	 * @param {Point} cp2 - Second control point
	 * @param {Point} e - End point
	 * @param {array} points - Initial set of points
	 * @returns {point[]} Array of points
	 */function toPoints$1(s,cp1,cp2,e){let points=arguments.length>4&&arguments[4]!==undefined?arguments[4]:[];let maxNbrOfSplits=arguments.length>5&&arguments[5]!==undefined?arguments[5]:8;if(maxNbrOfSplits<1||flatness(s,cp1,cp2,e)<=10){if(points[points.length-1]!==s){points.push(s);}points.push(e);return points;}const t=0.5;const m0=mid(s,cp1);const m1=mid(cp1,cp2);const m2=mid(cp2,e);const b={// Split curve at point
	x:interpolate(t,s.x,cp1.x,cp2.x,e.x),y:interpolate(t,s.y,cp1.y,cp2.y,e.y)};const q0=mid(m0,m1);// New cp2 for left curve
	const q1=mid(m1,m2);// New cp1 for right curve
	toPoints$1(s,m0,q0,b,points,maxNbrOfSplits-1);// left curve
	toPoints$1(b,q1,m2,e,points,maxNbrOfSplits-1);// Right curve
	return points;}function toCubic(s,cp,e){const cp1x=s.x+2/3*(cp.x-s.x);const cp1y=s.y+2/3*(cp.y-s.y);const cp2x=e.x+2/3*(cp.x-e.x);const cp2y=e.y+2/3*(cp.y-e.y);const cp1={x:cp1x,y:cp1y};const cp2={x:cp2x,y:cp2y};return {cp1,cp2};}/**
	 * Recursive subdivision of a curve using de Casteljau algorithm.
	 * Splits the curve into multiple line segments where each segments is choosen based on a level of flatness.
	 * @ignore
	 * @param {Point} s - Start point
	 * @param {Point} cp - Control point
	 * @param {Point} e - End point
	 * @returns {Point[]} Array of points
	 */function toPoints(s,cp,e){const{cp1,cp2}=toCubic(s,cp,e);return toPoints$1(s,cp1,cp2,e);}const EPSILON$1$1=1e-12;function removeDuplicates$2(points){for(let i=0;i<points.length-1;i++){const p0=points[i];const p1=points[i+1];if(Math.abs(p0.x-p1.x)<EPSILON$1$1&&Math.abs(p0.y-p1.y)<EPSILON$1$1){points.splice(i,1);i--;}}}/**
	 * Transform an arc to a set of points a long the arc.
	 * Specifiction F.6 (https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes)
	 * @ignore
	 * @param {array} s - Segments
	 * @param {number} startX - X-coordinate for start of arc
	 * @param {number} startY - Y-coordinate for start of arc
	 */function arcToPoints(s,startX,startY){const points=[];const largeArcFlag=!!s[4];// F.6.3
	const sweepFlag=!!s[5];// F.6.3
	const rotation=s[3];let endX=s[6];let endY=s[7];let rx=s[1];let ry=s[2];let cx;let cy;let sweepAngle;let startAngle;if(s[0]==='a'){endX+=startX;endY+=startY;}// F.6.2
	if(startX===endY&&startY===endY){return points;}// Given no radius, threat as lineTo command
	if(!rx||!ry){points.push({x:endX,y:endY});return points;}({cx,cy,rx,ry,sweepAngle,startAngle}=arcToCenter(rx,ry,rotation,largeArcFlag,sweepFlag,endX,endY,startX,startY));// Approximation of perimeter
	const p=Math.abs(sweepAngle*Math.sqrt((rx**2+ry**2)/2));// Generate a point every 10th pixel. Scaling of the node should probably be included in this calculation
	const res=Math.ceil(p/10);const resAngle=sweepAngle/res;for(let k=1;k<=res;k++){const deltaAngle=resAngle*k;const radians=(startAngle+deltaAngle)%PI_X2;const cos=Math.cos(radians);const sin=Math.sin(radians);// F.6.3 https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
	points.push({x:cx+cos*rx+-sin*cos,y:cy+sin*ry+cos*sin});}// points.push({ x: cx, y: cy });
	return points;}/**
	 * Converts a SVG path data string into a set of points.
	 * @ignore
	 * @param {string} path
	 * @returns {Array<point[]>} Array of points
	 */function pathToPoints(path){const commands=parsePath(path);const segments=[];const points=[];let x=0;// Current point
	let y=0;let cpx=null;// Last control point on a cubic curve
	let cpy=null;let qcpx=null;// Last control point on a quad curve
	let qcpy=null;for(let i=0;i<commands.length;++i){const cmd=commands[i];const pathType=cmd[0];// Reset control point if command is not cubic
	if(pathType!=='S'&&pathType!=='s'&&pathType!=='C'&&pathType!=='c'){cpx=null;cpy=null;}if(pathType!=='T'&&pathType!=='t'&&pathType!=='Q'&&pathType!=='q'){qcpx=null;qcpy=null;}switch(pathType){case 'm':if(points.length){segments.push(points.splice(0));}// Fall through
	case 'l':// eslint-disable-line no-fallthrough
	x+=cmd[1];y+=cmd[2];points.push({x,y});break;case 'M':if(points.length){segments.push(points.splice(0));}// Fall through
	case 'L':// eslint-disable-line no-fallthrough
	x=cmd[1];y=cmd[2];points.push({x,y});break;case 'H':x=cmd[1];points.push({x,y});break;case 'h':x+=cmd[1];points.push({x,y});break;case 'V':y=cmd[1];points.push({x,y});break;case 'v':y+=cmd[1];points.push({x,y});break;case 'a':points.push(...arcToPoints(cmd,x,y));x+=cmd[6];y+=cmd[7];break;case 'A':points.push(...arcToPoints(cmd,x,y));x=cmd[6];y=cmd[7];break;case 'c':points.push(...toPoints$1({x,y},{x:cmd[1]+x,y:cmd[2]+y},{x:cmd[3]+x,y:cmd[4]+y},{x:cmd[5]+x,y:cmd[6]+y}));cpx=cmd[3]+x;// Last control point
	cpy=cmd[4]+y;x+=cmd[5];y+=cmd[6];break;case 'C':points.push(...toPoints$1({x,y},{x:cmd[1],y:cmd[2]},{x:cmd[3],y:cmd[4]},{x:cmd[5],y:cmd[6]}));cpx=cmd[3];// Last control point
	cpy=cmd[4];x=cmd[5];y=cmd[6];break;case 's':if(cpx===null||cpx===null){cpx=x;cpy=y;}points.push(...toPoints$1({x,y},{x:2*x-cpx,y:2*y-cpy},{x:cmd[1]+x,y:cmd[2]+y},{x:cmd[3]+x,y:cmd[4]+y}));cpx=cmd[1]+x;// last control point
	cpy=cmd[2]+y;x+=cmd[3];y+=cmd[4];break;case 'S':if(cpx===null||cpx===null){cpx=x;cpy=y;}points.push(...toPoints$1({x,y},{x:2*x-cpx,y:2*y-cpy},{x:cmd[1],y:cmd[2]},{x:cmd[3],y:cmd[4]}));cpx=cmd[1];// last control point
	cpy=cmd[2];x=cmd[3];y=cmd[4];break;case 'Q':points.push(...toPoints({x,y},{x:cmd[1],y:cmd[2]},{x:cmd[3],y:cmd[4]}));qcpx=cmd[1];// last control point
	qcpy=cmd[2];x=cmd[3];y=cmd[4];break;case 'q':points.push(...toPoints({x,y},{x:cmd[1]+x,y:cmd[2]+y},{x:cmd[3]+x,y:cmd[4]+y}));qcpx=cmd[1]+x;// last control point
	qcpy=cmd[2]+y;x+=cmd[3];y+=cmd[4];break;case 'T':if(qcpx===null||qcpx===null){qcpx=x;qcpy=y;}qcpx=2*x-qcpx;// last control point
	qcpy=2*y-qcpy;points.push(...toPoints({x,y},{x:qcpx,y:qcpy},{x:cmd[1],y:cmd[2]}));x=cmd[1];y=cmd[2];break;case 't':if(qcpx===null||qcpx===null){qcpx=x;qcpy=y;}qcpx=2*x-qcpx;// last control point
	qcpy=2*y-qcpy;points.push(...toPoints({x,y},{x:qcpx,y:qcpy},{x:cmd[1]+x,y:cmd[2]+y}));x+=cmd[1];y+=cmd[2];break;case 'z':case 'Z':if(points.length){points.push({x:points[0].x,y:points[0].y});}break;// Do nothing
	}}removeDuplicates$2(points);segments.push(points.splice(0));return segments;}const debugPathToPointsDef={require:['renderer','chart'],defaultSettings:{settings:{target:'',fill:'transparent',stroke:'lime',opacity:1,radius:2,useOuterRect:false}},on:{update(){this.draw();}},draw(){const shapes=this.chart.findShapes('path').filter(s=>s.key===this.props.target);// Find all shapes
	const circles=[];shapes.forEach(s=>{pathToPoints(s.attrs.d).forEach(segment=>{segment.forEach(p=>{circles.push({type:'circle',cx:p.x,cy:p.y,r:this.props.radius,fill:this.props.fill,stroke:this.props.stroke,opacity:this.props.opacity,collider:{type:null}});});});});this.renderer.render(circles);},created(){this.props=this.settings.settings;},resize(_ref){let{outer,inner}=_ref;if(this.props.useOuterRect){return outer;}return inner;},render(){},mounted(){this.draw();},updated(){this.props=this.settings.settings;this.draw();}};function debugCollider(picasso){picasso.component('debug-collider',debugColliderDef);}function debugPathToPoints(picasso){picasso.component('debug-path-to-points',debugPathToPointsDef);}var components=[box,pointMarker$1,pie,gridLine$1,refLine$1,axis$1,container,text$1,scrollbar$1,rangeBrush$1,rangeBrush,lassoBrush,labels$1,categoricalLegend,sequentialLegend$1,line,areaBrush,addTooltip,debugCollider,debugPathToPoints];let Node$1 = class Node{/**
	   * @private
	   */constructor(type){this._parent=null;this._children=[];this._ancestors=null;this.type=type;this.data=null;}/**
	   * Detaches this node from its parent, if such exists.
	   * @returns {Node}
	   */detach(){if(this._parent){this._parent.removeChild(this);}return this;}/**
	   * Parent of this node.
	   * @readonly
	   * @type {Node}
	   */get parent(){return this._parent;}/**
	   * Checks whether this node is a branch.
	   *
	   * True if this node has children, false otherwise.
	   * @readonly
	   * @type {Boolean}
	   */get isBranch(){return this._children&&this._children.length;}/**
	   * Children of this node.
	   * @readonly
	   * @type {Node[]}
	   */get children(){return this._children;}/**
	   * Ancestors of this node, including parent.
	   * @readonly
	   * @type {Node[]}
	   */get ancestors(){if(!this._ancestors){this._ancestors=[];if(this.parent){this._ancestors.push(this.parent,...this.parent.ancestors);}}return this._ancestors;}/**
	   * Descendants of this node.
	   * @readonly
	   * @type {Node[]}
	   */get descendants(){let r=[];const len=this.children.length;let i;let c;for(i=0,len;i<len;i++){c=this.children[i];r.push(c);if(c.children.length){r=[...r,...c.descendants];}}return r;}/**
	   *
	   * @returns {Boolean}
	   */equals(n){const children=this.children;const nChildren=n.children;if(children.length!==nChildren.length){return false;}// Requires deterministic child order
	for(let i=0;i<children.length;i++){if(!children[i].equals(nChildren[i])){return false;}}return true;}toJSON(){return {type:this.type,children:this.children.map(ch=>ch.toJSON())};}};/**
	 * Construct a new GeoRect instance
	 * @private
	 */class GeoRect{constructor(){let{x=0,y=0,width=0,height=0,minWidth=0,minHeight=0}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.set({x,y,width,height,minWidth,minHeight});}set(){let{x=0,y=0,width=0,height=0,minWidth=0,minHeight=0}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.type='rect';if(width>=0){this.x=x;this.width=Math.max(width,minWidth);}else {this.x=x+Math.min(width,-minWidth);this.width=-Math.min(width,-minWidth);}if(height>=0){this.y=y;this.height=Math.max(height,minHeight);}else {this.y=y+Math.min(height,-minHeight);this.height=-Math.min(height,-minHeight);}}/**
	   * @param {Point} p
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(p){return testRectPoint(this,p);}/**
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){const line=pointsToLine(points);return testRectLine(this,line);}/**
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){const rect=pointsToRect(points);return testRectRect(this,rect);}/**
	   * @param {Circle} c
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(c){return testCircleRect(c,this);}/**
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){return testPolygonRect(polygon,this);}/**
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){return testGeoPolygonRect(geopolygon,this);}/**
	   * Get the points
	   * @returns {Point[]}
	   */points(){return [{x:this.x,y:this.y},{x:this.x+this.width,y:this.y},{x:this.x+this.width,y:this.y+this.height},{x:this.x,y:this.y+this.height}];}}function create$k(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return new GeoRect(...args);}/**
	 * Construct a new GeoCircle instance
	 * @private
	 */class GeoCircle{constructor(){let{cx=0,cy=0,r=0,minRadius=0}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.set({cx,cy,r,minRadius});}set(){let{cx=0,cy=0,r=0,minRadius=0}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.type='circle';this.cx=cx;this.cy=cy;this.r=Math.max(r,minRadius);this.vector={x:this.cx,y:this.cy};}/**
	   * @param {Point} p
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(p){return testCirclePoint(this,p);}/**
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){const line=pointsToLine(points);return testCircleLine(this,line);}/**
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){const rect=pointsToRect(points);return testCircleRect(this,rect);}/**
	   * @param {Circle} c
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(c){return testCircleCircle(this,c);}/**
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){return testCirclePolygon(this,polygon);}/**
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){return testCircleGeoPolygon(this,geopolygon);}/**
	   * Get the points
	   * @returns {Point[]}
	   */points(){return [{x:this.cx,y:this.cy}];}}function create$j(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return new GeoCircle(...args);}/**
	 * Construct a new GeoLine instance
	 * @private
	 */class GeoLine{constructor(){let{x1=0,y1=0,x2=0,y2=0,tolerance=0}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.set({x1,y1,x2,y2,tolerance});}set(){let{x1=0,y1=0,x2=0,y2=0,tolerance=0}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.type='line';this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;this.tolerance=Math.max(0,Math.round(tolerance));this.vectors=this.points();this.zeroSize=x1===x2&&y1===y2;}/**
	   * @param {Point} p
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(p){if(this.tolerance>0){const c={cx:p.x,cy:p.y,r:this.tolerance};return testCircleLine(c,this);}return testLinePoint(this,p);}/**
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){const line=pointsToLine(points);return testLineLine(this,line);}/**
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){const rect=pointsToRect(points);return testRectLine(rect,this);}/**
	   * @param {Circle} c
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(c){return testCircleLine(c,this);}/**
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){return testPolygonLine(polygon,this);}/**
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){return testGeoPolygonLine(geopolygon,this);}/**
	   * Get the points
	   * @returns {Point[]}
	   */points(){return [{x:this.x1,y:this.y1},{x:this.x2,y:this.y2}];}}function create$i(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return new GeoLine(...args);}function close$1(vertices){const first=vertices[0];const last=vertices[vertices.length-1];if(first.x!==last.x||first.y!==last.y){vertices.push(first);}}function removeDuplicates$1(vertices){for(let i=0;i<vertices.length-1;i++){const v0=vertices[i];const v1=vertices[i+1];if(v0.x===v1.x&&v0.y===v1.y){vertices.splice(i,1);i--;}}}/**
	 * Construct a new Polygon instance
	 * Added ignore flag as the name collide with definition in index.js
	 * @private
	 */class Polygon{constructor(){let{vertices=[]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.set({vertices});}/**
	   * Set the vertices.
	   * If vertices doesn't close the polygon, a closing vertice is appended.
	   * @ignore
	   * @param {object} input An object with a vertices property
	   * @param {Point[]} [input.vertices=[]] Vertices are represented as an array of points.
	   */set(){let{vertices=[]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.type='polygon';this.vertices=vertices.slice();this.edges=[];removeDuplicates$1(this.vertices);if(this.vertices.length<=2){return;}close$1(this.vertices);this.xMin=NaN;this.yMin=NaN;this.xMax=NaN;this.yMax=NaN;for(let i=0;i<this.vertices.length;i++){if(i<this.vertices.length-1){this.edges.push([this.vertices[i],this.vertices[i+1]]);}this.xMin=isNaN(this.xMin)?this.vertices[i].x:Math.min(this.xMin,this.vertices[i].x);this.xMax=isNaN(this.xMax)?this.vertices[i].x:Math.max(this.xMax,this.vertices[i].x);this.yMin=isNaN(this.yMin)?this.vertices[i].y:Math.min(this.yMin,this.vertices[i].y);this.yMax=isNaN(this.yMax)?this.vertices[i].y:Math.max(this.yMax,this.vertices[i].y);}this._bounds=null;this._boundingRect=null;}/**
	   * Check if a point is inside the area of the polygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @ignore
	   * @param {Point} point
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(point){return testPolygonPoint(this,point);}/**
	   * Check if circle is inside the area of the polygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @ignore
	   * @param {Circle} circle
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(circle){return testCirclePolygon(circle,this);}/**
	   * @ignore
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){return testPolygonLine(this,pointsToLine(points));}/**
	   * @ignore
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){return testPolygonRect(this,pointsToRect(points));}/**
	   * Check if polygon intersects another polygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @ignore
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){return testPolygonPolygon(this,polygon);}/**
	   * Check if polygon intersects a geopolygon.
	   * @ignore
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){return testGeoPolygonPolygon(geopolygon,this);}/**
	   * Get the points
	   * @ignore
	   * @returns {Point[]}
	   */points(){return this.vertices;}/**
	   * Get the bounds of the polygon, as an array of points
	   * @ignore
	   * @returns {Point[]}
	   */bounds(){if(!this._bounds){this._bounds=[{x:this.xMin,y:this.yMin},{x:this.xMax,y:this.yMin},{x:this.xMax,y:this.yMax},{x:this.xMin,y:this.yMax}];}return this._bounds;}/**
	   * Get the bounding rect of the polygon
	   * @ignore
	   * @returns {Rect}
	   */boundingRect(){if(!this._boundingRect){this._boundingRect={x:this.xMin,y:this.yMin,width:this.xMax-this.xMin,height:this.yMax-this.yMin};}return this._boundingRect;}}function create$h(){for(var _len=arguments.length,a=new Array(_len),_key=0;_key<_len;_key++){a[_key]=arguments[_key];}return new Polygon(...a);}function close(vertices){const first=vertices[0];const last=vertices[vertices.length-1];if(first.x!==last.x||first.y!==last.y){vertices.push(first);}}function removeDuplicates(vertices){for(let i=0;i<vertices.length-1;i++){const v0=vertices[i];const v1=vertices[i+1];if(v0.x===v1.x&&v0.y===v1.y){vertices.splice(i,1);i--;}}}/**
	 * A geo-polygon is a polygon which is similar to a polygon in GeoJson. A typical geopolygon is an array of polygons where the first polygon is an outer polygon and the rest are inner polygons
	 * @private
	 */class GeoPolygon{constructor(){let{vertices=[[]]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.set({vertices});}/**
	   * Set the vertices.
	   * If vertices doesn't close the polygon, a closing vertice is appended.
	   * @param {object} input An object with a vertices property
	   * @param {Array} [input.vertices=[]] Vertices are represented as an array of arrays of points.
	   */set(){let{vertices=[]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.type='geopolygon';this.vertices=vertices.slice();this.numPolygons=this.vertices.length;this.polygons=[];this.xMin=NaN;this.yMin=NaN;this.xMax=NaN;this.yMax=NaN;for(let i=0;i<this.numPolygons;i++){removeDuplicates(this.vertices[i]);if(this.vertices[i].length>2){close(this.vertices[i]);}this.polygons[i]=create$h({vertices:this.vertices[i]});this.xMin=isNaN(this.xMin)?this.polygons[i].xMin:Math.min(this.xMin,this.polygons[i].xMin);this.xMax=isNaN(this.xMax)?this.polygons[i].xMax:Math.max(this.xMax,this.polygons[i].xMax);this.yMin=isNaN(this.yMin)?this.polygons[i].yMin:Math.min(this.yMin,this.polygons[i].yMin);this.yMax=isNaN(this.yMax)?this.polygons[i].yMax:Math.max(this.yMax,this.polygons[i].yMax);}this._bounds=null;this._boundingRect=null;}/**
	   * Check if a point is inside the area of the geopolygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @param {Point} point
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(point){return testGeoPolygonPoint(this,point);}/**
	   * Check if circle is inside the area of the polygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @param {Circle} circle
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(circle){return testCircleGeoPolygon(circle,this);}/**
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){return testGeoPolygonLine(this,pointsToLine(points));}/**
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){return testGeoPolygonRect(this,pointsToRect(points));}/**
	   * Check if geopolygon intersects another polygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){return testGeoPolygonPolygon(this,polygon);}/**
	   * Check if geopolygon intersects another geopolygon.
	   * Supports convex, concave and self-intersecting polygons (filled area).
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){return testGeoPolygonGeoPolygon(this,geopolygon);}/**
	   * Get the points
	   * @returns {Point[]}
	   */points(){return this.vertices;}/**
	   * Get the bounds of the polygon, as an array of points
	   * @ignore
	   * @returns {Point[]}
	   */bounds(){if(!this._bounds){this._bounds=[{x:this.xMin,y:this.yMin},{x:this.xMax,y:this.yMin},{x:this.xMax,y:this.yMax},{x:this.xMin,y:this.yMax}];}return this._bounds;}/**
	   * Get the bounding rect of the polygon
	   * @ignore
	   * @returns {Rect}
	   */boundingRect(){if(!this._boundingRect){this._boundingRect={x:this.xMin,y:this.yMin,width:this.xMax-this.xMin,height:this.yMax-this.yMin};}return this._boundingRect;}}function create$g(){for(var _len=arguments.length,a=new Array(_len),_key=0;_key<_len;_key++){a[_key]=arguments[_key];}return new GeoPolygon(...a);}function pointsAreNotEqual(p0,p1){return p0.x!==p1.x||p0.y!==p1.y;}/**
	 * Construct a new GeoPolyline instance
	 * @private
	 */class GeoPolyline{constructor(){let{points=[]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.set({points});}set(){let{points=[]}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.type='polyline';this.segments=[];this._points=points.slice();if(this._points.length>1){for(let i=0,len=this._points.length-1;i<len;i++){if(pointsAreNotEqual(this._points[i],this._points[i+1])){this.segments.push({x1:this._points[i].x,y1:this._points[i].y,x2:this._points[i+1].x,y2:this._points[i+1].y});}}}}/**
	   * @param {Point} point
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(point){return this.segments.some(line=>testLinePoint(line,point));}/**
	   * @param {Circle} circle
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(circle){return this.segments.some(line=>testCircleLine(circle,line));}/**
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){const testLine=pointsToLine(points);return this.segments.some(line=>testLineLine(line,testLine));}/**
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){const rect=pointsToRect(points);return this.segments.some(line=>testRectLine(rect,line));}/**
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){// This is a unoptimized solution and should be replaced by a more efficient algorithm.
	return this.segments.some(line=>testPolygonLine(polygon,line));}/**
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){// This is a unoptimized solution and should be replaced by a more efficient algorithm.
	return this.segments.some(line=>testGeoPolygonLine(geopolygon,line));}/**
	   * Get the points
	   * @returns {Point[]}
	   */points(){return this._points;}}function create$f(){for(var _len=arguments.length,a=new Array(_len),_key=0;_key<_len;_key++){a[_key]=arguments[_key];}return new GeoPolyline(...a);}const reg$2=registryFactory();reg$2.add('rect',create$k);reg$2.add('circle',create$j);reg$2.add('line',create$i);reg$2.add('polygon',create$h);reg$2.add('geopolygon',create$g);reg$2.add('polyline',create$f);/* eslint-disable import/prefer-default-export */function create$e(type,input){return reg$2.get(type)(input);}/* eslint-enable import/prefer-default-export *//**
	 * @typedef {object} Rect
	 * @property {number} x - X-coordinate
	 * @property {number} y - Y-coordinate
	 * @property {number} width - Width
	 * @property {number} height - Height
	 *//**
	 * @typedef {object} Line
	 * @property {number} x1 - Start x-coordinate
	 * @property {number} y1 - Start y-coordinate
	 * @property {number} x2 - End x-coordinate
	 * @property {number} y2 - End y-coordinate
	 *//**
	 * @typedef {object} Point
	 * @property {number} x - X-coordinate
	 * @property {number} y - Y-coordinate
	 *//**
	 * @typedef {object} Circle
	 * @property {number} cx - Center x-coordinate
	 * @property {number} cy - Center y-coordinate
	 * @property {number} r - Circle radius
	 *//**
	 * @typedef {object} Polygon
	 * @property {Array<Point>} points - Array of connected points
	 *//**
	 * @typedef {object} Geopolygon
	 * @property {Array<Polygon>} polygons - Array of polygons
	 *//**
	 * @typedef {object} Polyline
	 * @property {Array<Point>} points - Array of connected points
	 *//**
	 * @typedef {object} Path
	 * @property {string} d - Path definition
	 *//**
	 * Construct a new GeometryCollection instance
	 * @private
	 */class GeometryCollection{constructor(){let collection=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];this.set(collection);}set(){let collection=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];this.geometries=[];collection.forEach(geo=>{const geoInstance=create$e(geo.type,geo);if(geoInstance){this.geometries.push(geoInstance);}});}/**
	   * @param {Point} p
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */containsPoint(p){return this.geometries.some(geo=>geo.containsPoint(p));}/**
	   * @param {Point[]} points - Line start and end point as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsLine(points){return this.geometries.some(geo=>geo.intersectsLine(points));}/**
	   * @param {Point[]} points - Rect vertices as an array of points
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsRect(points){return this.geometries.some(geo=>geo.intersectsRect(points));}/**
	   * @param {Circle} c
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsCircle(c){return this.geometries.some(geo=>geo.intersectsCircle(c));}/**
	   * @param {Polygon} polygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsPolygon(polygon){return this.geometries.some(geo=>geo.intersectsPolygon(polygon));}/**
	   * @param {Geopolygon} geopolygon
	   * @returns {boolean} True if there is an intersection, false otherwise
	   */intersectsGeoPolygon(geopolygon){return this.geometries.some(geo=>geo.intersectsGeoPolygon(geopolygon));}}function create$d(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key];}return new GeometryCollection(...args);}class Matrix{/**
	   * Creates a matrix with identity values.
	   * @private
	   */constructor(){this._elements=[[1,0,0],[0,1,0],[0,0,1]];this._stack=[];}/**
	   * Creates a new matrix with a copy of the current values.
	   */clone(){const mt=new Matrix();return mt.multiply(this);}/**
	   * Sets the matrix values
	   * @param {Number[][]} arr A 3x3 array.
	   */set(arr){this._elements=arr;return this;}/**
	   * Saves the current matrix values to a stack.
	   */save(){this._stack.push(this.elements);return this;}/**
	   * Sets the current matrix values to the last ones saved on to the stack.
	   */restore(){if(this._stack.length){this._elements=this._stack.pop();// TODO - use a copy instead
	}return this;}/**
	   * Adds a scalar value to each element in the matrix.
	   * @param {Number} value
	   */add(value){// assume scalar
	let i,j;for(i=0;i<this._elements.length;i++){for(j=0;j<this._elements[i].length;j++){this._elements[i][j]+=value;}}return this;}/**
	   * Translates the current matrix along the x and y axis.
	   * @param {Number} x
	   * @param {Number} y
	   */translate(x,y){this.multiply([[1,0,x],[0,1,y],[0,0,1]]);return this;}/**
	   * Rotates the current matrix.
	   * @param {Number} radianAngle Angle in radians.
	   */rotate(radianAngle){let cos=Math.cos(-radianAngle),sin=Math.sin(-radianAngle);this.multiply([[cos,sin,0],[-sin,cos,0],[0,0,1]]);return this;}/**
	   *
	   * If value is a number; multiplies each element in the matrix by the given value.
	   * If value is a matrix; multiplies the two matrices.
	   * @param {Number|Array|Matrix} value
	   */multiply(value){let i,j,m,k;if(value instanceof Matrix){value=value._elements;}if(Array.isArray(value)){// matrix multiplication
	m=[[0,0,0],[0,0,0],[0,0,0]];for(i=0;i<this._elements.length;i++){// row
	for(j=0;j<this._elements[i].length;j++){// column
	for(k=0;k<3;k++){// row
	m[i][j]+=this._elements[i][k]*value[k][j];}}}this._elements=m;}else {// scalar multiplication
	for(i=0;i<this._elements.length;i++){for(j=0;j<this._elements[i].length;j++){this._elements[i][j]*=value;}}}return this;}/**
	   * Scales the matrix along x and y axis.
	   * @param {Number} x The value to scale the matrix with along the x direction
	   * @param {Number} [y=x] The value to scale the matrix with along the y direction.
	   */scale(x){let y=arguments.length>1&&arguments[1]!==undefined?arguments[1]:x;// if ( arguments.length < 2 || typeof y === "undefined" ) {
	//  y = x;
	// }
	this.multiply([[x,0,0],[0,y,0],[0,0,1]]);return this;}/**
	   * Multiples the matrix with the supplied transformation values
	   * @param {Number} a Horizontal scaling
	   * @param {Number} b Horizontal skewing
	   * @param {Number} c Vertical skewing
	   * @param {Number} d Vertical scaling
	   * @param {Number} e Horizontal moving
	   * @param {Number} f Vertical scaling
	   */transform(a,b,c,d,e,f){this.multiply([[a,c,e],[b,d,f],[0,0,1]]);return this;}/**
	   * Gets the value of the determinant.
	   * @return {Number}
	   */determinant(){let a=this._elements[0][0],b=this._elements[0][1],c=this._elements[0][2],d=this._elements[1][0],e=this._elements[1][1],f=this._elements[1][2],g=this._elements[2][0],h=this._elements[2][1],i=this._elements[2][2],p=0;p=a*e*i+b*f*g+c*d*h-c*e*g-b*d*i-a*f*h;return p;}/**
	   * Inverts the matrix.
	   */invert(){let dt=this.determinant(),a=this._elements[0][0],b=this._elements[0][1],c=this._elements[0][2],d=this._elements[1][0],e=this._elements[1][1],f=this._elements[1][2],g=this._elements[2][0],h=this._elements[2][1],k=this._elements[2][2];this._elements=[[e*k-f*h,c*h-b*k,b*f-c*e],[f*g-d*k,a*k-c*g,c*d-a*f],[d*h-e*g,g*b-a*h,a*e-b*d]];this.multiply(1/dt);// TODO - handle when dt === 0 ?
	return this;}/**
	   * Transposes the elements of the matrix.
	   */transpose(){const m=Object.create(this._elements);// ?
	this._elements=[[m[0][0],m[1][0],m[2][0]],[m[0][1],m[1][1],m[2][1]],[m[0][2],m[1][2],m[2][2]]];return this;}/**
	   * Resets the inner elements of the matrix to identity values.
	   */identity(){this._elements=[[1,0,0],[0,1,0],[0,0,1]];return this;}toString(){return "".concat(this._elements.map(r=>r.join('\t')).join('\n'));}isIdentity(){const m=this._elements;return m[0][0]===1&&m[0][1]===0&&m[0][2]===0&&m[1][0]===0&&m[1][1]===1&&m[1][2]===0&&m[2][0]===0&&m[2][1]===0&&m[2][2]===1;}/**
	   * Transforms the given point by this matrix and returns a new point
	   */transformPoint(p){let vec=[p.x,p.y,1],i,j,e=this._elements,m=[0,0,0];for(i=0;i<this._elements.length;i++){// row
	for(j=0;j<this._elements[i].length;j++){// column
	m[i]+=vec[j]*e[i][j];}}return {x:m[0],y:m[1]};}/**
	   * Transforms the given points by this matrix and returns the new points
	   */transformPoints(array){let vec,i,j,k,m,e=this._elements,ret=[];for(k=0;k<array.length;k++){vec=[array[k].x,array[k].y,1];m=[0,0,0];for(i=0;i<this._elements.length;i++){// row
	for(j=0;j<this._elements[i].length;j++){// column
	m[i]+=vec[j]*e[i][j];}}ret.push({x:m[0],y:m[1]});}return ret;}get elements(){const m=this._elements;return [[m[0][0],m[0][1],m[0][2]],[m[1][0],m[1][1],m[1][2]],[m[2][0],m[2][1],m[2][2]]];}}const transformRegEx=/(translate|scale|rotate|matrix)\(([0-9,.eE+-\s]+)(?:,|\s?)+\)/g;function parseTransform(transform){let m,commands=[];/* eslint-disable no-cond-assign */while((m=transformRegEx.exec(transform))!==null){const argsStr=m[2].trim();const args=argsStr.indexOf(',')===-1?argsStr.split(' '):argsStr.split(',');commands.push({cmd:m[1],args:args.filter(a=>a.trim().length>0).map(a=>Number(a))});}/* eslint-enable no-cond-assign */return commands;}function resolveRotateCmd(matrix,transform){const radians=transform.args[0]*(Math.PI/180);if(transform.args.length>2){const x=transform.args[1];const y=transform.args[2];matrix.translate(x,y);matrix.rotate(radians);matrix.translate(-x,-y);}else if(transform.args.length===1){matrix.rotate(radians);}}function resolveScaleCmd(matrix,transform){const x=transform.args[0];const y=isNaN(transform.args[1])?transform.args[0]:transform.args[1];matrix.scale(x,y);}function resolveTranslateCmd(matrix,transform){const x=transform.args[0];const y=isNaN(transform.args[1])?0:transform.args[1];matrix.translate(x,y);}function resolveMatrixCmd(matrix,transform){if(transform.args.length>=6){matrix.transform(...transform.args);}}function resolveTransform(t,matrix){const transforms=parseTransform(t);let transform;for(let i=0,len=transforms.length;i<len;i++){transform=transforms[i];if(transform.cmd==='rotate'){resolveRotateCmd(matrix,transform);}else if(transform.cmd==='scale'){resolveScaleCmd(matrix,transform);}else if(transform.cmd==='matrix'){resolveMatrixCmd(matrix,transform);}else if(transform.cmd==='translate'){resolveTranslateCmd(matrix,transform);}}}/* eslint-disable no-useless-escape */const SELECTOR_MAPS={type:/^\w[\w-]+/,attr:/^\[\w(?:[\w\._-]+)?(?:[!]?=['\"][\w\s*#_-]*['\"])?\]/,universal:/^(\*)/,tag:/^\.(\w+)/};const FILTERS={type:(c,objects)=>// eslint-disable-line arrow-body-style
	objects.filter(o=>{const type=o.type;if(type){return type.toLowerCase()===c.toLowerCase();}return false;}),attr:(attr,operator,value,objects)=>// eslint-disable-line arrow-body-style
	objects.filter(o=>{const v=o.attrs[attr];if(!operator){// TODO handle undefined differently for != operator? As display object may very well have a default rendering color
	return typeof v!=='undefined';}if(typeof v==='undefined'){return false;}switch(operator){case '=':return value===String(v);case '!=':return value!==String(v);default:return false;}}),universal:objects=>objects,tag:(selector,objects)=>// eslint-disable-line arrow-body-style
	objects.filter(o=>{const tag=o.tag;if(tag){return tag.trim().split(/\s+/).indexOf(selector.replace('.',''))!==-1;}return false;})};/**
	 * Filters out objects of given type and value
	 * @ignore
	 * @example
	 * filter(
	 *   {type:'type', value:'Circle'},
	 *   [new Circle(), new Rectangle()]
	 * )
	 * // [Circle]
	 * @param {Object} token
	 * @param {Array} objects
	 * @returns {Object[]} Objects that fulfill the type and value
	 */function filter(token,objects){if(!objects||!objects.length||!token||typeof FILTERS[token.type]!=='function'){return [];}switch(token.type){case 'type':return FILTERS[token.type](token.value,objects);case 'attr':return FILTERS[token.type](token.attribute,token.operator,token.attributeValue,objects);case 'universal':return FILTERS[token.type](objects);case 'tag':return FILTERS[token.type](token.value,objects);default:return [];}}/**
	 * Tokenizes a string into supported selectors
	 * @ignore
	 *
	 * @example
	 * tokenize("Circle[color='red']")
	 *
	 * @param {String} s
	 */function tokenize(s){const groups=[];let sub;let info;let match;let validSelector;s.split(/\s*,\s*/).forEach(group=>{group=group.trim();sub=[];const selectorMapsIterator=key=>{match=group.match(SELECTOR_MAPS[key]);if(match){validSelector=true;group=group.slice(match[0].length);info={type:key,value:match[0]};if(key==='attr'){// extract parts of attribute from e.g. [color='red'] => (color, =, red)
	match=match[0].match(/\[(\w[\w\._-]+)?(?:([!]?=)['\"]([\w\s#_-]*)['\"])?\]/);info.attribute=match[1];info.operator=match[2];info.attributeValue=match[3];}sub.push(info);}};while(group){validSelector=false;match=group.match(/^\s*([>+~]|\s)\s*/);if(match){validSelector=true;sub.push({type:' ',value:match[0]});group=group.slice(match[0].length);}Object.keys(SELECTOR_MAPS).forEach(selectorMapsIterator);if(sub&&sub.length&&groups.indexOf(sub)<0){groups.push(sub);}if(!validSelector){break;}}});return groups;}function find(s,object){const result=[];const groupResults=[];let groups;let descendants;if(object.isBranch){groups=tokenize(s);descendants=object.descendants;let tokens;for(let gi=0,glen=groups.length;gi<glen;gi++){tokens=groups[gi];const levels=[];let filtered=descendants.slice();let hasRemainder=false;tokens.reverse().forEach(token=>{if(token.type===' '){levels.push(filtered);filtered=descendants.slice();hasRemainder=false;return;}filtered=filter(token,filtered);hasRemainder=true;});if(hasRemainder){levels.push(filtered);}const selected=levels[0].filter(node=>{let ancestor=node.parent;let idx;for(let i=1;i<levels.length;i++){idx=levels[i].indexOf(ancestor);while(ancestor&&idx<0){ancestor=ancestor.parent;idx=levels[i].indexOf(ancestor);}if(idx<0){return false;}}return true;});groupResults.push(selected);}for(let i=0,len=groupResults.length;i<len;i++){for(let ni=0,nlen=groupResults[i].length;ni<nlen;ni++){if(result.indexOf(groupResults[i][ni])<0){result.push(groupResults[i][ni]);}}}}return result||[];}var nodeSelector={find};function appendDpi(points,dpi){for(let i=0,len=points.length;i<len;i++){points[i].x/=dpi;points[i].y/=dpi;}}function geometryToDef(geometry,dpi,mvm){const type=geometry.type;let points=geometry.points();if(mvm){if(points.every(item=>Array.isArray(item))){points=points.map(item=>mvm.transformPoints(item));}else {points=mvm.transformPoints(points);}}appendDpi(points,dpi);let def=null;if(type==='rect'||type==='bounds'){def=pointsToRect(points);def.type=type;}else if(type==='circle'){def=pointsToCircle(points,geometry.r);def.type=type;}else if(type==='line'){def=pointsToLine(points);def.type=type;}else if(type==='polygon'||type==='polyline'){const path=pointsToPath(points,type==='polygon');def={type:'path',d:path};}else if(type==='geopolygon'){let path='';for(let i=0;i<points.length;i++){path+=pointsToPath(points[i],true);}def={type:'path',d:path};}return def;}/**
	 * @ignore
	 * @returns {object} Returns a node definition of the collider
	 */function colliderToShape(node,dpi){if(node.collider){const mvm=node.modelViewMatrix;const isCollection=node.colliderType==='collection';if(isCollection){const children=node.collider.geometries.map(geometry=>geometryToDef(geometry,dpi,mvm));return {type:'container',children};}return geometryToDef(node.collider,dpi,mvm);}return null;}/**
	 * Read-only object representing a node on the scene.
	 */class SceneNode{constructor(node){this._bounds=function(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;const{x,y,width,height}=node.boundingRect?node.boundingRect(includeTransform):{x:0,y:0,width:0,height:0};return {x,y,width,height};};this._attrs=node.attrs;this._type=node.type;this._data=node.data;this._dpi=node.stage?node.stage.dpi:1;this._collider=()=>colliderToShape(node,this._dpi);this._desc=node.desc;this._tag=node.tag;this._children=()=>node.children.map(n=>new SceneNode(n));this._parent=()=>node.parent?new SceneNode(node.parent):null;this._cache={elementBoundingRect:null};this._getElementBoundingRect=()=>{if(!this._cache.elementBoundingRect&&this.element){this._cache.elementBoundingRect=this.element.getBoundingClientRect();}return this._cache.elementBoundingRect||{left:0,top:0};};}/**
	   * Get child nodes
	   * @type {SceneNode[]}
	   */get children(){return this._children();}/**
	   * Get parent node
	   * @type {SceneNode}
	   */get parent(){return this._parent();}/**
	   * Node type
	   * @type {string}
	   */get type(){return this._type;}/**
	   * Get the associated data
	   * @type {any}
	   */get data(){return this._data;}/**
	   * Node attributes
	   * @type {object}
	   */get attrs(){return this._attrs;}/**
	   * Element the scene is attached to
	   * @type {HTMLElement}
	   * @private
	   */set element(e){this._cache.elementBoundingRect=null;this._element=e;}/**
	   * Element the scene is attached to
	   * @type {HTMLElement}
	   */get element(){return this._element;}/**
	   * Key of the component this shape belongs to
	   * @type {string}
	   * @private
	   */set key(k){this._key=k;}/**
	   * Key of the component this shape belongs to
	   * @type {string}
	   */get key(){return this._key;}/**
	   * Bounding rectangle of the node. After any transform has been applied, if any, but excluding scaling transform related to devicePixelRatio.
	   * Origin is in the top-left corner of the scene element.
	   * @type {Rect}
	   */get bounds(){const bounds=this._bounds();bounds.x/=this._dpi;bounds.y/=this._dpi;bounds.width/=this._dpi;bounds.height/=this._dpi;return bounds;}/**
	   * Bounding rectangle of the node within its local coordinate system.
	   * Origin is in the top-left corner of the scene element.
	   * @type {Rect}
	   */get localBounds(){const bounds=this._bounds(false);return bounds;}/**
	   * Bounding rectangle of the node, relative a target.
	   *
	   * If target is an HTMLElement, the bounds are relative to the HTMLElement.
	   * Any other target type will return the bounds relative to the viewport of the browser.
	   *
	   * @param {HTMLElement|any} target
	   * @param {boolean} includeTransform - Whether to include any applied transforms on the node
	   * @returns {Rect}
	   * @example
	   *
	   * node.boundsRelativeTo($('div'));
	   * node.boundsRelativeTo('viewport');
	   */boundsRelativeTo(target){let includeTransform=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;const type=typeof target;const bounds=includeTransform?this.bounds:this.localBounds;const selfRect=this._getElementBoundingRect();let dx=selfRect.left;let dy=selfRect.top;if(type==='object'&&target!==null&&typeof target.getBoundingClientRect==='function'){const{left=0,top=0}=target.getBoundingClientRect();dx-=left;dy-=top;}bounds.x+=dx;bounds.y+=dy;return bounds;}/**
	   * Collider of the node. Transform on the node has been applied to the collider shape, if any, but excluding scaling transform related to devicePixelRatio.
	   * Origin is in the top-left corner of the scene element.
	   *
	   * If node has no collider, null is returned.
	   * @type {Line|Rect|Circle|Path}
	   */get collider(){return this._collider();}/**
	   * Node description
	   * @type {object}
	   */get desc(){return this._desc;}/**
	   * Node tag
	   * @type {string}
	   */get tag(){return this._tag;}}function create$c(){for(var _len=arguments.length,a=new Array(_len),_key=0;_key<_len;_key++){a[_key]=arguments[_key];}return new SceneNode(...a);}class Collision{constructor(node){this._node=create$c(node);this._parent=null;this._input=null;}get node(){return this._node;}set parent(p){this._parent=p;}get parent(){return this._parent;}set input(i){this._input=i;}get input(){return this._input;}}function create$b(){for(var _len=arguments.length,a=new Array(_len),_key=0;_key<_len;_key++){a[_key]=arguments[_key];}return new Collision(...a);}function appendParentNode(node,collision){const p=node.parent;if(p&&p.type!=='stage'){collision.parent=create$b(p);const pp=p.parent;if(pp&&pp.type!=='stage'){appendParentNode(pp,collision.parent);}}}function appendInputShape(shape,collisions){for(let i=0,len=collisions.length;i<len;i++){collisions[i].input=shape;}}function resolveFrontChildCollision(node,type,input){const num=node.descendants.length;for(let i=num-1;i>=0;i--){const desc=node.descendants[i];if(desc.collider===null){continue;}if(desc.collider[type](input)){const collision=create$b(desc);appendParentNode(desc,collision);return collision;}}return null;}function resolveGeometryCollision(node,type,input){if(node.collider[type](input)){const c=create$b(node);appendParentNode(node,c);return c;}return null;}function inverseTransform(node,input){let transformedInput={};if(node.modelViewMatrix){if(Array.isArray(input)){// Rect or Line
	transformedInput=node.inverseModelViewMatrix.transformPoints(input);}else if(!isNaN(input.r)){// Circle
	const p={x:input.cx,y:input.cy};({x:transformedInput.cx,y:transformedInput.cy}=node.inverseModelViewMatrix.transformPoint(p));transformedInput.r=input.r;}else if(Array.isArray(input.vertices)){// Polygon
	transformedInput.vertices=node.inverseModelViewMatrix.transformPoints(input.vertices);}else {// Point
	transformedInput=node.inverseModelViewMatrix.transformPoint(input);}}else {transformedInput=input;}if(Array.isArray(transformedInput.vertices)){if(transformedInput.vertices.every(item=>Array.isArray(item))){transformedInput=create$g(transformedInput);}else {transformedInput=create$h(transformedInput);// TODO Shouldn't have to do this here, currently its beacause a collision algorithm optimization, i.e. caching of polygon bounds
	}}return transformedInput;}function resolveCollision(node,intersectionType,input){if(node.colliderType===null){return null;}const transformedInput=inverseTransform(node,input);if(node.colliderType==='frontChild'){return resolveFrontChildCollision(node,intersectionType,transformedInput);}return resolveGeometryCollision(node,intersectionType,transformedInput);}function findAllCollisions(nodes,intersectionType,ary,input){const num=nodes.length;for(let i=0;i<num;i++){const node=nodes[i];const collision=resolveCollision(node,intersectionType,input);if(collision){ary.push(collision);}// Only traverse children if no match is found on parent and it doesnt have any custom collider
	if(node.children&&!collision&&!node.collider){findAllCollisions(node.children,intersectionType,ary,input);}}}function hasCollision(nodes,intersectionType,input){const num=nodes.length;for(let i=0;i<num;i++){const node=nodes[i];const collision=resolveCollision(node,intersectionType,input);if(collision!==null){return true;}if(node.children&&!node.collider){return hasCollision(node.children,intersectionType,input);}}return false;}function resolveShape(shape){let ratio=arguments.length>1&&arguments[1]!==undefined?arguments[1]:1;const type=getShapeType(shape);let _shape={};switch(type){case 'circle':_shape.cx=shape.cx*ratio;_shape.cy=shape.cy*ratio;_shape.r=shape.r;return ['intersectsCircle',_shape];case 'rect':_shape=rectToPoints(shape).map(p=>scalarMultiply(p,ratio));return ['intersectsRect',_shape];case 'line':_shape=lineToPoints(shape).map(p=>scalarMultiply(p,ratio));return ['intersectsLine',_shape];case 'point':_shape=scalarMultiply(shape,ratio);return ['containsPoint',_shape];case 'polygon':_shape.vertices=shape.vertices.map(vertex=>scalarMultiply(vertex,ratio));return ['intersectsPolygon',_shape];case 'geopolygon':_shape.vertices=shape.vertices.map(vertices=>vertices.map(vertex=>scalarMultiply(vertex,ratio)));return ['intersectsGeoPolygon',_shape];default:return [];}}function resolveCollionsOnNode(node,shape){const[intersectionType,_shape]=resolveShape(shape,node.dpi);const collisions=[];if(intersectionType){findAllCollisions([node],intersectionType,collisions,_shape);appendInputShape(shape,collisions);}return collisions;}function hasCollisionOnNode(node,shape){const[intersectionType,_shape]=resolveShape(shape,node.dpi);return hasCollision([node],intersectionType,_shape);}/**
	 * @private
	 * @typedef {object} DisplayObject
	 * @property {string} type
	 * @property {string|GradientNode|PatternNode} [fill] - {@link https://www.w3.org/TR/fill-stroke-3/#fill-shorthand}
	 * @property {string|GradientNode|PatternNode} [stroke] - {@link https://www.w3.org/TR/fill-stroke-3/#propdef-stroke}
	 * @property {number} [strokeWidth] - {@link https://www.w3.org/TR/fill-stroke-3/#propdef-stroke-width}
	 * @property {string|number[]} [strokeDasharray] - {@link https://www.w3.org/TR/fill-stroke-3/#propdef-stroke-dasharray}
	 * @property {number} [opacity] - {@link https://www.w3.org/TR/css-color-4/#propdef-opacity}
	 * @property {string} [transform] - {@link https://www.w3.org/TR/SVG/coords.html#TransformAttribute}
	 * @property {object} [data] - Data object, may contain any properties
	 * @property {object} [desc] - Meta-data object, may contain any properties
	 * @property {string} [tag] - White-space seperated list of tags
	 * @property {string} [id] - Unique identifier of the node
	 * @property {object} [collider]
	 */class DisplayObject extends Node$1{constructor(type){super(type);this._stage=null;this._collider={type:null,definition:null,fn:null};this._attrs={};this._node=null;}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};this.node=v;const{data,desc,tag,strokeReference,fillReference}=v;assignMappedAttribute(this.attrs,v);if(typeof data!=='undefined'){this.data=data;}if(typeof desc==='object'){this.desc=extend$1$1(true,{},desc);}if(typeof tag==='string'){this.tag=tag;}if(typeof strokeReference==='string'){this.strokeReference=strokeReference;}if(typeof fillReference==='string'){this.fillReference=fillReference;}}findShapes(selector){return nodeSelector.find(selector,this).map(node=>create$c(node));}getItemsFrom(shape){return resolveCollionsOnNode(this,shape);}containsPoint(p){return hasCollisionOnNode(this,p);}intersectsLine(line){return hasCollisionOnNode(this,line);}intersectsRect(rect){return hasCollisionOnNode(this,rect);}intersectsCircle(circle){return hasCollisionOnNode(this,circle);}intersectsPolygon(polygon){return hasCollisionOnNode(this,polygon);}intersectsGeoPolygon(geopolygon){return hasCollisionOnNode(this,geopolygon);}resolveLocalTransform(){let m=arguments.length>0&&arguments[0]!==undefined?arguments[0]:new Matrix();if(typeof this.attrs.transform!=='undefined'){resolveTransform(this.attrs.transform,m);}this.modelViewMatrix=m.clone();}resolveGlobalTransform(){let m=arguments.length>0&&arguments[0]!==undefined?arguments[0]:new Matrix();const a=this.ancestors;if(a.length>0){for(let i=a.length-1;i>=0;i--){a[i].resolveLocalTransform(m);m=a[i].modelViewMatrix;}}this.resolveLocalTransform(m);}/**
	   * Returns the value of attribute a.
	   * @private
	   * @param a
	   * @returns {*} The value of attribute a.
	   */attr(a){return this.attrs[a];}equals(d){const attrs=this.attrs;const attrKeys=Object.keys(attrs);const dAttrs=d.attrs;const dAttrKeys=Object.keys(dAttrs);if(attrKeys.length!==dAttrKeys.length){return false;}for(let i=0;i<attrKeys.length;i++){const key=attrKeys[i];if(!Object.hasOwnProperty.call(dAttrs,key)){return false;}if(attrs[key]!==dAttrs[key]){return false;}}return super.equals(d);}toJSON(){const json=super.toJSON();json.attrs=this.attrs;return json;}get attrs(){return this._attrs;}get stage(){if(this._parent&&!this._stage){// lazy evaluation
	this._stage=this._parent.stage;}else if(!this._parent&&this._stage!==this){this._stage=null;}return this._stage;}set modelViewMatrix(m){this._mvm=m;this._imvm=null;}get modelViewMatrix(){return this._mvm;}get inverseModelViewMatrix(){this._imvm=this._imvm?this._imvm:this._mvm.clone().invert();return this._imvm;}set node(n){this._node=n;}get node(){return this._node;}set collider(definition){const type=Array.isArray(definition)?'collection':definition&&definition.type;if(typeof type!=='string'){// Non string type definition resets the collider
	this._collider.type=null;this._collider.definition=null;this._collider.fn=null;return;}// Check if a collider of the same type is already defined, if so, do an update
	if(this._collider!==null&&this._collider.type===type&&this._collider.fn!==null){this._collider.fn.set(definition);this._collider.definition=definition;return;}// Store the definition so that it can be lazy evaluated
	this._collider.type=type;this._collider.definition=definition;}get collider(){// Resolve geometry function from cache
	if(this._collider.fn!==null){return this._collider.fn;}// Resolve geometry function and store it in cache
	switch(this._collider.type){case 'collection':this._collider.fn=create$d(this._collider.definition);break;case 'frontChild':// TODO Deprecate
	// Front child is not resolved by a function on this node, but instead on one of its child nodes
	return true;case 'bounds':this._collider.fn=create$e('rect',this.boundingRect());break;case 'line':case 'rect':case 'circle':case 'polygon':case 'geopolygon':case 'polyline':this._collider.fn=create$e(this._collider.type,this._collider.definition);break;default:return null;}return this._collider.fn;}get colliderType(){return this._collider.type;}}class NodeContainer extends Node$1{addChild(c){if(!c||!(c instanceof Node$1)){throw new TypeError("Expecting a Node as argument, but got ".concat(c));}if(c===this){throw new Error('Can not add itself as child!');}if(c._children&&c._children.length&&this.ancestors.indexOf(c)>=0){throw new Error('Can not add an ancestor as child!');}if(c._parent&&c._parent!==this){c._parent.removeChild(c);}this._children.push(c);c._parent=this;c._ancestors=null;return this;}addChildren(children){let i,num=children?children.length:0;for(i=0;i<num;i++){this.addChild(children[i]);}return this;}/**
	   * Removes given child node from this node.
	   * @private
	   * @param {Node} c
	   * @returns {Node} This object, for chaining purposes.
	   */removeChild(c){const indx=this._children.indexOf(c);if(indx>=0){this._children.splice(indx,1);c._parent=null;c._ancestors=null;}return this;}removeChildren(children){let i,num;if(!this._children){return this;}if(children){num=children.length;for(i=0;i<num;i++){this.removeChild(children[i]);}}else {while(this._children.length){this.removeChild(this._children[0]);}}return this;}}/**
	 * @private
	 * @extends DisplayObject
	 * @typedef {object} ContainerNode
	 * @property {DisplayObject[]} children - Array of child nodes
	 */const NC$2=NodeContainer.prototype;class Container extends DisplayObject{constructor(){let s=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{type='container'}=s;super(type);this.set(s);}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};super.set(v);const{collider}=v;const opts=extend$1$1({type:null},collider);this.collider=opts;this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};}appendChildRect(child,includeTransform){if(typeof child.bounds!=='undefined'){const rect=this.__boundingRect[includeTransform]||{};const[p0,,p2]=child.bounds(includeTransform);const{x:xMin,y:yMin}=p0;const{x:xMax,y:yMax}=p2;const _xMax=isNaN(rect.width)?xMax:Math.max(xMax,rect.width+rect.x);const _yMax=isNaN(rect.height)?yMax:Math.max(yMax,rect.height+rect.y);rect.x=isNaN(rect.x)?xMin:Math.min(xMin,rect.x);rect.y=isNaN(rect.y)?yMin:Math.min(yMin,rect.y);rect.width=_xMax-rect.x;rect.height=_yMax-rect.y;this.__boundingRect[includeTransform]=rect;}}boundingRect(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__boundingRect[includeTransform]!==null){return this.__boundingRect[includeTransform];}const num=this.children.length;for(let i=0;i<num;i++){this.appendChildRect(this.children[i],includeTransform);}this.__boundingRect[includeTransform]=extend$1$1({x:0,y:0,width:0,height:0},this.__boundingRect[includeTransform]);return this.__boundingRect[includeTransform];}bounds(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__bounds[includeTransform]!==null){return this.__bounds[includeTransform];}const rect=this.boundingRect(includeTransform);this.__bounds[includeTransform]=[{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];return this.__bounds[includeTransform];}addChild(c){const r=NC$2.addChild.call(this,c);if(this._collider&&this._collider.type==='bounds'){this.appendChildRect(c,true);const opts=extend$1$1({type:'bounds',x:0,y:0,width:0,height:0},this.__boundingRect.true);this.collider=opts;}return r;}addChildren(children){const r=NC$2.addChildren.call(this,children);const num=children.length;if(this._collider&&this._collider.type==='bounds'&&num>0){for(let i=0;i<num;i++){this.appendChildRect(children[i],true);}const opts=extend$1$1({type:'bounds',x:0,y:0,width:0,height:0},this.__boundingRect.true);this.collider=opts;}return r;}removeChild(c){c._stage=null;let desc=c.descendants,num=desc?desc.length:0,i;// remove reference to stage from all descendants
	for(i=0;i<num;i++){desc[i]._stage=null;}NC$2.removeChild.call(this,c);if(this._collider&&this._collider.type==='bounds'){this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};const opts=extend$1$1(this.boundingRect(true),{type:'bounds'});this.collider=opts;}return this;}removeChildren(children){NC$2.removeChildren.call(this,children);if(this._collider&&this._collider.type==='bounds'){this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};const opts=extend$1$1(this.boundingRect(true),{type:'bounds'});this.collider=opts;}return this;}}function create$a(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new Container(...s);}class Stage extends Container{constructor(dpi){super('stage');this._stage=this;this._dpiRatio=dpi||1;}get dpi(){return this._dpiRatio;}}function create$9(){for(var _len=arguments.length,a=new Array(_len),_key=0;_key<_len;_key++){a[_key]=arguments[_key];}return new Stage(...a);}/**
	 * @private
	 * @typedef {object} GradientNode
	 * @property {string} type
	 * @property {object[]} stops
	 * @property {string} [stops[].type=linearGradient] - radialGradient|linearGradient|conicGradient
	 * @property {string} stops[].color - {@link https://www.w3.org/TR/SVG/types.html#DataTypeColor}
	 * @property {string} [stops[].opacity=1] - {@link https://www.w3.org/TR/css-color-4/#propdef-opacity}
	 * @property {number} stops[].offset - {@link https://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute}
	 * @property {number} [degree] - Gradient rotation angle
	 *//**
	 * @private
	 * @typedef {object} GradientItemNode
	 * @property {string} id - Gradient identifier
	 * @property {number} x1 - {@link https://www.w3.org/TR/SVG/pservers.html#LinearGradientElementX1Attribute}
	 * @property {number} y1 - {@link https://www.w3.org/TR/SVG/pservers.html#LinearGradientElementY1Attribute}
	 * @property {number} x2 - {@link https://www.w3.org/TR/SVG/pservers.html#LinearGradientElementX2Attribute}
	 * @property {number} y2 - {@link https://www.w3.org/TR/SVG/pservers.html#LinearGradientElementY2Attribute}
	 * @property {number} offset - {@link https://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute}
	 * @property {object} style - {@link https://www.w3.org/TR/SVG/styling.html#StyleAttribute}
	 */const NC$1=NodeContainer.prototype;const allowedAttrs$1=['x1','x2','y1','y2','id','offset','style'];class GradientItem extends DisplayObject{constructor(){let s=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{type='container'}=s;super(type);this.set(s);this._boundingRect={};}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};super.set(v);const attrs=this.attrs;let attrKey='';for(let i=0,len=allowedAttrs$1.length;i!==len;i++){attrKey=allowedAttrs$1[i];if(typeof v[attrKey]!=='undefined'){attrs[attrKey]=v[attrKey];}}}addChild(c){const r=NC$1.addChild.call(this,c);return r;}addChildren(children){const r=NC$1.addChildren.call(this,children);return r;}removeChild(c){c._stage=null;let desc=c.descendants,num=desc?desc.length:0,i;// remove reference to stage from all descendants
	for(i=0;i<num;i++){desc[i]._stage=null;}NC$1.removeChild.call(this,c);return this;}removeChildren(children){NC$1.removeChildren.call(this,children);return this;}}function create$8(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new GradientItem(...s);}/**
	 * @private
	 * @experimental
	 * @typedef {object} PatternNode
	 * @property {string} [type='pattern']
	 * @property {string} fill
	 * @property {number} width
	 * @property {number} height
	 * @property {object[]} shapes
	 * @example
	 * // Stripe pattern
	 * {
	 *   type: 'pattern',
	 *   fill: 'red',
	 *   width: 4,
	 *   height: 4,
	 *   shapes: [
	 *     { type: 'rect', x: 3, y: 0, width: 1, height: 1 },
	 *     { type: 'rect', x: 2, y: 1, width: 1, height: 1 },
	 *     { type: 'rect', x: 1, y: 2, width: 1, height: 1 },
	 *     { type: 'rect', x: 0, y: 3, width: 1, height: 1 },
	 *   ]
	 * }
	 */const NC=NodeContainer.prototype;const allowedAttrs=['patternUnits','x','y','width','height','id'];class PatternItem extends DisplayObject{constructor(){let s=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{type='container'}=s;super(type);this.set(s);this._boundingRect={};}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};super.set(v);const attrs=this.attrs;let attrKey='';for(let i=0,len=allowedAttrs.length;i!==len;i++){attrKey=allowedAttrs[i];if(typeof v[attrKey]!=='undefined'){attrs[attrKey]=v[attrKey];}}}addChild(c){const r=NC.addChild.call(this,c);return r;}addChildren(children){const r=NC.addChildren.call(this,children);return r;}removeChild(c){c._stage=null;let desc=c.descendants,num=desc?desc.length:0,i;// remove reference to stage from all descendants
	for(i=0;i<num;i++){desc[i]._stage=null;}NC.removeChild.call(this,c);return this;}removeChildren(children){NC.removeChildren.call(this,children);return this;}}function create$7(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new PatternItem(...s);}/**
	 * @private
	 * @extends DisplayObject
	 * @typedef {object} RectNode
	 * @property {number} x - X coordinate
	 * @property {number} y - Y coordinate
	 * @property {number} width - Width
	 * @property {number} height- Height
	 */class Rect extends DisplayObject{constructor(){super('rect');this.set(...arguments);}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{x=0,y=0,width=0,height=0,rx=0,ry=0,collider}=v;const opts=extend$1$1({type:'rect',x,y,width,height},collider);super.set(v);if(width>=0){this.attrs.x=x;this.attrs.width=width;}else {this.attrs.x=x+width;this.attrs.width=-width;}if(height>=0){this.attrs.y=y;this.attrs.height=height;}else {this.attrs.y=y+height;this.attrs.height=-height;}if(rx>0){this.attrs.rx=rx;}if(ry>0){this.attrs.ry=ry;}this.collider=opts;this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};}boundingRect(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__boundingRect[includeTransform]!==null){return this.__boundingRect[includeTransform];}const p=rectToPoints(this.attrs);const pt=includeTransform&&this.modelViewMatrix?this.modelViewMatrix.transformPoints(p):p;const[xMin,yMin,xMax,yMax]=getMinMax$1(pt);this.__boundingRect[includeTransform]={x:xMin,y:yMin,width:xMax-xMin,height:yMax-yMin};return this.__boundingRect[includeTransform];}bounds(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__bounds[includeTransform]!==null){return this.__bounds[includeTransform];}const rect=this.boundingRect(includeTransform);this.__bounds[includeTransform]=[{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];return this.__bounds[includeTransform];}}function create$6(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new Rect(...s);}/**
	 * @private
	 * @extends DisplayObject
	 * @typedef {object} CircleNode
	 * @property {number} cx - {@link https://www.w3.org/TR/SVG/shapes.html#CircleElementCXAttribute}
	 * @property {number} cy - {@link https://www.w3.org/TR/SVG/shapes.html#CircleElementCYAttribute}
	 * @property {number} r - {@link https://www.w3.org/TR/SVG/shapes.html#CircleElementRAttribute}
	 */class Circle extends DisplayObject{constructor(){super('circle');this.set(...arguments);}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{cx=0,cy=0,r=0,collider}=v;const opts=extend$1$1({type:'circle',cx,cy,r},collider);super.set(v);this.attrs.cx=cx;this.attrs.cy=cy;this.attrs.r=r;this.collider=opts;this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};}boundingRect(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__boundingRect[includeTransform]!==null){return this.__boundingRect[includeTransform];}// TODO Handle Circle bounds correctly for a circle transformed to an non axis aligned ellipse/circle
	// Current solution only rotate the bounds, giving a larger boundingRect if rotated
	const p=this.bounds(includeTransform);this.__boundingRect[includeTransform]={x:p[0].x,y:p[0].y,width:p[2].x-p[0].x,height:p[2].y-p[0].y};return this.__boundingRect[includeTransform];}bounds(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__bounds[includeTransform]!==null){return this.__bounds[includeTransform];}// TODO Handle Circle bounds correctly for a circle transformed to an non axis aligned ellipse/circle
	const{cx,cy,r:rX,r:rY}=this.attrs;const x=cx-rX;const y=cy-rY;let w=rX*2;let h=rY*2;let p=[{x,y},{x:x+w,y},{x:x+w,y:y+h},{x,y:y+h}];if(includeTransform&&this.modelViewMatrix){p=this.modelViewMatrix.transformPoints(p);const[xMin,yMin,xMax,yMax]=getMinMax$1(p);w=xMax-xMin;h=yMax-yMin;this.__bounds[includeTransform]=[{x:xMin,y:yMin},{x:xMin+w,y:yMin},{x:xMin+w,y:yMin+h},{x:xMin,y:yMin+h}];}else {this.__bounds[includeTransform]=p;}return this.__bounds[includeTransform];}}function create$5(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new Circle(...s);}/**
	 * @private
	 * @extends DisplayObject
	 * @typedef {object} LineNode
	 * @property {number} x1 - {@link https://www.w3.org/TR/SVG/shapes.html#LineElementX1Attribute}
	 * @property {number} y1 - {@link https://www.w3.org/TR/SVG/shapes.html#LineElementY1Attribute}
	 * @property {number} x2 - {@link https://www.w3.org/TR/SVG/shapes.html#LineElementX2Attribute}
	 * @property {number} y2 - {@link https://www.w3.org/TR/SVG/shapes.html#LineElementY2Attribute}
	 */class Line extends DisplayObject{constructor(){super('line');this.set(...arguments);}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{x1=0,y1=0,x2=0,y2=0,collider}=v;super.set(v);this.attrs.x1=x1;this.attrs.y1=y1;this.attrs.x2=x2;this.attrs.y2=y2;const defaultCollider={type:'line',x1,y1,x2,y2};this.collider=extend$1$1(defaultCollider,collider);this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};}boundingRect(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__boundingRect[includeTransform]!==null){return this.__boundingRect[includeTransform];}let p=lineToPoints(this.attrs);if(includeTransform&&this.modelViewMatrix){p=this.modelViewMatrix.transformPoints(p);}const[xMin,yMin,xMax,yMax]=getMinMax$1(p);const hasSize=xMin!==xMax||yMin!==yMax;this.__boundingRect[includeTransform]={x:xMin,y:yMin,width:hasSize?Math.max(1,xMax-xMin):0,height:hasSize?Math.max(1,yMax-yMin):0};return this.__boundingRect[includeTransform];}bounds(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__bounds[includeTransform]!==null){return this.__bounds[includeTransform];}const rect=this.boundingRect(includeTransform);this.__bounds[includeTransform]=[{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];return this.__bounds[includeTransform];}}function create$4(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new Line(...s);}const PI_2=Math.PI/2;function lineAngle(p0,p1){const t=Math.atan2(p1.y-p0.y,p1.x-p0.x);return t<0?t+Math.PI*2:t;}// TODO Find a more accurate method to find the open and closed points
	function rotatePoint(p,angle,radius){return {x:p.x+Math.cos(angle)*radius,y:p.y+Math.sin(angle)*radius};}function polylineToPolygonCollider(points,radius){let opts=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};const open=[];const close=[];// TODO handle case if points.length === 2
	if(opts.forceOrientation==='h'){const start=points[0].x<points[1].x?-1:1;const end=points[points.length-1].x>points[points.length-2].x?1:-1;points.unshift({x:points[0].x+start,y:points[0].y});points.push({x:points[points.length-1].x+end,y:points[points.length-1].y});}else if(opts.forceOrientation==='v'){const start=points[0].y<points[1].y?-1:1;const end=points[points.length-1].y>points[points.length-2].y?1:-1;points.unshift({x:points[0].x,y:points[0].y+start});points.push({x:points[points.length-1].x,y:points[points.length-1].y+end});}const len=points.length-1;for(let i=1;i<len;i++){const prev=points[i-1];const curr=points[i];const next=points[i+1];const currToPrev=lineAngle(curr,prev);const currToNext=lineAngle(curr,next);const openAngle=(currToPrev+currToNext)/2;const closeAngle=openAngle+Math.PI;const maxAngle=Math.max(openAngle,closeAngle);const minAngle=Math.min(openAngle,closeAngle);const openClose=currToPrev>currToNext;if(i===1){const prevToCurr=lineAngle(prev,curr);open.push(rotatePoint(prev,prevToCurr-PI_2,radius));close.unshift(rotatePoint(prev,prevToCurr+PI_2,radius));}const opened=openClose?maxAngle:minAngle;const closed=openClose?minAngle:maxAngle;open.push(rotatePoint(curr,opened,radius));close.unshift(rotatePoint(curr,closed,radius));if(i===len-1){const nextToCurr=lineAngle(next,curr);open.push(rotatePoint(next,nextToCurr+PI_2,radius));close.unshift(rotatePoint(next,nextToCurr-PI_2,radius));}}return {type:'polygon',vertices:[...open,...close]};}function flatten2d(ary){const newAry=[];let a;let len=ary.length;for(let i=0;i<len;i++){a=ary[i];for(let k=0;k<a.length;k++){newAry.push(a[k]);}}return newAry;}const EPSILON$4=1e-12;const CURVES={step:curveStep,stepAfter:stepAfter,stepBefore:stepBefore,linear:curveLinear,basis:curveBasis,cardinal:curveCardinal.tension(0),catmullRom:curveCatmullRom,monotonex:monotoneX,monotoney:monotoneY,natural:curveNatural};/**
	 * @private
	 * @extends DisplayObject
	 * @typedef {object} PathNode
	 * @property {string} d - {@link https://www.w3.org/TR/SVG/paths.html#DAttribute}
	 */function isClosed(points){if(points.length<2){return false;}const p0=points[0];const p1=points[points.length-1];return Math.abs(p0.x-p1.x)<EPSILON$4&&Math.abs(p0.y-p1.y)<EPSILON$4;}class Path extends DisplayObject{constructor(){super('path');this.set(...arguments);}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};super.set(v);this.segments=[];this.points=[];if(v.arcDatum){const arcGen=arc();arcGen.innerRadius(v.desc.slice.innerRadius);arcGen.outerRadius(v.desc.slice.outerRadius);arcGen.cornerRadius(v.desc.slice.cornerRadius);const d=arcGen(v.arcDatum);this.attrs.d=d;}else if(v.points){const{major,minor,layerObj,points,stngs,generatorType}=v;const areaGenerator=area();const defined=stngs.coordinates?stngs.coordinates.defined:null;areaGenerator[major.p](d=>d.major*major.size)// eslint-disable-line no-unexpected-multiline
	["".concat(minor.p,"1")](d=>d.minor*minor.size)// eslint-disable-line no-unexpected-multiline
	["".concat(minor.p,"0")](d=>d.minor0*minor.size)// eslint-disable-line no-unexpected-multiline
	.curve(CURVES[layerObj.curve==='monotone'?"monotone".concat(major.p):layerObj.curve]);if(defined){areaGenerator.defined(d=>!d.dummy&&typeof d.minor==='number'&&!isNaN(d.minor)&&d.defined);}else {areaGenerator.defined(d=>!d.dummy&&typeof d.minor==='number'&&!isNaN(d.minor));}const filteredPoints=stngs.connect?points.filter(areaGenerator.defined()):points;const generator=generatorType==='area'?areaGenerator:areaGenerator[generatorType]();const d=generator(filteredPoints);this.attrs.d=d;}else if(v.d){this.attrs.d=v.d;}this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};if(Array.isArray(v.collider)||typeof v.collider==='object'&&typeof v.collider.type!=='undefined'){this.collider=v.collider;}else if(this.attrs.d){this.segments=pathToPoints(this.attrs.d);if(this.segments.length>1&&this.segments.every(segment=>isClosed(segment))){this.collider=extend$1$1({type:'geopolygon',vertices:this.segments},v.collider);return;}this.segments.forEach(segment=>{if(segment.length<=1);else if(isClosed(segment)){this.collider=extend$1$1({type:'polygon',vertices:segment},v.collider);}else if(typeof v.collider==='object'&&v.collider.visual){const size=this.attrs['stroke-width']/2;this.collider=polylineToPolygonCollider(segment,size,v.collider);}else {this.collider=extend$1$1({type:'polyline',points:segment},v.collider);}});}}boundingRect(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__boundingRect[includeTransform]!==null){return this.__boundingRect[includeTransform];}if(!this.points.length){this.segments=this.segments.length?this.segments:pathToPoints(this.attrs.d);this.points=flatten2d(this.segments);}const pt=includeTransform&&this.modelViewMatrix?this.modelViewMatrix.transformPoints(this.points):this.points;const[xMin,yMin,xMax,yMax]=getMinMax$1(pt);this.__boundingRect[includeTransform]={x:xMin||0,y:yMin||0,width:xMax-xMin||0,height:yMax-yMin||0};return this.__boundingRect[includeTransform];}bounds(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__bounds[includeTransform]!==null){return this.__bounds[includeTransform];}const rect=this.boundingRect(includeTransform);this.__bounds[includeTransform]=[{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];return this.__bounds[includeTransform];}}function create$3(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new Path(...s);}function hasData$1(_ref){let{data,_boundingRect,_textBoundsFn}=_ref;return typeof data!=='undefined'&&data!==null&&(_boundingRect||_textBoundsFn);}/**
	 * @private
	 * @extends DisplayObject
	 * @typedef {object} TextNode
	 * @property {string} text
	 * @property {number} x - {@link https://www.w3.org/TR/SVG/text.html#TextElementXAttribute}
	 * @property {number} y - {@link https://www.w3.org/TR/SVG/text.html#TextElementYAttribute}
	 * @property {number} [dx] - {@link https://www.w3.org/TR/SVG/text.html#TextElementDXAttribute}
	 * @property {number} [dy] - {@link https://www.w3.org/TR/SVG/text.html#TextElementDYAttribute}
	 * @property {string} [fontSize] - {@link https://www.w3.org/TR/SVG/text.html#FontPropertiesUsedBySVG}
	 * @property {string} [fontFamily] - {@link https://www.w3.org/TR/SVG/text.html#FontPropertiesUsedBySVG}
	 * @property {Rect} [boundingRect] - Explicitly set the bounding rectangle of the node. Has predence over textBoundsFn
	 * @property {function} [textBoundsFn] - Implicitly set the bounding rectangle of the node, the function must return an object with x, y, width and height attributes
	 * @property {string} [baseline] - Alias for dominantBaseline
	 * @property {string} [dominantBaseline] - {@link https://www.w3.org/TR/SVG/text.html#BaselineAlignmentProperties}
	 * @property {string} [anchor] - Alias for textAnchor
	 * @property {string} [textAnchor] - {@link https://www.w3.org/TR/SVG/text.html#TextAnchorProperty}
	 * @property {string} [wordBreak] - Word-break option
	 * @property {number} [maxWidth] - Maximum allowed text width
	 * @property {number} [maxHeight] - Maximum allowed text height. If both maxLines and maxHeight are set, the property that results in the fewest number of lines is used
	 * @property {number} [maxLines] - Maximum number of lines allowed
	 * @property {number} [lineHeight=1.2] - Line height
	 */class Text extends DisplayObject{constructor(){super('text');this.set(...arguments);}set(){let v=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{x=0,y=0,dx=0,dy=0,textBoundsFn,text,title,collider,boundingRect,ellipsed}=v;super.set(v);this.attrs.x=x;this.attrs.y=y;this.attrs.dx=dx;this.attrs.dy=dy;this.attrs.text=text;if(typeof title!=='undefined'){this.attrs.title=String(title);}if(typeof boundingRect==='object'){this._textBoundsFn=()=>boundingRect;}else if(typeof textBoundsFn==='function'){this._textBoundsFn=textBoundsFn;}if(typeof ellipsed==='string'){this.ellipsed=ellipsed;}this.collider=extend$1$1({type:hasData$1(this)?'bounds':null},collider);this.__boundingRect={true:null,false:null};this.__bounds={true:null,false:null};}boundingRect(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__boundingRect[includeTransform]!==null){return this.__boundingRect[includeTransform];}let rect;if(typeof this._textBoundsFn==='function'){rect=this._textBoundsFn(this.attrs);}else {return {x:0,y:0,width:0,height:0};}const p=rectToPoints(rect);const pt=includeTransform&&this.modelViewMatrix?this.modelViewMatrix.transformPoints(p):p;const[xMin,yMin,xMax,yMax]=getMinMax$1(pt);this.__boundingRect[includeTransform]={x:xMin,y:yMin,width:xMax-xMin,height:yMax-yMin};return this.__boundingRect[includeTransform];}bounds(){let includeTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;if(this.__bounds[includeTransform]!==null){return this.__bounds[includeTransform];}const rect=this.boundingRect(includeTransform);this.__bounds[includeTransform]=[{x:rect.x,y:rect.y},{x:rect.x+rect.width,y:rect.y},{x:rect.x+rect.width,y:rect.y+rect.height},{x:rect.x,y:rect.y+rect.height}];return this.__bounds[includeTransform];}}function create$2(){for(var _len=arguments.length,s=new Array(_len),_key=0;_key<_len;_key++){s[_key]=arguments[_key];}return new Text(...s);}const reg$1=registryFactory();reg$1.add('rect',create$6);reg$1.add('circle',create$5);reg$1.add('text',create$2);reg$1.add('line',create$4);reg$1.add('path',create$3);reg$1.add('stage',create$9);reg$1.add('container',create$a);reg$1.add('defs',create$a);reg$1.add('linearGradient',create$8);reg$1.add('radialGradient',create$8);reg$1.add('conicGradient',create$8);reg$1.add('stop',create$8);reg$1.add('pattern',create$7);/* eslint-disable import/prefer-default-export */function create$1(type,input){return reg$1.get(type)(input);}/* eslint-enable import/prefer-default-export *//**
	 * Creates a context. Input an array of strings that should be inherited by the context.
	 * @private
	 *
	 * @param  {Array}  [whitelist=[]]  An array of whitelisted string keys to inherit
	 * @return {Function}               A context function
	 */function contextFactory(){let whitelist=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];const states=[{}];/**
	   * Returns the current context as an object. The object is mutable.
	   * @private
	   *
	   * @return {Object}   Current context
	   */function context(){// Returns the current context, the last in the stack.
	const item=states[states.length-1];return item;}/**
	   * Call context.save() to save the current context and move down the stack.
	   *
	   * @param  {Object} [item={}]   Optional item to save.
	   * @return {Object}             The current context, just as context()
	   */context.save=function save(){let item=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const current=context();const obj={};let key='';// Only inherit whitelisted properties
	for(let i=0;i<whitelist.length;i++){key=whitelist[i];if(typeof current[key]!=='undefined'){obj[key]=current[key];}}// Extend the new object with the saved item
	extend$1$1(obj,item);// Push it to the stack
	states.push(obj);// Return the new current context
	return context();};/**
	   * Restore the previous context. Returns the context.
	   *
	   * @return {Undefined}   Returns nothing
	   */context.restore=function restore(){// Remove the last element from the stack
	states.splice(states.length-1,1);};return context;}const styleContext=contextFactory(['stroke','fill','strokeWidth','opacity','fontFamily','fontSize','baseline']);function doEvent(state,listeners){if(!Array.isArray(listeners)){return;}for(let i=0,len=listeners.length;i<len;i++){listeners[i](state);}}function updateState(state,index,nodes){state.node=nodes[index];state.index=index;}function traverse(items,parent,matrix,on){let disabled=false;const state={siblings:items,node:null,index:0};for(let i=0,len=items.length;i<len;i++){updateState(state,i,items);doEvent(state,on.create);disabled=typeof state.node.disabled==='function'?state.node.disabled():state.node.disabled;if(disabled){continue;}// Save the current style context to be able to inherit styles
	state.node=styleContext.save(state.node);const displayNode=create$1(state.node.type,state.node);if(displayNode){if(state.node.transform){matrix.save();resolveTransform(state.node.transform,matrix);}if(!matrix.isIdentity()){displayNode.modelViewMatrix=matrix.clone();}parent.addChild(displayNode);if(state.node.children){traverse(state.node.children,displayNode,matrix,on);}if(state.node.transform){matrix.restore();}}// Revert to previous style context
	styleContext.restore();}}function scene(_ref){let{items,stage,dpi,on={}}=_ref;if(!stage){stage=create$1('stage',dpi);}traverse(items,stage,new Matrix(),on);return stage;}/**
	 * Get or create a gradient
	 * @ignore
	 * @param  {Object} g        Canvas 2d context
	 * @param  {Object} node    Current node (for width/height properties)
	 * @param  {Object} gradient The gradient properties
	 * @return {Object}          A canvas compatible radial or linear gradient object
	 */function createCanvasGradient(g,node,gradient){const{orientation,degree,stops=[]}=gradient;let newGradient=null;if(orientation==='radial'){const bounds=node.boundingRect();newGradient=g.createRadialGradient(bounds.x+bounds.width/2,bounds.y+bounds.height/2,1e-5,bounds.x+bounds.width/2,bounds.y+bounds.height/2,Math.max(bounds.width,bounds.height)/2);}else if(orientation==='conic'){const startAngle=gradient.startAngle||0;const centerOffsetX=gradient.x||0;const centerOffsetY=gradient.y||0;newGradient=g.createConicGradient(startAngle,centerOffsetX,centerOffsetY);}else {const points=degreesToPoints(degree);['x1','x2','y1','y2'].forEach(c=>{if(c in gradient){points[c]=gradient[c];}});const bounds=node.boundingRect();newGradient=g.createLinearGradient(bounds.x+points.x1*bounds.width,bounds.y+points.y1*bounds.height,bounds.x+points.x2*bounds.width,bounds.y+points.y2*bounds.height);}for(let i=0,len=stops.length;i<len;i++){let stop=stops[i];newGradient.addColorStop(stop.offset,stop.color);}return newGradient;}function getPattern(pattern,dummyCanvas,ctx){dummyCanvas.width=pattern.width;dummyCanvas.height=pattern.height;ctx.save();ctx.fillStyle=pattern.fill;pattern.shapes.forEach(s=>{switch(s.type){case 'rect':ctx.rect(s.x,s.y,s.width,s.height);break;}});ctx.fill();ctx.restore();return ctx.createPattern(dummyCanvas,'repeat');}function patternizer$1(document){const dummyCanvas=document.createElement('canvas');const ctx=dummyCanvas.getContext('2d');let cache={};return {create(pattern){const key=pattern.key;if(key){cache[key]=cache[key]||getPattern(pattern,dummyCanvas,ctx);return cache[key];}return getPattern(pattern,dummyCanvas,ctx);},clear(){cache={};}};}/**
	 * @typedef {object} Renderer~SizeDefinition
	 * @property {number} [x] - x-coordinate
	 * @property {number} [y] - y-coordinate
	 * @property {number} [width] - Width
	 * @property {number} [height] - Height
	 * @property {object} [scaleRatio]
	 * @property {number} [scaleRatio.x] - Scale ratio on x-axis
	 * @property {number} [scaleRatio.y] - Scale ratio on y-axis
	 * @property {object} [margin]
	 * @property {number} [margin.left] - Left margin
	 * @property {number} [margin.top] - Top margin
	 *//**
	 * Create the renderer box
	 * @private
	 * @param {Renderer~SizeDefinition} [opts]
	 * @returns {Renderer~SizeDefinition} A svg renderer instance
	 */function createRendererBox(){let{x,y,width,height,scaleRatio,margin,edgeBleed}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const box={x:0,y:0,width:0,height:0,scaleRatio:{x:1,y:1},margin:{left:0,top:0},edgeBleed:{left:0,right:0,top:0,bottom:0,bool:false}};box.x=isNaN(x)?box.x:x;box.y=isNaN(y)?box.y:y;box.width=isNaN(width)?box.width:width;box.height=isNaN(height)?box.height:height;if(typeof scaleRatio!=='undefined'){box.scaleRatio.x=isNaN(scaleRatio.x)?box.scaleRatio.x:scaleRatio.x;box.scaleRatio.y=isNaN(scaleRatio.y)?box.scaleRatio.y:scaleRatio.y;}if(typeof margin!=='undefined'){box.margin.left=isNaN(margin.left)?0:margin.left;box.margin.top=isNaN(margin.top)?0:margin.top;}if(typeof edgeBleed==='object'){['left','right','top','bottom'].forEach(prop=>{if(!isNaN(edgeBleed[prop])&&edgeBleed[prop]>0){box.edgeBleed[prop]=edgeBleed[prop];box.edgeBleed.bool=true;}});}box.computedPhysical={x:Math.round(box.margin.left+(box.x-box.edgeBleed.left)*box.scaleRatio.x),y:Math.round(box.margin.top+(box.y-box.edgeBleed.top)*box.scaleRatio.y),width:Math.round((box.width+box.edgeBleed.left+box.edgeBleed.right)*box.scaleRatio.x),height:Math.round((box.height+box.edgeBleed.top+box.edgeBleed.bottom)*box.scaleRatio.y)};return box;}/**
	 * Base renderer factory
	 * @private
	 */function create(){/**
	   * @interface
	   * @alias Renderer
	   */const renderer={/**
	     * Get the element this renderer is attached to
	     * @returns {HTMLElement}
	     */element:()=>{},/**
	     * Get the root element of the renderer
	     * @returns {HTMLElement}
	     */root:()=>{},/**
	     * Set or Get renderer settings
	     * @param {object} [settings] Settings for the renderer
	     */settings:()=>{},/**
	     * @param {HTMLElement} element - Element to attach renderer to
	     * @returns {HTMLElement} Root element of the renderer
	     */appendTo:()=>{},/**
	     * Get Scene based on provided nodes, constructed in the same way as in the render function.
	     * Only the canvas and svg renderer uses scene nodes.
	     * @private
	     * @param {object[]} nodes - Nodes on which the scene will be constructed
	     * @returns {Scene}
	     */getScene:()=>[],/**
	     * @param {object[]} nodes - Nodes to render
	     * @returns {boolean} True if the nodes were rendered, otherwise false
	     */render:()=>false,/**
	     * Get nodes renderer at area
	     * @param {Point|Circle|Rect|Line|Polygon|Geopolygon} geometry - Get nodes that intersects with geometry
	     * @returns {SceneNode[]}
	     */itemsAt:()=>[],/**
	     * Get all nodes matching the provided selector
	     * @param {string} selector CSS selector [type, attribute, universal, class]
	     * @returns {SceneNode[]} Array of objects containing matching nodes
	     */findShapes:()=>[],/**
	     * Clear all child elements from the renderer root element
	     * @returns {Renderer} The renderer instance
	     */clear:()=>{},/**
	     * Remove the renderer root element from its parent element
	     */destory:()=>{},/**
	     * Set or Get the size definition of the renderer container.
	     * @param {Renderer~SizeDefinition} [opts] - Size definition
	     * @returns {Renderer~SizeDefinition} The current size definition
	     */size:()=>{},/**
	     * @function
	     * @param {object} opts
	     * @param {string} opts.text - Text to measure
	     * @param {string} opts.fontSize - Font size
	     * @param {string} opts.fontFamily - Font family
	     * @returns {object} Width and height of text
	     * @example
	     * measureText({
	     *  text: 'my text',
	     *  fontSize: '12px',
	     *  fontFamily: 'Arial'
	     * }); // returns { width: 20, height: 12 }
	     */measureText,/**
	     * Calculates the bounding rectangle of a text node. Including any potential line breaks.
	     * @function
	     * @private
	     * @param {TextNode} node
	     * @return {Rect} The bounding rectangle
	     */textBounds,setKey:key=>{renderer.element().setAttribute('data-key',key);}};return renderer;}function hasData(data){return typeof data!=='undefined'&&data!==null;}function injectTextBoundsFn(renderer){return _ref=>{let{node}=_ref;if(node.type==='text'&&hasData(node.data)&&!node.textBoundsFn){node.textBoundsFn=renderer.textBounds;}};}const DEFAULT_PADDING={horizontal:200,vertical:200};/**
	 * Creates a canvas element, preferrably larger than the target canvas.
	 * This "buffer canvas" is detached from the DOM and allows rendering of shapes outside of the visible area.
	 * Especially useful when applying transforms to target canvas.
	 * @private
	 */class CanvasBuffer{constructor(targetCanvas){this.targetCanvas=targetCanvas;this.bufferCanvas=targetCanvas.cloneNode();}/**
	   * @param {object|function} [canvasBufferSize] object containing width and height or a function which returns it
	   */updateSize(_ref){let{rect,dpiRatio,canvasBufferSize}=_ref;let bufferSize;if(canvasBufferSize){bufferSize=typeof canvasBufferSize==='function'?canvasBufferSize(rect):canvasBufferSize;}else {bufferSize={width:rect.computedPhysical.width+DEFAULT_PADDING.horizontal*2,height:rect.computedPhysical.height+DEFAULT_PADDING.vertical*2};}this.bufferCanvas.style.width="".concat(bufferSize.width,"px");this.bufferCanvas.style.height="".concat(bufferSize.height,"px");this.bufferCanvas.width=Math.round(bufferSize.width*dpiRatio);this.bufferCanvas.height=Math.round(bufferSize.height*dpiRatio);}/**
	   * Draws buffer canvas on the target canvas.
	   */apply(){const g=this.targetCanvas.getContext('2d');g.drawImage(this.bufferCanvas,0,0);}clear(){// clear canvas
	this.bufferCanvas.width=this.bufferCanvas.width;// eslint-disable-line
	}getContext(){return this.bufferCanvas.getContext('2d');}}const reg=registryFactory();function toLineDash(p){if(Array.isArray(p)){return p;}if(typeof p==='string'){if(p.indexOf(',')!==-1){return p.split(',');}return p.split(' ');}return [];}function dpiScale(g){const dpr=typeof window==='undefined'?1:window.devicePixelRatio||1;const backingStorePixelRatio=g.webkitBackingStorePixelRatio||g.mozBackingStorePixelRatio||g.msBackingStorePixelRatio||g.oBackingStorePixelRatio||g.backingStorePixelRatio||1;return dpr/backingStorePixelRatio;}function resolveMatrix(p,g){g.setTransform(p[0][0],p[1][0],p[0][1],p[1][1],p[0][2],p[1][2]);}function applyContext(g,s,shapeToCanvasMap){let computed=arguments.length>3&&arguments[3]!==undefined?arguments[3]:{};const computedKeys=Object.keys(computed);for(let i=0,len=shapeToCanvasMap.length;i<len;i++){let cmd=shapeToCanvasMap[i];const shapeCmd=cmd[0];const canvasCmd=cmd[1];const convertCmd=cmd[2];if(shapeCmd in s.attrs&&!(canvasCmd in computed)&&g[canvasCmd]!==s.attrs[shapeCmd]){const val=convertCmd?convertCmd(s.attrs[shapeCmd]):s.attrs[shapeCmd];if(typeof g[canvasCmd]==='function'){g[canvasCmd](val);}else {g[canvasCmd]=val;}}}for(let i=0,len=computedKeys.length;i<len;i++){const key=computedKeys[i];g[key]=computed[key];}}function renderShapes(shapes,g,shapeToCanvasMap,deps){for(let i=0,len=shapes.length;i<len;i++){let shape=shapes[i];let computed={};g.save();if(shape.attrs&&(shape.attrs.fill||shape.attrs.stroke)){if(shape.attrs.fill&&typeof shape.attrs.fill==='object'&&shape.attrs.fill.type==='gradient'){computed.fillStyle=createCanvasGradient(g,shape,shape.attrs.fill);}else if(shape.attrs.fill&&typeof shape.attrs.fill==='object'&&shape.attrs.fill.type==='pattern'){computed.fillStyle=deps.patterns.create(shape.attrs.fill);}if(shape.attrs.stroke&&typeof shape.attrs.stroke==='object'&&shape.attrs.stroke.type==='gradient'){computed.strokeStyle=createCanvasGradient(g,shape,shape.attrs.stroke);}else if(shape.attrs.stroke&&typeof shape.attrs.stroke==='object'&&shape.attrs.stroke.type==='pattern'){computed.strokeStyle=deps.patterns.create(shape.attrs.stroke);}}applyContext(g,shape,shapeToCanvasMap,computed);if(shape.modelViewMatrix){resolveMatrix(shape.modelViewMatrix.elements,g);}if(reg.has(shape.type)){reg.get(shape.type)(shape.attrs,{g,doFill:'fill'in shape.attrs&&shape.attrs.fill!=='none',doStroke:'stroke'in shape.attrs&&shape.attrs['stroke-width']!==0,ellipsed:shape.ellipsed});}if(shape.children){renderShapes(shape.children,g,shapeToCanvasMap,deps);}g.restore();}}/**
	 * Sets transform on target element.
	 * @param {Element} el Target canvas element
	 * @param {number} dpiRatio
	 * @param {TransformObject}
	 * @private
	 */function applyTransform(_ref){let{el,dpiRatio,transform}=_ref;if(typeof transform==='object'){const adjustedTransform=[transform.horizontalScaling,transform.horizontalSkewing,transform.verticalSkewing,transform.verticalScaling,transform.horizontalMoving*dpiRatio,transform.verticalMoving*dpiRatio];const g=el.getContext('2d');g.setTransform(...adjustedTransform);}}/**
	 * Create a new canvas renderer
	 * @typedef {function} canvasRendererFactory
	 * @param {function} [sceneFn] - Scene factory
	 * @returns {Renderer} A canvas renderer instance
	 */function renderer$2(){let sceneFn=arguments.length>0&&arguments[0]!==undefined?arguments[0]:scene;let el;let buffer;const settings={transform:undefined,canvasBufferSize:undefined,progressive:undefined};let scene$1;let hasChangedRect=false;let rect=createRendererBox();const shapeToCanvasMap=[['fill','fillStyle'],['stroke','strokeStyle'],['opacity','globalAlpha'],['globalAlpha','globalAlpha'],['stroke-width','lineWidth'],['stroke-linejoin','lineJoin'],['stroke-dasharray','setLineDash',toLineDash]];let patterns;const canvasRenderer=create();canvasRenderer.element=()=>el;canvasRenderer.root=()=>el;canvasRenderer.settings=rendererSettings=>{if(rendererSettings){Object.keys(settings).forEach(key=>{if(rendererSettings[key]!==undefined){settings[key]=rendererSettings[key];}});}return settings;};canvasRenderer.appendTo=element=>{if(!el){el=element.ownerDocument.createElement('canvas');el.style.position='absolute';el.style['-webkit-font-smoothing']='antialiased';el.style['-moz-osx-font-smoothing']='antialiased';el.style.pointerEvents='none';}if(typeof settings.transform==='function'&&!buffer){buffer=new CanvasBuffer(el);}element.appendChild(el);return el;};canvasRenderer.getScene=shapes=>{const g=buffer&&buffer.getContext()||el.getContext('2d');const dpiRatio=dpiScale(g);const scaleX=rect.scaleRatio.x;const scaleY=rect.scaleRatio.y;const sceneContainer={type:'container',children:shapes,transform:rect.edgeBleed.bool?"translate(".concat(rect.edgeBleed.left*dpiRatio*scaleX,", ").concat(rect.edgeBleed.top*dpiRatio*scaleY,")"):''};if(dpiRatio!==1||scaleX!==1||scaleY!==1){sceneContainer.transform+="scale(".concat(dpiRatio*scaleX,", ").concat(dpiRatio*scaleY,")");}return sceneFn({items:[sceneContainer],dpi:dpiRatio,on:{create:[onLineBreak(canvasRenderer.measureText),injectTextBoundsFn(canvasRenderer)]}});};canvasRenderer.render=shapes=>{if(!el){return false;}if(!patterns){patterns=patternizer$1(el.ownerDocument);}const g=buffer&&buffer.getContext()||el.getContext('2d');const dpiRatio=dpiScale(g);const transform=buffer&&settings.transform();if(transform){// clear canvas
	el.width=el.width;// eslint-disable-line
	applyTransform({el,dpiRatio,transform});buffer.apply();return true;}if(hasChangedRect){el.style.left="".concat(rect.computedPhysical.x,"px");el.style.top="".concat(rect.computedPhysical.y,"px");el.style.width="".concat(rect.computedPhysical.width,"px");el.style.height="".concat(rect.computedPhysical.height,"px");el.width=Math.round(rect.computedPhysical.width*dpiRatio);el.height=Math.round(rect.computedPhysical.height*dpiRatio);if(buffer){buffer.updateSize({rect,dpiRatio,canvasBufferSize:settings.canvasBufferSize});}}const newScene=canvasRenderer.getScene(shapes);const hasChangedScene=scene$1?!newScene.equals(scene$1):true;patterns.clear();const doRender=hasChangedRect||hasChangedScene;const progressive=typeof settings.progressive==='function'&&settings.progressive();if(doRender){if(!progressive||progressive.isFirst){canvasRenderer.clear();}renderShapes(newScene.children,g,shapeToCanvasMap,{patterns});}if(buffer){// clear canvas
	el.width=el.width;// eslint-disable-line
	buffer.apply();}hasChangedRect=false;if(progressive&&!progressive.isFirst){newScene.children.unshift(...scene$1.children);}scene$1=newScene;return doRender;};canvasRenderer.itemsAt=input=>scene$1?scene$1.getItemsFrom(input):[];canvasRenderer.findShapes=selector=>scene$1?scene$1.findShapes(selector):[];canvasRenderer.clear=()=>{if(el){el.width=el.width;// eslint-disable-line
	}if(buffer){buffer.clear();}scene$1=null;return canvasRenderer;};canvasRenderer.size=opts=>{if(opts){const newRect=createRendererBox(opts);if(JSON.stringify(rect)!==JSON.stringify(newRect)){hasChangedRect=true;rect=newRect;}}return rect;};canvasRenderer.destroy=()=>{if(el){if(el.parentElement){el.parentElement.removeChild(el);}el=null;}if(buffer){buffer=null;}scene$1=null;};return canvasRenderer;}function register(type,renderFn){reg.add(type,renderFn);}function clampRadius(max,value){return Math.max(0,Math.min(max,value));}/**
	 * Implementation details follow rx/ry restrictions from https://svgwg.org/svg2-draft/geometry.html#RX
	 *
	 * Using Quadratic Bézier curve it's not possible accurately represent a circle or ellipse but should for the case of a rounded rectangle be sufficent.
	 * @private
	 */function quadraticRoundedRect(g,x,y,width,height,rx,ry){rx=clampRadius(width/2,rx>0?rx:ry);ry=clampRadius(height/2,ry>0?ry:rx);g.moveTo(x,y+ry);g.lineTo(x,y+height-ry);g.quadraticCurveTo(x,y+height,x+rx,y+height);g.lineTo(x+width-rx,y+height);g.quadraticCurveTo(x+width,y+height,x+width,y+height-ry);g.lineTo(x+width,y+ry);g.quadraticCurveTo(x+width,y,x+width-rx,y);g.lineTo(x+rx,y);g.quadraticCurveTo(x,y,x,y+ry);}function render$4(rect,_ref){let{g,doFill,doStroke}=_ref;g.beginPath();if(rect.rx>0||rect.ry>0){quadraticRoundedRect(g,rect.x,rect.y,rect.width,rect.height,rect.rx,rect.ry);}else {g.rect(rect.x,rect.y,rect.width,rect.height);}if(doFill){g.fill();}if(doStroke){g.stroke();}}function render$3(circle,_ref){let{g,doFill,doStroke}=_ref;g.beginPath();g.moveTo(circle.cx+circle.r,circle.cy);g.arc(circle.cx,circle.cy,circle.r,0,Math.PI*2,false);if(doFill){g.fill();}if(doStroke){g.stroke();}}function render$2(line,_ref){let{g,doStroke}=_ref;g.beginPath();g.moveTo(line.x1,line.y1);g.lineTo(line.x2,line.y2);if(doStroke){g.stroke();}}/* eslint no-misleading-character-class: 0 */// Source: https://en.wikipedia.org/wiki/Bi-directional_text and http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt
	// 3 types of strong direction characters: L (strong left-to-right), R(strong right-to-left, Hebrew) and AL(strong right-to-left, Arabic language)
	const rangesOfLChars$1='[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u02BB-\u02C1\u02D0-\u02D1\u02E0-\u02E4\u02EE\u0370-\u0373\u0376-\u037D\u0386\u0388-\u03F5\u03F7-\u0482\u048A-\u0589\u0903-\u0939\u093B\u093D-\u0940\u0949-\u094C\u094E-\u0950\u0958-\u0961\u0964-\u097F\u0982-\u09B9\u09BD-\u09C0\u09C7-\u09CC\u09CE-\u09E1\u09E6-\u09F1\u09F4-\u09FA\u0A03-\u0A39\u0A3E-\u0A40\u0A59-\u0A6F\u0A72-\u0A74\u0A83-\u0AB9\u0ABD-\u0AC0\u0AC9-\u0ACC\u0AD0-\u0AE1\u0AE6-\u0AEF\u0B02-\u0B39\u0B3D-\u0B3E\u0B40\u0B47-\u0B4C\u0B57-\u0B61\u0B66-\u0B77\u0B83-\u0BBF\u0BC1-\u0BCC\u0BD0-\u0BF2\u0C01-\u0C3D\u0C41-\u0C44\u0C58-\u0C61\u0C66-\u0C6F\u0C7F-\u0CB9\u0CBD-\u0CCB\u0CD5-\u0CE1\u0CE6-\u0D40\u0D46-\u0D4C\u0D4E-\u0D61\u0D66-\u0DC6\u0DCF-\u0DD1\u0DD8-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E4F-\u0EB0\u0EB2-\u0EB3\u0EBD-\u0EC6\u0ED0-\u0F17\u0F1A-\u0F34\u0F36\u0F38\u0F3E-\u0F6C\u0F7F\u0F85\u0F88-\u0F8C\u0FBE-\u0FC5\u0FC7-\u102C\u1031\u1038\u103B-\u103C\u103F-\u1057\u105A-\u105D\u1061-\u1070\u1075-\u1081\u1083-\u1084\u1087-\u108C\u108E-\u109C\u109E-\u135A\u1360-\u138F\u13A0-\u13F4\u1401-\u167F\u1681-\u169A\u16A0-\u1711\u1720-\u1731\u1735-\u1751\u1760-\u1770\u1780-\u17B6\u17BE-\u17C5\u17C7-\u17C8\u17D4-\u17DA\u17DC\u17E0-\u17E9\u1810-\u18A8\u18AA-\u191C\u1923-\u1926\u1929-\u1931\u1933-\u1938\u1946-\u19DA\u1A00-\u1A16\u1A19-\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1A80-\u1AAD\u1B04-\u1B33\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B6A\u1B74-\u1B7C\u1B82-\u1BA1\u1BA6-\u1BA7\u1BAA-\u1BE5\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1C2B\u1C34-\u1C35\u1C3B-\u1C7F\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1DBF\u1E00-\u1FBC\u1FBE\u1FC2-\u1FCC\u1FD0-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FFC\u200E\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E-\u214F\u2160-\u2188\u2336-\u237A\u2395\u249C-\u24E9\u26AC\u2800-\u28FF\u2C00-\u2CE4\u2CEB-\u2CEE\u2D00-\u2D70\u2D80-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u31BA\u31F0-\u321C\u3220-\u324F\u3260-\u327B\u327F-\u32B0\u32C0-\u32CB\u32D0-\u3376\u337B-\u33DD\u33E0-\u33FE\u3400-\u4DB5\u4E00-\uA48C\uA4D0-\uA60C\uA610-\uA66E\uA680-\uA6EF\uA6F2-\uA6F7\uA722-\uA787\uA789-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA824\uA827\uA830-\uA837\uA840-\uA873\uA880-\uA8C3\uA8CE-\uA8D9\uA8F2-\uA925\uA92E-\uA946\uA952-\uA97C\uA983-\uA9B2\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uAA28\uAA2F-\uAA30\uAA33-\uAA34\uAA40-\uAA42\uAA44-\uAA4B\uAA4D-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2-\uABE4\uABE6-\uABE7\uABE9-\uABEC\uABF0-\uFB17\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]';const rangesOfRChars$1='[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05F4\u07C0-\u07EA\u07F4-\u07F5\u07FA-\u0815\u081A\u0824\u0828\u0830-\u0858\u085E\u200F\uFB1D\uFB1F-\uFB28\uFB2A-\uFB4F]';const rangesOfALChars$1='[\u0608\u060B\u060D\u061B-\u064A\u066D-\u066F\u0671-\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u070D\u0710\u0712-\u072F\u074D-\u07A5\u07B1\uFB50-\uFD3D\uFD50-\uFDFC\uFE70-\uFEFC]';// let rangesOfNChars = '[\u0009-\u000D\u001C-\u0022\u0026-\u002A\u003B-\u0040\u005B-\u0060\u007B-\u007E\u0085\u00A1\u00A6-\u00A9\u00AB-\u00AC\u00AE-\u00AF\u00B4\u00B6-\u00B8\u00BB-\u00BF\u00D7\u00F7\u02B9-\u02BA\u02C2-\u02CF\u02D2-\u02DF\u02E5-\u02ED\u02EF-\u02FF\u0374-\u0375\u037E-\u0385\u0387\u03F6\u058A\u0606-\u0607\u060E-\u060F\u06DE\u06E9\u07F6-\u07F9\u0BF3-\u0BF8\u0BFA\u0C78-\u0C7E\u0F3A-\u0F3D\u1390-\u1399\u1400\u1680\u169B-\u169C\u17F0-\u180A\u180E\u1940-\u1945\u19DE-\u19FF\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD-\u200A\u2010-\u2029\u2035-\u2043\u2045-\u205F\u207C-\u207E\u208C-\u208E\u2100-\u2101\u2103-\u2106\u2108-\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u213A-\u213B\u2140-\u2144\u214A-\u214D\u2150-\u215F\u2189-\u2211\u2214-\u2335\u237B-\u2394\u2396-\u2487\u24EA-\u26AB\u26AD-\u27FF\u2900-\u2B59\u2CE5-\u2CEA\u2CF9-\u2CFF\u2E00-\u3004\u3008-\u3020\u3030\u3036-\u3037\u303D-\u303F\u309B-\u309C\u30A0\u30FB\u31C0-\u31E3\u321D-\u321E\u3250-\u325F\u327C-\u327E\u32B1-\u32BF\u32CC-\u32CF\u3377-\u337A\u33DE-\u33DF\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA60D-\uA60F\uA673\uA67E-\uA67F\uA700-\uA721\uA788\uA828-\uA82B\uA874-\uA877\uFD3E-\uFD3F\uFDFD\uFE10-\uFE19\uFE30-\uFE4F\uFE51\uFE54\uFE56-\uFE5E\uFE60-\uFE61\uFE64-\uFE68\uFE6B\uFF01-\uFF02\uFF06-\uFF0A\uFF1B-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFFE2-\uFFE4\uFFE8-\uFFFD]';
	const rangesOfLRgExp$1=new RegExp(rangesOfLChars$1);const rangesOfRRgExp$1=new RegExp(rangesOfRChars$1);const rangesOfALRgExp$1=new RegExp(rangesOfALChars$1);// let rangesOfNRgExp = new RegExp(rangesOfNChars);
	// let lrm = String.fromCharCode(8206); // left-to-right marker
	// let rlm = String.fromCharCode(8207); // right-to-left marker
	function isLtrChar$1(c){return rangesOfLRgExp$1.test(c);}function isRtlChar$1(c){return rangesOfRRgExp$1.test(c)||rangesOfALRgExp$1.test(c);}function detectTextDirection$1(s){let n=s?s.length:0,i,c;for(i=0;i<n;i++){c=s[i];if(isLtrChar$1(c)){return 'ltr';}if(isRtlChar$1(c)){return 'rtl';}}return 'ltr';}const textAnchorRTLMap={start:'end',end:'start',center:'center',middle:'middle'};/* let flippedTextAnchor = true;
	let detected = false;
	export function detectRtlSvgSupport(ns, ownerDoc) {
	  if (!detected) {
	    const body = ownerDoc.body;
	    if (body) {
	      const rtlTestSVG = ownerDoc.createElementNS(ns, 'svg');
	      const textNode = ownerDoc.createElementNS(ns, 'text');
	      const group = ownerDoc.createElementNS(ns, 'g');

	      rtlTestSVG.setAttribute('xmlns', ns);
	      rtlTestSVG.setAttribute('style', 'position: absolute; width: 100px; height: 100px; top: -100px; left: 0px');

	      textNode.setAttribute('text-anchor', 'start');
	      textNode.setAttribute('direction', 'rtl');
	      textNode.setAttribute('font-size', '14px');
	      textNode.setAttribute('x', 50);
	      textNode.setAttribute('y', 50);
	      textNode.textContent = 'ثعبان';

	      group.appendChild(textNode);
	      rtlTestSVG.appendChild(group);
	      body.appendChild(rtlTestSVG);

	      flippedTextAnchor = textNode.getBoundingClientRect().left < 50;
	      body.removeChild(rtlTestSVG);
	    }
	  }
	  detected = true;
	} */function flipTextAnchor(value,dir){if(dir==='rtl'){return textAnchorRTLMap[value];}return value;}function render$1(t,_ref){let{g,ellipsed,doStroke}=_ref;const text=ellipsed||ellipsText(t,measureText);g.font=[t['font-style'],t['font-weight'],t['font-size'],t['font-family']].filter(v=>!!v).join(' ');const dir=detectTextDirection$1(t.text);if(g.canvas.dir!==dir){g.canvas.dir=dir;}const textAnchor=t['text-anchor']==='middle'?'center':t['text-anchor'];const textAlign=flipTextAnchor(textAnchor,g.canvas.dir);if(textAlign&&g.textAlign!==textAlign){g.textAlign=textAlign;}const bdy=baselineHeuristic(t);g.fillText(text,t.x+t.dx,t.y+t.dy+bdy);if(doStroke){g.strokeText(text,t.x+t.dx,t.y+t.dy+bdy);}}function render$d(path,_ref){let{g,doStroke,doFill}=_ref;const p=new Path2D(path.d);if(doFill){g.fill(p);}if(doStroke){g.stroke(p);}}register('rect',render$4);register('circle',render$3);register('line',render$2);register('path',render$d);register('text',render$1);function rendererComponent$2(picasso){picasso.renderer('canvas',renderer$2);}function diff(from,to){const added=[];let items;const removed=[];const updatedNew=[];const updatedOld=[];let fromIds;let toIds;const idMapper=a=>a.id;const nodeMapper=(node,i)=>{let id;if(typeof node==='object'){if('id'in node){id=node.id;}else {id=i;}}else {id=node;}return {content:node,id:"".concat(id,"__").concat(node.type||'')};};if(!from.isTree){from=from.map(nodeMapper);}to=to.map(nodeMapper);fromIds=from.map(idMapper);toIds=to.map(idMapper);// TODO - handle duplicate values
	// added = to.filter( v => fromIds.indexOf( v.id ) < 0 );
	// updatedNew = to.filter( v => fromIds.indexOf( v.id ) >= 0 );
	// removed = from.filter( v => toIds.indexOf( v.id ) < 0 );
	// updatedOld = from.filter( v => toIds.indexOf( v.id ) >= 0 );
	for(let i=0,len=to.length;i<len;i++){const idx=fromIds.indexOf(to[i].id);if(idx===-1){added.push(to[i]);}else {updatedNew.push(to[i]);}}for(let i=0,len=from.length;i<len;i++){const idx=toIds.indexOf(from[i].id);if(idx===-1){removed.push(from[i]);}else {updatedOld.push(from[i]);}}for(let i=0,len=added.length;i<len;i++){if(added[i].content.children){added[i].diff=diff([],added[i].content.children);added[i].children=added[i].diff.updatedNew.concat(added[i].diff.added);added[i].children.isTree=true;}}for(let i=0,len=updatedNew.length;i<len;i++){updatedNew[i].diff=diff(updatedOld[i].children||[],updatedNew[i].content.children||[]);updatedNew[i].object=updatedOld[i].object;updatedNew[i].children=updatedNew[i].diff.items;}items=updatedNew.concat(added);added.isTree=true;removed.isTree=true;updatedNew.isTree=true;updatedOld.isTree=true;items.isTree=true;return {added,updatedNew,updatedOld,removed,items};}function createNodes(nodes,parent,create){for(let i=0,len=nodes.length;i<len;i++){nodes[i].object=create(nodes[i].content.type,parent);}}function destroyNodes(nodes,destroy){for(let i=0,len=nodes.length;i<len;i++){if(nodes[i].object!==null&&typeof nodes[i].object!=='undefined'){destroy(nodes[i].object);nodes[i].object=null;}}}function updateNodes(nodes,creator,maintainer,destroyer){let item;for(let i=0,len=nodes.length;i<len;i++){item=nodes[i];if(item.object!==null&&typeof item.object!=='undefined'){maintainer(item.object,item.content);if(item.diff){createNodes(item.diff.added,item.object,creator);destroyNodes(item.diff.removed,destroyer);updateNodes(item.diff.items,creator,maintainer,destroyer);}}}}function createTree(oldItems,newItems,root,creator,maintainer,destroyer){const d=diff(oldItems,newItems);createNodes(d.added,root,creator);destroyNodes(d.removed,destroyer);updateNodes(d.items,creator,maintainer,destroyer);return d.items;}const svgNs='http://www.w3.org/2000/svg';// const badValues = ['', NaN, 'NaN', undefined, null, false, true];
	const creator=(type,parent)=>{if(!type||typeof type!=='string'){throw new Error("Invalid type: ".concat(type));}const el=parent.ownerDocument.createElementNS(svgNs,type==='container'?'g':type);parent.appendChild(el);return el;};const destroyer=el=>{if(el.parentNode){el.parentNode.removeChild(el);}};// isValid - is a way to bring a more consistent rendering behaviour between SVG and canvas.
	// Where SVG would treat NaN values as 0, canvas would simple not render anything.
	const isValid$1=item=>{switch(item.type){case 'circle':return !isNaN(item.attrs.cx)&&!isNaN(item.attrs.cy)&&!isNaN(item.attrs.r);case 'line':return !isNaN(item.attrs.x1)&&!isNaN(item.attrs.y1)&&!isNaN(item.attrs.x2)&&!isNaN(item.attrs.y2);case 'rect':return !isNaN(item.attrs.x)&&!isNaN(item.attrs.y)&&!isNaN(item.attrs.width)&&!isNaN(item.attrs.height);case 'text':return !isNaN(item.attrs.x)&&!isNaN(item.attrs.y);default:return true;}};const maintainer=(element,item)=>{if(isValid$1(item)){for(const attr in item.attrs){if(attr==='stroke'&&item.strokeReference){element.setAttribute('stroke',item.strokeReference);}else if(attr==='fill'&&item.fillReference){element.setAttribute('fill',item.fillReference);}else if(attr==='text'){element.setAttribute('style','white-space: pre');element.textContent=item.ellipsed||ellipsText(item.attrs,measureText);const dir=detectTextDirection$1(item.attrs.text);if(dir==='rtl'){element.setAttribute('direction','rtl');element.setAttribute('dir','rtl');element.setAttribute('text-anchor',flipTextAnchor(element.getAttribute('text-anchor'),dir));}}else if(item.type==='text'&&(attr==='dy'||attr==='dominant-baseline')){const dy=+element.getAttribute(attr)||0;let val=0;if(attr==='dominant-baseline'){val=baselineHeuristic(item.attrs);}else {val=item.attrs[attr];}element.setAttribute('dy',val+dy);}else if(item.type==='text'&&attr==='title'&&item.attrs.title){const t=element.ownerDocument.createElementNS(svgNs,'title');t.textContent=item.attrs.title;element.appendChild(t);}else {element.setAttribute(attr,item.attrs[attr]);}}if(typeof item.data==='string'||typeof item.data==='number'||typeof item.data==='boolean'){element.setAttribute('data',item.data);}else if(typeof item.data==='object'&&item.data!==null){for(const d in item.data){if(typeof item.data[d]==='string'||typeof item.data[d]==='number'||typeof item.data[d]==='boolean'){element.setAttribute("data-".concat(d),item.data[d]);}}}}};class TreeItemRenderer{/**
	   * Constructor
	   * @private
	   * @param  {TreeCreator} treeCreator - Function used to create the DOM tree..
	   * @param  {SVGCreator} nodeCreator - Function used to create nodes.
	   * @param  {SVGMaintainer} nodeMaintainer - Function used to update nodes.
	   * @param  {SVGDestroyer} nodeDestroyer - Function used to destroy nodes.
	   */constructor(treeCreator,nodeCreator,nodeMaintainer,nodeDestroyer){this.create=treeCreator;this.nodeCreator=nodeCreator;this.nodeMaintainer=nodeMaintainer;this.nodeDestroyer=nodeDestroyer;}render(newItems,root){return this.create([],newItems,root,this.nodeCreator,this.nodeMaintainer,this.nodeDestroyer);}}function tree(){return new TreeItemRenderer(createTree,creator,maintainer,destroyer);}/**
	 * Create an SVGElement and attach to parent.
	 * @private
	 * @callback SVGCreator
	 * @param {String} type - The type of element to create.
	 * @param {SVGElement} parent - The parent element to append the new element to.
	 * @return {SVGElement} The created element
	 *//**
	 * Update the element with content from item.
	 * @private
	 * @callback SVGMaintainer
	 * @param {SVGElement} el - The element to update
	 * @param {Object} item - The object to use as input for the update
	 *//**
	 * Detach element from its parent.
	 * @private
	 * @callback SVGDestroyer
	 * @param {SVGElement} el - Element to destroy.
	 *//**
	 * Create, update and destroy nodes.
	 * @private
	 * @callback TreeCreator
	 * @param {Object[]} existing - The existing items in the tree.
	 * @param {Object[]} active - The new items to create the tree from.
	 * @param {SVGCreator} creator - Function used to create nodes.
	 * @param {SVGMaintainer} maintainer - Function used to update nodes.
	 * @param {SVGDestroyer} destroyer - Function used to destroy nodes.
	 *//* eslint import/prefer-default-export: 0 *//**
	 * Hash an object
	 * Modified version of Java's HashCode function
	 * Source: {@link http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/}
	 * @ignore
	 *
	 * @param  {Object} item Item to hash
	 * @return {String}      Unique hash id
	 */function hashObject(item){let hash=0;let i;let chr;let len;item=JSON.stringify(item);if(item.length===0){return hash;}for(i=0,len=item.length;i<len;i++){chr=item.charCodeAt(i);hash=(hash<<5)-hash+chr;hash&=hash;// Convert to 32bit integer
	}return hash;}function gradienter(bucket){let hasher=arguments.length>1&&arguments[1]!==undefined?arguments[1]:hashObject;let cache={};let uid=Date.now();const p={getOrCreateGradient(){let item=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let attr=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'fill';let url=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'';let gradientHash=hasher(item[attr]);let gradientId="picasso-gradient-".concat(uid,"-").concat(gradientHash);if(!cache[gradientHash]){let{orientation,degree,stops=[]}=item[attr];let gradient={};if(degree===undefined){degree=90;}// Default to linear
	if(orientation==='radial'){gradient.type='radialGradient';}else {gradient=degreesToPoints(degree);['x1','x2','y1','y2'].forEach(c=>{if(c in item[attr]){gradient[c]=item[attr][c];}});gradient.type='linearGradient';}gradient.id=gradientId;gradient.children=stops.map(_ref=>{let{offset,color,opacity}=_ref;return {type:'stop',offset:"".concat(offset*100,"%"),style:"stop-color:".concat(color,";stop-opacity:").concat(typeof opacity!=='undefined'?opacity:1)};});bucket.push(gradient);cache[gradientHash]=gradientId;}return "url('".concat(url,"#").concat(gradientId,"')");},onCreate(state){let url='';if(typeof window!=='undefined'){url=window.location.href.split('#')[0];}const item=state.node;if(item.fill&&typeof item.fill==='object'&&item.fill.type==='gradient'){item.fillReference=p.getOrCreateGradient(item,'fill',url);}if(item.stroke&&typeof item.stroke==='object'&&item.stroke.type==='gradient'){item.strokeReference=p.getOrCreateGradient(item,'stroke',url);}},clear(){cache={};}};return p;}function patternizer(bucket){let hasher=arguments.length>1&&arguments[1]!==undefined?arguments[1]:hashObject;let cache={};let uid=Date.now();const p={onCreate(state){let inputs={};if(state.node&&typeof state.node.fill==='object'&&state.node.fill.type==='pattern'&&state.node.fill.shapes){inputs.fill=state.node.fill;}if(state.node&&typeof state.node.stroke==='object'&&state.node.stroke.type==='pattern'&&state.node.stroke.shapes){inputs.stroke=state.node.stroke;}Object.keys(inputs).forEach(key=>{let url='';const input=inputs[key];const patternHash=hasher(input);const pnid="picasso-pattern-".concat(uid,"-").concat(patternHash);if(typeof window!=='undefined'){url=window.location.href.split('#')[0];}if(!cache[patternHash]){const pn={patternUnits:'userSpaceOnUse',x:0,y:0,width:input.width,height:input.height,type:'pattern',id:pnid,children:[],fill:input.fill};input.shapes.forEach(s=>{pn.children.push(s);});bucket.push(pn);cache[patternHash]=true;}state.node["".concat(key,"Reference")]="url('".concat(url,"#").concat(pnid,"')");});},clear(){cache={};}};return p;}/**
	 * Create a new svg renderer
	 * @typedef {function} svgRendererFactory
	 * @param {function} [treeFactory] - Node tree factory
	 * @param {string} [ns] - Namespace definition
	 * @param {function} [sceneFn] - Scene factory
	 * @returns {Renderer} A svg renderer instance
	 */function renderer$1(){let treeFn=arguments.length>0&&arguments[0]!==undefined?arguments[0]:tree;let ns=arguments.length>1&&arguments[1]!==undefined?arguments[1]:svgNs;let sceneFn=arguments.length>2&&arguments[2]!==undefined?arguments[2]:scene;const tree$1=treeFn();let el;let group;let hasChangedRect=false;let rect=createRendererBox();let scene$1;const settings={transform:undefined,disableScreenReader:false};const svg=create();const defs={type:'defs',children:[]};const patterns=patternizer(defs.children);const gradients=gradienter(defs.children);svg.element=()=>el;svg.root=()=>group;svg.settings=rendererSettings=>{if(rendererSettings){Object.keys(settings).forEach(key=>{if(rendererSettings[key]!==undefined){settings[key]=rendererSettings[key];}});}return settings;};svg.appendTo=element=>{if(!el){el=element.ownerDocument.createElementNS(ns,'svg');el.style.position='absolute';el.style['-webkit-font-smoothing']='antialiased';el.style['-moz-osx-font-smoothing']='antialiased';el.style.pointerEvents='none';el.setAttribute('xmlns',ns);group=element.ownerDocument.createElementNS(ns,'g');group.style.pointerEvents='auto';el.appendChild(group);}element.appendChild(el);return el;};svg.getScene=nodes=>{const scaleX=rect.scaleRatio.x;const scaleY=rect.scaleRatio.y;const sceneContainer={type:'container',children:Array.isArray(nodes)?[...nodes,defs]:nodes,transform:rect.edgeBleed.bool?"translate(".concat(rect.edgeBleed.left*scaleX,", ").concat(rect.edgeBleed.top*scaleY,")"):''};if(scaleX!==1||scaleY!==1){sceneContainer.transform+="scale(".concat(scaleX,", ").concat(scaleY,")");}return sceneFn({items:[sceneContainer],on:{create:[state=>{state.node.fillReference=undefined;state.node.strokeReference=undefined;},gradients.onCreate,patterns.onCreate,onLineBreak(svg.measureText),injectTextBoundsFn(svg)]}});};svg.render=nodes=>{if(!el){return false;}const transformation=typeof settings.transform==='function'&&settings.transform();if(transformation){const{horizontalScaling,horizontalSkewing,verticalSkewing,verticalScaling,horizontalMoving,verticalMoving}=transformation;group.style.transform="matrix(".concat(horizontalScaling,", ").concat(horizontalSkewing,", ").concat(verticalSkewing,", ").concat(verticalScaling,", ").concat(horizontalMoving,", ").concat(verticalMoving,")");return true;}group.style.transform='';const disableScreenReader=settings.disableScreenReader;if(disableScreenReader){el.setAttribute('aria-hidden',true);}if(hasChangedRect){el.style.left="".concat(rect.computedPhysical.x,"px");el.style.top="".concat(rect.computedPhysical.y,"px");el.setAttribute('width',rect.computedPhysical.width);el.setAttribute('height',rect.computedPhysical.height);}gradients.clear();patterns.clear();defs.children.length=0;const newScene=svg.getScene(nodes);const hasChangedScene=scene$1?!newScene.equals(scene$1):true;const doRender=hasChangedRect||hasChangedScene;if(doRender){svg.clear();tree$1.render(newScene.children,group);}hasChangedRect=false;scene$1=newScene;return doRender;};svg.itemsAt=input=>scene$1?scene$1.getItemsFrom(input):[];svg.findShapes=selector=>scene$1?scene$1.findShapes(selector):[];svg.clear=()=>{if(!group){return svg;}scene$1=null;const g=group.cloneNode(false);el.replaceChild(g,group);group=g;return svg;};svg.destroy=()=>{// parentElement is not supported in IE11 for SVGElement.
	if(el&&el.parentNode){el.parentNode.removeChild(el);}el=null;group=null;};svg.size=opts=>{if(opts){const newRect=createRendererBox(opts);if(JSON.stringify(rect)!==JSON.stringify(newRect)){hasChangedRect=true;rect=newRect;}}return rect;};return svg;}function rendererComponent$1(picasso){picasso.renderer('svg',renderer$1);}var n,l,u,t,r,o,f,c={},s=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function h(n,l){for(var u in l)n[u]=l[u];return n;}function v(n){var l=n.parentNode;l&&l.removeChild(n);}function y(l,u,i){var t,r,o,f={};for(o in u)"key"==o?t=u[o]:"ref"==o?r=u[o]:f[o]=u[o];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),"function"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps) void 0===f[o]&&(f[o]=l.defaultProps[o]);return p$1(l,f,t,r,null);}function p$1(n,i,t,r,o){var f={type:n,props:i,key:t,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++u:o};return null==o&&null!=l.vnode&&l.vnode(f),f;}function _$1(n){return n.children;}function k(n,l){this.props=n,this.context=l;}function b(n,l){if(null==l)return n.__?b(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?b(n):null;}function g(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break;}return g(n);}}function m(n){(!n.__d&&(n.__d=true)&&t.push(n)&&!w$1.__r++||r!==l.debounceRendering)&&((r=l.debounceRendering)||o)(w$1);}function w$1(){var n,l,u,i,r,o,e,c;for(t.sort(f);n=t.shift();)n.__d&&(l=t.length,i=void 0,r=void 0,e=(o=(u=n).__v).__e,(c=u.__P)&&(i=[],(r=h({},o)).__v=o.__v+1,L(c,o,r,u.__n,void 0!==c.ownerSVGElement,null!=o.__h?[e]:null,i,null==e?b(o):e,o.__h),M$1(i,o),o.__e!=e&&g(o)),t.length>l&&t.sort(f));w$1.__r=0;}function x(n,l,u,i,t,r,o,f,e,a){var h,v,y,d,k,g,m,w=i&&i.__k||s,x=w.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(d=u.__k[h]=null==(d=l[h])||"boolean"==typeof d||"function"==typeof d?null:"string"==typeof d||"number"==typeof d||"bigint"==typeof d?p$1(null,d,null,null,d):Array.isArray(d)?p$1(_$1,{children:d},null,null,null):d.__b>0?p$1(d.type,d.props,d.key,d.ref?d.ref:null,d.__v):d)){if(d.__=u,d.__b=u.__b+1,null===(y=w[h])||y&&d.key==y.key&&d.type===y.type)w[h]=void 0;else for(v=0;v<x;v++){if((y=w[v])&&d.key==y.key&&d.type===y.type){w[v]=void 0;break;}y=null;}L(n,d,y=y||c,t,r,o,f,e,a),k=d.__e,(v=d.ref)&&y.ref!=v&&(m||(m=[]),y.ref&&m.push(y.ref,null,d),m.push(v,d.__c||k,d)),null!=k?(null==g&&(g=k),"function"==typeof d.type&&d.__k===y.__k?d.__d=e=A(d,e,n):e=C(n,d,y,w,k,e),"function"==typeof u.type&&(u.__d=e)):e&&y.__e==e&&e.parentNode!=n&&(e=b(y));}for(u.__e=g,h=x;h--;)null!=w[h]&&("function"==typeof u.type&&null!=w[h].__e&&w[h].__e==u.__d&&(u.__d=$$1(i).nextSibling),S(w[h],w[h]));if(m)for(h=0;h<m.length;h++)O(m[h],m[++h],m[++h]);}function A(n,l,u){for(var i,t=n.__k,r=0;t&&r<t.length;r++)(i=t[r])&&(i.__=n,l="function"==typeof i.type?A(i,l,u):C(u,i,i,t,i.__e,l));return l;}function C(n,l,u,i,t,r){var o,f,e;if(void 0!==l.__d)o=l.__d,l.__d=void 0;else if(null==u||t!=r||null==t.parentNode)n:if(null==r||r.parentNode!==n)n.appendChild(t),o=null;else {for(f=r,e=0;(f=f.nextSibling)&&e<i.length;e+=1)if(f==t)break n;n.insertBefore(t,r),o=r;}return void 0!==o?o:t.nextSibling;}function $$1(n){var l,u,i;if(null==n.type||"string"==typeof n.type)return n.__e;if(n.__k)for(l=n.__k.length-1;l>=0;l--)if((u=n.__k[l])&&(i=$$1(u)))return i;return null;}function H$1(n,l,u,i,t){var r;for(r in u)"children"===r||"key"===r||r in l||T(n,r,null,u[r],i);for(r in l)t&&"function"!=typeof l[r]||"children"===r||"key"===r||"value"===r||"checked"===r||u[r]===l[r]||T(n,r,l[r],u[r],i);}function I(n,l,u){"-"===l[0]?n.setProperty(l,null==u?"":u):n[l]=null==u?"":"number"!=typeof u||a.test(l)?u:u+"px";}function T(n,l,u,i,t){var r;n:if("style"===l){if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||I(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||I(n.style,l,u[l]);}}else if("o"===l[0]&&"n"===l[1])r=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?i||n.addEventListener(l,r?z$1:j$1,r):n.removeEventListener(l,r?z$1:j$1,r);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==l&&"height"!==l&&"href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n;}catch(n){}"function"==typeof u||(null==u||false===u&&"-"!==l[4]?n.removeAttribute(l):n.setAttribute(l,u));}}function j$1(n){return this.l[n.type+false](l.event?l.event(n):n);}function z$1(n){return this.l[n.type+true](l.event?l.event(n):n);}function L(n,u,i,t,r,o,f,e,c){var s,a,v,y,p,d,b,g,m,w,A,P,C,$,H,I=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,o=[e]),(s=l.__b)&&s(u);try{n:if("function"==typeof I){if(g=u.props,m=(s=I.contextType)&&t[s.__c],w=s?m?m.props.value:s.__:t,i.__c?b=(a=u.__c=i.__c).__=a.__E:("prototype"in I&&I.prototype.render?u.__c=a=new I(g,w):(u.__c=a=new k(g,w),a.constructor=I,a.render=q$1),m&&m.sub(a),a.props=g,a.state||(a.state={}),a.context=w,a.__n=t,v=a.__d=!0,a.__h=[],a._sb=[]),null==a.__s&&(a.__s=a.state),null!=I.getDerivedStateFromProps&&(a.__s==a.state&&(a.__s=h({},a.__s)),h(a.__s,I.getDerivedStateFromProps(g,a.__s))),y=a.props,p=a.state,a.__v=u,v)null==I.getDerivedStateFromProps&&null!=a.componentWillMount&&a.componentWillMount(),null!=a.componentDidMount&&a.__h.push(a.componentDidMount);else {if(null==I.getDerivedStateFromProps&&g!==y&&null!=a.componentWillReceiveProps&&a.componentWillReceiveProps(g,w),!a.__e&&null!=a.shouldComponentUpdate&&!1===a.shouldComponentUpdate(g,a.__s,w)||u.__v===i.__v){for(u.__v!==i.__v&&(a.props=g,a.state=a.__s,a.__d=!1),a.__e=!1,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),A=0;A<a._sb.length;A++)a.__h.push(a._sb[A]);a._sb=[],a.__h.length&&f.push(a);break n;}null!=a.componentWillUpdate&&a.componentWillUpdate(g,a.__s,w),null!=a.componentDidUpdate&&a.__h.push(function(){a.componentDidUpdate(y,p,d);});}if(a.context=w,a.props=g,a.__P=n,P=l.__r,C=0,"prototype"in I&&I.prototype.render){for(a.state=a.__s,a.__d=!1,P&&P(u),s=a.render(a.props,a.state,a.context),$=0;$<a._sb.length;$++)a.__h.push(a._sb[$]);a._sb=[];}else do{a.__d=!1,P&&P(u),s=a.render(a.props,a.state,a.context),a.state=a.__s;}while(a.__d&&++C<25);a.state=a.__s,null!=a.getChildContext&&(t=h(h({},t),a.getChildContext())),v||null==a.getSnapshotBeforeUpdate||(d=a.getSnapshotBeforeUpdate(y,p)),H=null!=s&&s.type===_$1&&null==s.key?s.props.children:s,x(n,Array.isArray(H)?H:[H],u,i,t,r,o,f,e,c),a.base=u.__e,u.__h=null,a.__h.length&&f.push(a),b&&(a.__E=a.__=null),a.__e=!1;}else null==o&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=N$1(i.__e,u,i,t,r,o,f,c);(s=l.diffed)&&s(u);}catch(n){u.__v=null,(c||null!=o)&&(u.__e=e,u.__h=!!c,o[o.indexOf(e)]=null),l.__e(n,u,i);}}function M$1(n,u){l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u);});}catch(n){l.__e(n,u.__v);}});}function N$1(l,u,i,t,r,o,f,e){var s,a,h,y=i.props,p=u.props,d=u.type,_=0;if("svg"===d&&(r=true),null!=o)for(;_<o.length;_++)if((s=o[_])&&"setAttribute"in s==!!d&&(d?s.localName===d:3===s.nodeType)){l=s,o[_]=null;break;}if(null==l){if(null===d)return document.createTextNode(p);l=r?document.createElementNS("http://www.w3.org/2000/svg",d):document.createElement(d,p.is&&p),o=null,e=false;}if(null===d)y===p||e&&l.data===p||(l.data=p);else {if(o=o&&n.call(l.childNodes),a=(y=i.props||c).dangerouslySetInnerHTML,h=p.dangerouslySetInnerHTML,!e){if(null!=o)for(y={},_=0;_<l.attributes.length;_++)y[l.attributes[_].name]=l.attributes[_].value;(h||a)&&(h&&(a&&h.__html==a.__html||h.__html===l.innerHTML)||(l.innerHTML=h&&h.__html||""));}if(H$1(l,p,y,r,e),h)u.__k=[];else if(_=u.props.children,x(l,Array.isArray(_)?_:[_],u,i,t,r&&"foreignObject"!==d,o,f,o?o[0]:i.__k&&b(i,0),e),null!=o)for(_=o.length;_--;)null!=o[_]&&v(o[_]);e||("value"in p&&void 0!==(_=p.value)&&(_!==l.value||"progress"===d&&!_||"option"===d&&_!==y.value)&&T(l,"value",_,y.value,false),"checked"in p&&void 0!==(_=p.checked)&&_!==l.checked&&T(l,"checked",_,y.checked,false));}return l;}function O(n,u,i){try{"function"==typeof n?n(u):n.current=u;}catch(n){l.__e(n,i);}}function S(n,u,i){var t,r;if(l.unmount&&l.unmount(n),(t=n.ref)&&(t.current&&t.current!==n.__e||O(t,null,u)),null!=(t=n.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(n){l.__e(n,u);}t.base=t.__P=null,n.__c=void 0;}if(t=n.__k)for(r=0;r<t.length;r++)t[r]&&S(t[r],u,i||"function"!=typeof n.type);i||null==n.__e||v(n.__e),n.__=n.__e=n.__d=void 0;}function q$1(n,l,u){return this.constructor(n,u);}function B$1(u,i,t){var r,o,f;l.__&&l.__(u,i),o=(r="function"==typeof t)?null:t&&t.__k||i.__k,f=[],L(i,u=(!r&&t||i).__k=y(_$1,null,[u]),o||c,c,void 0!==i.ownerSVGElement,!r&&t?[t]:o?null:i.firstChild?n.call(i.childNodes):null,f,!r&&t?t:o?o.__e:i.firstChild,r),M$1(f,u);}n=s.slice,l={__e:function(n,l,u,i){for(var t,r,o;l=l.__;)if((t=l.__c)&&!t.__)try{if((r=t.constructor)&&null!=r.getDerivedStateFromError&&(t.setState(r.getDerivedStateFromError(n)),o=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),o=t.__d),o)return t.__E=t;}catch(l){n=l;}throw n;}},u=0,k.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=h({},this.state),"function"==typeof n&&(n=n(h({},u),this.props)),n&&h(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),m(this));},k.prototype.forceUpdate=function(n){this.__v&&(this.__e=true,n&&this.__h.push(n),m(this));},k.prototype.render=_$1,t=[],o="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,f=function(n,l){return n.__v.__b-l.__v.__b;},w$1.__r=0;function renderer(){let opts=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};const{createElement=document.createElement.bind(document)}=opts;let el;let rect=createRendererBox();let dNode;const settings={transform:undefined,disableScreenReader:false};const dom=create();dom.element=()=>el;dom.root=()=>el;dom.settings=rendererSettings=>{if(rendererSettings){Object.keys(settings).forEach(key=>{if(rendererSettings[key]!==undefined){settings[key]=rendererSettings[key];}});}return settings;};dom.appendTo=element=>{if(!el){el=createElement('div');el.style.position='absolute';el.style['-webkit-font-smoothing']='antialiased';el.style['-moz-osx-font-smoothing']='antialiased';el.style.pointerEvents='none';}element.appendChild(el);return el;};dom.render=nodes=>{if(!el){return false;}const transformation=typeof settings.transform==='function'&&settings.transform();if(transformation){const{horizontalScaling,horizontalSkewing,verticalSkewing,verticalScaling,horizontalMoving,verticalMoving}=transformation;el.style.transform="matrix(".concat(horizontalScaling,", ").concat(horizontalSkewing,", ").concat(verticalSkewing,", ").concat(verticalScaling,", ").concat(horizontalMoving,", ").concat(verticalMoving,")");return true;}el.style.transform='';const disableScreenReader=settings.disableScreenReader;if(disableScreenReader){el.setAttribute('aria-hidden',true);}el.style.left="".concat(rect.computedPhysical.x,"px");el.style.top="".concat(rect.computedPhysical.y,"px");el.style.width="".concat(rect.computedPhysical.width,"px");el.style.height="".concat(rect.computedPhysical.height,"px");let vNode;if(Array.isArray(nodes)){vNode=y("div",null,nodes);}else {vNode=nodes;}dNode=B$1(vNode,el,dNode);return true;};dom.renderArgs=[y];// Arguments to render functions using the DOM renderer
	dom.clear=()=>{if(el){let first=el.firstChild;while(first){el.removeChild(first);first=el.firstChild;}dNode=null;}return dom;};dom.destroy=()=>{if(el&&el.parentElement){el.parentElement.removeChild(el);}el=null;dNode=null;};dom.size=inner=>{if(inner){rect=createRendererBox(inner);}return rect;};return dom;}function rendererComponent(picasso){picasso.renderer('dom',renderer);}var renderers=[rendererComponent$1,rendererComponent$2,rendererComponent];var scales=[];const LOG_LEVEL={OFF:0,ERROR:1,WARN:2,INFO:3,DEBUG:4};const loggerFn=function(){let{level=LOG_LEVEL.OFF,pipe=console}=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let currentlevel=level;const LOG_FN={[LOG_LEVEL.OFF]:()=>{},[LOG_LEVEL.ERROR]:function(){return pipe.error(...arguments);},[LOG_LEVEL.WARN]:function(){return pipe.warn(...arguments);},[LOG_LEVEL.INFO]:function(){return pipe.info(...arguments);},[LOG_LEVEL.DEBUG]:function(){return pipe.log(...arguments);}};const log=function(lev){if(!lev||currentlevel<lev){return;}for(var _len=arguments.length,args=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key];}(LOG_FN[lev]||LOG_FN[LOG_LEVEL.DEBUG])(...args);};/**
	   * @typedef {object} logger
	   * @private
	   */return/** @lends logger */{/**
	     * Log a message
	     * @param {number} lev - The log level
	     * @param {...any} args
	     * @kind function
	     */log,/**
	     * Log an error message
	     * @param {...any} args
	     */error:function(){for(var _len2=arguments.length,args=new Array(_len2),_key2=0;_key2<_len2;_key2++){args[_key2]=arguments[_key2];}return log(LOG_LEVEL.ERROR,...args);},/**
	     * Log a warning message
	     * @param {...any} args
	     */warn:function(){for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++){args[_key3]=arguments[_key3];}return log(LOG_LEVEL.WARN,...args);},/**
	     * Log an info message
	     * @param {...any} args
	     */info:function(){for(var _len4=arguments.length,args=new Array(_len4),_key4=0;_key4<_len4;_key4++){args[_key4]=arguments[_key4];}return log(LOG_LEVEL.INFO,...args);},/**
	     * Log a debug message
	     * @param {...any} args
	     */debug:function(){for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++){args[_key5]=arguments[_key5];}return log(LOG_LEVEL.DEBUG,...args);},/**
	     * Set the current log level
	     * @param {number} lev - The log level
	     */level:lev=>{if(typeof lev==='number'){currentlevel=lev;}return currentlevel;},LOG_LEVEL};};const palettes=[{key:'categorical',colors:[['#a54343','#d76c6c','#ec983d','#ecc43d','#f9ec86','#cbe989','#70ba6e','#578b60','#79d69f','#26a0a7','#138185','#65d3da']// breeze colors
	]},{key:'diverging',colors:[['#3d52a1','#3a89c9','#77b7e5','#b4ddf7','#e6f5fe','#ffe3aa','#f9bd7e','#ed875e','#d24d3e','#ae1c3e']]},{key:'sequential',colors:[['rgb(180,221,212)','rgb(34, 83, 90)']]}];/* eslint quote-props: 0 */const style={// -- FOUNDATION --
	// fonts
	'$font-family':"'Source Sans Pro', Arial, sans-serif",'$font-size':'12px','$line-height':'16px','$font-size--l':'16px','$font-weight':'normal',// base grays
	'$gray-100':'#ffffff','$gray-98':'#f9f9f9','$gray-95':'#f2f2f2','$gray-90':'#e6e6e6','$gray-35':'#595959','$gray-30':'#4d4d4d','$gray-25':'#404040','$gray-20':'#333333',// borders
	'$border-95':'rgba(255, 255, 255, 0.05)','$border-90':'rgba(255, 255, 255, 0.1)','$border-80':'rgba(255, 255, 255, 0.2)','$border-20':'rgba(0, 0, 0, 0.2)','$border-10':'rgba(0, 0, 0, 0.1)','$border-5':'rgba(0, 0, 0, 0.05)',// primary colors
	'$primary-blue':'#3F8AB3','$primary-green':'#6CB33F','$primary-red':'#DC423F','$primary-orange':'#EF960F',// spacing
	'$spacing--s':4,$spacing:8,'$spacing--l':12,// -------------------------
	// -- ALIASES --
	'$font-color':'$gray-35','$font-color--inverted':'$gray-90','$guide-color':'$gray-90','$guide-color--inverted':'$gray-35',$border:'$border-80','$border--inverted':'$border-10',// -------------------------
	// -- MIXINS --
	// data points
	$shape:{// data shape
	fill:'$primary-blue',strokeWidth:1,stroke:'$border'},'$shape-outline':{// data shape which usually does not have a fill, e.g. the line in a linechart
	stroke:'$primary-blue',strokeWidth:2},'$shape-guide':{// lines that somehow belongs to a data shape, e.g. whiskers in a boxplot
	stroke:'$guide-color',strokeWidth:1},'$shape-guide--inverted':{'@extend':'$shape-guide',stroke:'$guide-color--inverted'},$label:{fontSize:'$font-size',fontFamily:'$font-family',fill:'$font-color'},'$label--inverted':{$extend:'$label',fill:'$font-color--inverted'},// user interface
	'$label-overlay':{// e.g. selection range bubble
	fontSize:'$font-size--l',fontFamily:'$font-family',fill:'$gray-100',// background fill
	color:'$font-color',stroke:'$guide-color--inverted',strokeWidth:1,borderRadius:4},$title:{'@extend':'$label',fontSize:'$font-size--l',fontWeight:'$font-weight',stroke:'$guide-color--inverted',strokeWidth:0},'$guide-line':{strokeWidth:1,stroke:'$guide-color'},'$guide-line--minor':{strokeWidth:1,stroke:'$gray-95'// needs alias
	},'$padding--s':{left:'$spacing--s',right:'$spacing--s',top:'$spacing--s',bottom:'$spacing--s'},$padding:{left:'$spacing',right:'$spacing',top:'$spacing',bottom:'$spacing'},'$selection-area-target':{fill:'$primary-green',strokeWidth:0,opacity:0.2}};function usePlugin(plugin){let options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};let api=arguments.length>2?arguments[2]:undefined;plugin(api,options);}function pic(){let config=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let registries=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};const logger=loggerFn(config.logger);/**
	   * @lends picassojs
	   */const regis={// -- registries --
	/**
	     * Component registry
	     * @type {registry}
	     */component:registryFactory(registries.component,'component',logger),/**
	     * Data registry
	     * @type {registry}
	     */data:registryFactory(registries.data,'data',logger),/**
	     * Formatter registry
	     * @type {registry}
	     */formatter:registryFactory(registries.formatter,'formatter',logger),/**
	     * Interaction registry
	     * @type {registry}
	     */interaction:registryFactory(registries.interaction,'interaction',logger),/**
	     * Renderer registry
	     * @type {registry}
	     * @example
	     * const svgFactory = picassojs.renderer('svg');
	     * const svgRenderer = svgFactory();
	     */renderer:rendererRegistry(registries.renderer),/**
	     * Scale registry
	     * @type {registry}
	     */scale:registryFactory(registries.scale,'scale',logger),/**
	     * Symbol registry
	     * @type {registry}
	     * @private
	     */symbol:registryFactory(registries.symbol,'symbol',logger),// -- misc --
	/**
	     * log some some stuff
	     * @type {logger}
	     * @private
	     */logger};if(config.renderer&&config.renderer.prio){regis.renderer.default(config.renderer.prio[0]);}/**
	   * picasso.js entry point
	   * @entry
	   * @alias picassojs
	   * @param {object=} cfg
	   * @param {object=} cfg.renderer
	   * @param {Array<string>} cfg.renderer.prio
	   * @param {object=} cfg.logger
	   * @param {0|1|2|3|4} cfg.logger.level
	   * @param {object=} cfg.style
	   * @param {Array<object>=} cfg.palettes
	   * @returns {picassojs}
	   * @example
	   * import picasso from 'picasso.js';
	   *
	   * const configuredPicasso = picasso({ renderer: { prio: ['canvas'] } }) // All components will render using the canvas renderer
	   */function picassojs(){let cfg=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};let cc={palettes:config.palettes.concat(cfg.palettes||[]),style:extend$1$1({},config.style,cfg.style),logger:cfg.logger||config.logger,renderer:cfg.renderer||config.renderer};return pic(cc,regis);}/**
	   * @typedef {object} Registries
	   * @property {registry} component Component registry
	   * @property {registry} data Data registry
	   * @property {registry} formatter Formatter registry
	   * @property {registry} interaction Interaction registry
	   * @property {registry} renderer Renderer registry
	   * @property {registry} scale Scale registry
	   *//**
	   * Callback function to register a plugin
	   * @callback plugin
	   * @param {Registries} registries
	   * @param {object} options
	   *//**
	   * Plugin registry
	   * @param {plugin} plugin
	   * @param {object} [options]
	   */picassojs.use=function(plugin){let options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};return usePlugin(plugin,options,regis);};/**
	   * @param {ChartDefinition} definition
	   * @returns {Chart}
	   * @example
	   * picasso.chart({
	    element: document.querySelector('#container'), // This is the element to render the chart in
	    data: [
	      {
	        type: 'matrix',
	        data: [
	          ['Month', 'Sales', 'Margin'],
	          ['Jan', 1106, 7],
	          ['Feb', 5444, 53],
	          ['Mar', 147, 64],
	          ['Apr', 7499, 47],
	          ['May', 430, 62],
	          ['June', 9735, 13],
	          ['July', 5832, 13],
	          ['Aug', 7435, 15],
	          ['Sep', 3467, 35],
	          ['Oct', 3554, 78],
	          ['Nov', 5633, 23],
	          ['Dec', 6354, 63],
	        ],
	      },
	    ],
	    settings: {
	      scales: {
	        x: { data: { field: 'Margin' } },
	        y: { data: { field: 'Sales' } },
	      },
	      components: [
	        {
	          // specify how to render the chart
	          type: 'axis',
	          scale: 'y',
	          layout: {
	            dock: 'left',
	          },
	        },
	        {
	          type: 'axis',
	          scale: 'x',
	          layout: {
	            dock: 'bottom',
	          },
	        },
	        {
	          type: 'point',
	          data: {
	            extract: {
	              field: 'Month',
	              props: {
	                x: { field: 'Margin' },
	                y: { field: 'Sales' },
	              },
	            },
	          },
	          settings: {
	            x: { scale: 'x' },
	            y: { scale: 'y' },
	            size: function () {
	              return Math.random();
	            },
	          },
	        },
	      ],
	    },
	  });
	   */picassojs.chart=definition=>chartFn(definition,{registries:regis,logger,style:config.style,palettes:config.palettes});picassojs.config=()=>config;Object.keys(regis).forEach(key=>{picassojs[key]=regis[key];});/**
	   * picasso.js version
	   * @type {string}
	   */picassojs.version=about.version;return picassojs;}const p=pic({renderer:{prio:['svg','canvas']},logger:{level:0},style,palettes},{component:componentRegistry,data:dataRegistry,formatter:formatterRegistry,interaction:reg$3,renderer:rendererRegistry(),scale:scaleRegistry,symbol:parentReg});components.forEach(p.use);renderers.forEach(p.use);scales.forEach(p.use);

	/*
	* picasso-plugin-q v2.8.2
	* Copyright (c) 2025 QlikTech International AB
	* Released under the MIT license.
	*/

	function _defineProperty(e, r, t) {
	  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
	    value: t,
	    enumerable: true,
	    configurable: true,
	    writable: true
	  }) : e[r] = t, e;
	}
	function ownKeys(e, r) {
	  var t = Object.keys(e);
	  if (Object.getOwnPropertySymbols) {
	    var o = Object.getOwnPropertySymbols(e);
	    r && (o = o.filter(function (r) {
	      return Object.getOwnPropertyDescriptor(e, r).enumerable;
	    })), t.push.apply(t, o);
	  }
	  return t;
	}
	function _objectSpread2(e) {
	  for (var r = 1; r < arguments.length; r++) {
	    var t = null != arguments[r] ? arguments[r] : {};
	    r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
	      _defineProperty(e, r, t[r]);
	    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
	      Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
	    });
	  }
	  return e;
	}
	function _toPrimitive(t, r) {
	  if ("object" != typeof t || !t) return t;
	  var e = t[Symbol.toPrimitive];
	  if (void 0 !== e) {
	    var i = e.call(t, r);
	    if ("object" != typeof i) return i;
	    throw new TypeError("@@toPrimitive must return a primitive value.");
	  }
	  return ("string" === r ? String : Number)(t);
	}
	function _toPropertyKey(t) {
	  var i = _toPrimitive(t, "string");
	  return "symbol" == typeof i ? i : i + "";
	}
	var hasOwn = Object.prototype.hasOwnProperty;
	var toStr = Object.prototype.toString;
	var defineProperty = Object.defineProperty;
	var gOPD = Object.getOwnPropertyDescriptor;
	var isArray$1 = function isArray(arr) {
	  if (typeof Array.isArray === 'function') {
	    return Array.isArray(arr);
	  }
	  return toStr.call(arr) === '[object Array]';
	};
	var isPlainObject = function isPlainObject(obj) {
	  if (!obj || toStr.call(obj) !== '[object Object]') {
	    return false;
	  }
	  var hasOwnConstructor = hasOwn.call(obj, 'constructor');
	  var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
	  // Not own constructor property must be Object
	  if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
	    return false;
	  }

	  // Own properties are enumerated firstly, so to speed up,
	  // if last one is own, then all properties are own.
	  var key;
	  for (key in obj) {/**/}
	  return typeof key === 'undefined' || hasOwn.call(obj, key);
	};

	// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
	var setProperty = function setProperty(target, options) {
	  if (defineProperty && options.name === '__proto__') {
	    defineProperty(target, options.name, {
	      enumerable: true,
	      configurable: true,
	      value: options.newValue,
	      writable: true
	    });
	  } else {
	    target[options.name] = options.newValue;
	  }
	};

	// Return undefined instead of __proto__ if '__proto__' is not an own property
	var getProperty = function getProperty(obj, name) {
	  if (name === '__proto__') {
	    if (!hasOwn.call(obj, name)) {
	      return void 0;
	    } else if (gOPD) {
	      // In early versions of node, obj['__proto__'] is buggy when obj has
	      // __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
	      return gOPD(obj, name).value;
	    }
	  }
	  return obj[name];
	};
	var extend$3 = function extend() {
	  var options, name, src, copy, copyIsArray, clone;
	  var target = arguments[0];
	  var i = 1;
	  var length = arguments.length;
	  var deep = false;

	  // Handle a deep copy situation
	  if (typeof target === 'boolean') {
	    deep = target;
	    target = arguments[1] || {};
	    // skip the boolean and the target
	    i = 2;
	  }
	  if (target == null || typeof target !== 'object' && typeof target !== 'function') {
	    target = {};
	  }
	  for (; i < length; ++i) {
	    options = arguments[i];
	    // Only deal with non-null/undefined values
	    if (options != null) {
	      // Extend the base object
	      for (name in options) {
	        src = getProperty(target, name);
	        copy = getProperty(options, name);

	        // Prevent never-ending loop
	        if (target !== copy) {
	          // Recurse if we're merging plain objects or arrays
	          if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray$1(copy)))) {
	            if (copyIsArray) {
	              copyIsArray = false;
	              clone = src && isArray$1(src) ? src : [];
	            } else {
	              clone = src && isPlainObject(src) ? src : {};
	            }

	            // Never move original objects, clone them
	            setProperty(target, {
	              name: name,
	              newValue: extend(deep, clone, copy)
	            });

	            // Don't bring in undefined values
	          } else if (typeof copy !== 'undefined') {
	            setProperty(target, {
	              name: name,
	              newValue: copy
	            });
	          }
	        }
	      }
	    }
	  }

	  // Return the modified object
	  return target;
	};

	/* eslint no-nested-ternary: 0 */
	function getFieldAccessor$1(field, page, deps, columnOrder) {
	  if (!field) {
	    return -1;
	  }
	  const cache = deps.cache;
	  const origin = field.origin ? field.origin() : null;
	  if (origin) {
	    field = origin;
	  }
	  let fieldIdx = cache.fields.indexOf(field);
	  let attrIdx = -1;
	  let attrDimIdx = -1;
	  if (fieldIdx === -1) {
	    for (let i = 0; i < cache.wrappedFields.length; i++) {
	      attrDimIdx = cache.wrappedFields[i].attrDims.map(v => v.instance).indexOf(field);
	      attrIdx = cache.wrappedFields[i].attrExps.map(v => v.instance).indexOf(field);
	      if (attrDimIdx !== -1 || attrIdx !== -1) {
	        fieldIdx = i;
	        break;
	      }
	    }
	  }
	  if (Array.isArray(columnOrder) && columnOrder.some((el, i) => el !== i)) {
	    const correctIndex = columnOrder.indexOf(fieldIdx);
	    if (correctIndex !== -1) {
	      fieldIdx = correctIndex;
	    }
	  }
	  fieldIdx -= page.qArea.qLeft;
	  if (fieldIdx < 0 || fieldIdx >= page.qArea.qWidth) {
	    // throw new Error('Field out of range');
	    return -1;
	  }
	  if (attrDimIdx >= 0) {
	    return row => row[fieldIdx].qAttrDims.qValues[attrDimIdx];
	  }
	  if (attrIdx >= 0) {
	    return row => row[fieldIdx].qAttrExps.qValues[attrIdx];
	  }
	  return row => row[fieldIdx];
	}

	// TODO - handle 'other' value
	// const specialTextValues = {
	//   '-3': (meta) => {
	//     if ('othersLabel' in meta) {
	//       return meta.othersLabel;
	//     }
	//     return '';
	//   }
	// };

	function datumExtract$1(propCfg, cell, _ref) {
	  let {
	    key
	  } = _ref;
	  const datum = {
	    value: typeof propCfg.value === 'function' ? propCfg.value(cell) : typeof propCfg.value !== 'undefined' ? propCfg.value : cell // eslint-disable-line no-nested-ternary
	  };
	  datum.label = typeof propCfg.label === 'function' ? propCfg.label(cell) : typeof propCfg.label !== 'undefined' ? String(propCfg.label) : String(datum.value); // eslint-disable-line no-nested-ternary

	  if (propCfg.field) {
	    datum.source = {
	      key,
	      field: propCfg.field.key()
	    };
	  }
	  return datum;
	}
	function cellToValue(_ref2) {
	  let {
	    cache,
	    f,
	    mainCell,
	    p,
	    page,
	    rowIdx,
	    row,
	    sourceKey,
	    target,
	    targetProp,
	    columnOrder
	  } = _ref2;
	  let propCell = mainCell;
	  if (p.field && p.field !== f) {
	    const propCellFn = getFieldAccessor$1(p.field, page, {
	      cache
	    }, columnOrder);
	    if (propCellFn === -1) {
	      return;
	    }
	    propCell = extend$3({
	      qRow: rowIdx
	    }, propCellFn(row));
	  }
	  target[targetProp] = datumExtract$1(p, propCell, {
	    key: sourceKey
	  });
	}
	function extract$1(config, dataset, cache, util) {
	  const cfgs = Array.isArray(config) ? config : [config];
	  let dataItems = [];
	  for (let i = 0; i < cfgs.length; i++) {
	    if (typeof cfgs[i].field !== 'undefined') {
	      const cube = dataset.raw();
	      const sourceKey = dataset.key();
	      const f = typeof cfgs[i].field === 'object' ? cfgs[i].field : dataset.field(cfgs[i].field);
	      const {
	        props,
	        main
	      } = util.normalizeConfig(cfgs[i], dataset);
	      const propsArr = Object.keys(props);
	      const track = !!cfgs[i].trackBy;
	      const trackType = typeof cfgs[i].trackBy;
	      const tracker = {};
	      const trackedItems = [];
	      const items = [];
	      for (let j = 0; j < cube.qDataPages.length; j++) {
	        const fn = getFieldAccessor$1(f, cube.qDataPages[j], {
	          cache
	        }, cube.qColumnOrder);
	        if (fn === -1) {
	          continue;
	        }
	        for (let k = 0; k < cube.qDataPages[j].qMatrix.length; k++) {
	          const rowIdx = cube.qDataPages[j].qArea.qTop + k;
	          const mainCell = extend$3({
	            qRow: rowIdx
	          }, fn(cube.qDataPages[j].qMatrix[k]));
	          const ret = datumExtract$1(main, mainCell, {
	            key: sourceKey
	          });
	          const exclude = main.filter && !main.filter(mainCell);
	          if (exclude) {
	            continue;
	          }
	          for (let l = 0; l < propsArr.length; l++) {
	            const p = props[propsArr[l]];
	            let arr = p.fields || [p];
	            if (p.fields) {
	              ret[propsArr[l]] = [];
	            }

	            // loop through all props that need to be mapped and
	            // assign 'value' and 'source' to each property
	            for (let m = 0; m < arr.length; m++) {
	              cellToValue({
	                cache,
	                f,
	                mainCell,
	                p: arr[m],
	                prop: propsArr[l],
	                page: cube.qDataPages[j],
	                rowIdx,
	                row: cube.qDataPages[j].qMatrix[k],
	                sourceKey,
	                target: p.fields ? ret[propsArr[l]] : ret,
	                targetProp: p.fields ? m : propsArr[l],
	                columnOrder: cube.qColumnOrder
	              });
	            }
	            if (p.fields) {
	              const fieldValues = ret[propsArr[l]].map(v => v.value);
	              const fieldLabels = ret[propsArr[l]].map(v => v.label);
	              ret[propsArr[l]] = {
	                value: typeof p.value === 'function' ? p.value(fieldValues) : typeof p.value !== 'undefined' ? p.value : fieldValues,
	                label: typeof p.label === 'function' ? p.label(fieldLabels) : typeof p.label !== 'undefined' ? String(p.label) : String(ret[propsArr[l]].value)
	              };
	            }
	          }

	          // collect items based on the trackBy value
	          // items with the same trackBy value are placed in an array and reduced later
	          if (track) {
	            util.track({
	              cfg: cfgs[i],
	              itemData: mainCell,
	              obj: ret,
	              target: trackedItems,
	              tracker,
	              trackType
	            });
	          }
	          items.push(ret);
	        }
	      }

	      // reduce if items have been grouped
	      const tmp = track ? util.collect(trackedItems, {
	        main,
	        propsArr,
	        props
	      }) : items;
	      dataItems = [...dataItems, ...tmp];
	    }
	  }
	  return dataItems;
	}
	function count(node) {
	  var sum = 0,
	    children = node.children,
	    i = children && children.length;
	  if (!i) sum = 1;else while (--i >= 0) sum += children[i].value;
	  node.value = sum;
	}
	function node_count() {
	  return this.eachAfter(count);
	}
	function node_each(callback, that) {
	  let index = -1;
	  for (const node of this) {
	    callback.call(that, node, ++index, this);
	  }
	  return this;
	}
	function node_eachBefore(callback, that) {
	  var node = this,
	    nodes = [node],
	    children,
	    i,
	    index = -1;
	  while (node = nodes.pop()) {
	    callback.call(that, node, ++index, this);
	    if (children = node.children) {
	      for (i = children.length - 1; i >= 0; --i) {
	        nodes.push(children[i]);
	      }
	    }
	  }
	  return this;
	}
	function node_eachAfter(callback, that) {
	  var node = this,
	    nodes = [node],
	    next = [],
	    children,
	    i,
	    n,
	    index = -1;
	  while (node = nodes.pop()) {
	    next.push(node);
	    if (children = node.children) {
	      for (i = 0, n = children.length; i < n; ++i) {
	        nodes.push(children[i]);
	      }
	    }
	  }
	  while (node = next.pop()) {
	    callback.call(that, node, ++index, this);
	  }
	  return this;
	}
	function node_find(callback, that) {
	  let index = -1;
	  for (const node of this) {
	    if (callback.call(that, node, ++index, this)) {
	      return node;
	    }
	  }
	}
	function node_sum(value) {
	  return this.eachAfter(function (node) {
	    var sum = +value(node.data) || 0,
	      children = node.children,
	      i = children && children.length;
	    while (--i >= 0) sum += children[i].value;
	    node.value = sum;
	  });
	}
	function node_sort(compare) {
	  return this.eachBefore(function (node) {
	    if (node.children) {
	      node.children.sort(compare);
	    }
	  });
	}
	function node_path(end) {
	  var start = this,
	    ancestor = leastCommonAncestor(start, end),
	    nodes = [start];
	  while (start !== ancestor) {
	    start = start.parent;
	    nodes.push(start);
	  }
	  var k = nodes.length;
	  while (end !== ancestor) {
	    nodes.splice(k, 0, end);
	    end = end.parent;
	  }
	  return nodes;
	}
	function leastCommonAncestor(a, b) {
	  if (a === b) return a;
	  var aNodes = a.ancestors(),
	    bNodes = b.ancestors(),
	    c = null;
	  a = aNodes.pop();
	  b = bNodes.pop();
	  while (a === b) {
	    c = a;
	    a = aNodes.pop();
	    b = bNodes.pop();
	  }
	  return c;
	}
	function node_ancestors() {
	  var node = this,
	    nodes = [node];
	  while (node = node.parent) {
	    nodes.push(node);
	  }
	  return nodes;
	}
	function node_descendants() {
	  return Array.from(this);
	}
	function node_leaves() {
	  var leaves = [];
	  this.eachBefore(function (node) {
	    if (!node.children) {
	      leaves.push(node);
	    }
	  });
	  return leaves;
	}
	function node_links() {
	  var root = this,
	    links = [];
	  root.each(function (node) {
	    if (node !== root) {
	      // Don’t include the root’s parent, if any.
	      links.push({
	        source: node.parent,
	        target: node
	      });
	    }
	  });
	  return links;
	}
	function* node_iterator() {
	  var node = this,
	    current,
	    next = [node],
	    children,
	    i,
	    n;
	  do {
	    current = next.reverse(), next = [];
	    while (node = current.pop()) {
	      yield node;
	      if (children = node.children) {
	        for (i = 0, n = children.length; i < n; ++i) {
	          next.push(children[i]);
	        }
	      }
	    }
	  } while (next.length);
	}
	function hierarchy(data, children) {
	  if (data instanceof Map) {
	    data = [undefined, data];
	    if (children === undefined) children = mapChildren;
	  } else if (children === undefined) {
	    children = objectChildren;
	  }
	  var root = new Node(data),
	    node,
	    nodes = [root],
	    child,
	    childs,
	    i,
	    n;
	  while (node = nodes.pop()) {
	    if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) {
	      node.children = childs;
	      for (i = n - 1; i >= 0; --i) {
	        nodes.push(child = childs[i] = new Node(childs[i]));
	        child.parent = node;
	        child.depth = node.depth + 1;
	      }
	    }
	  }
	  return root.eachBefore(computeHeight);
	}
	function node_copy() {
	  return hierarchy(this).eachBefore(copyData);
	}
	function objectChildren(d) {
	  return d.children;
	}
	function mapChildren(d) {
	  return Array.isArray(d) ? d[1] : null;
	}
	function copyData(node) {
	  if (node.data.value !== undefined) node.value = node.data.value;
	  node.data = node.data.data;
	}
	function computeHeight(node) {
	  var height = 0;
	  do node.height = height; while ((node = node.parent) && node.height < ++height);
	}
	function Node(data) {
	  this.data = data;
	  this.depth = this.height = 0;
	  this.parent = null;
	}
	Node.prototype = hierarchy.prototype = {
	  constructor: Node,
	  count: node_count,
	  each: node_each,
	  eachAfter: node_eachAfter,
	  eachBefore: node_eachBefore,
	  find: node_find,
	  sum: node_sum,
	  sort: node_sort,
	  path: node_path,
	  ancestors: node_ancestors,
	  descendants: node_descendants,
	  leaves: node_leaves,
	  links: node_links,
	  copy: node_copy,
	  [Symbol.iterator]: node_iterator
	};
	function optional(f) {
	  return f == null ? null : required(f);
	}
	function required(f) {
	  if (typeof f !== "function") throw new Error();
	  return f;
	}
	var preroot = {
	    depth: -1
	  },
	  ambiguous = {},
	  imputed = {};
	function defaultId(d) {
	  return d.id;
	}
	function defaultParentId(d) {
	  return d.parentId;
	}
	function stratify() {
	  var id = defaultId,
	    parentId = defaultParentId,
	    path;
	  function stratify(data) {
	    var nodes = Array.from(data),
	      currentId = id,
	      currentParentId = parentId,
	      n,
	      d,
	      i,
	      root,
	      parent,
	      node,
	      nodeId,
	      nodeKey,
	      nodeByKey = new Map();
	    if (path != null) {
	      const I = nodes.map((d, i) => normalize(path(d, i, data)));
	      const P = I.map(parentof);
	      const S = new Set(I).add("");
	      for (const i of P) {
	        if (!S.has(i)) {
	          S.add(i);
	          I.push(i);
	          P.push(parentof(i));
	          nodes.push(imputed);
	        }
	      }
	      currentId = (_, i) => I[i];
	      currentParentId = (_, i) => P[i];
	    }
	    for (i = 0, n = nodes.length; i < n; ++i) {
	      d = nodes[i], node = nodes[i] = new Node(d);
	      if ((nodeId = currentId(d, i, data)) != null && (nodeId += "")) {
	        nodeKey = node.id = nodeId;
	        nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node);
	      }
	      if ((nodeId = currentParentId(d, i, data)) != null && (nodeId += "")) {
	        node.parent = nodeId;
	      }
	    }
	    for (i = 0; i < n; ++i) {
	      node = nodes[i];
	      if (nodeId = node.parent) {
	        parent = nodeByKey.get(nodeId);
	        if (!parent) throw new Error("missing: " + nodeId);
	        if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
	        if (parent.children) parent.children.push(node);else parent.children = [node];
	        node.parent = parent;
	      } else {
	        if (root) throw new Error("multiple roots");
	        root = node;
	      }
	    }
	    if (!root) throw new Error("no root");

	    // When imputing internal nodes, only introduce roots if needed.
	    // Then replace the imputed marker data with null.
	    if (path != null) {
	      while (root.data === imputed && root.children.length === 1) {
	        root = root.children[0], --n;
	      }
	      for (let i = nodes.length - 1; i >= 0; --i) {
	        node = nodes[i];
	        if (node.data !== imputed) break;
	        node.data = null;
	      }
	    }
	    root.parent = preroot;
	    root.eachBefore(function (node) {
	      node.depth = node.parent.depth + 1;
	      --n;
	    }).eachBefore(computeHeight);
	    root.parent = null;
	    if (n > 0) throw new Error("cycle");
	    return root;
	  }
	  stratify.id = function (x) {
	    return arguments.length ? (id = optional(x), stratify) : id;
	  };
	  stratify.parentId = function (x) {
	    return arguments.length ? (parentId = optional(x), stratify) : parentId;
	  };
	  stratify.path = function (x) {
	    return arguments.length ? (path = optional(x), stratify) : path;
	  };
	  return stratify;
	}

	// To normalize a path, we coerce to a string, strip the trailing slash if any
	// (as long as the trailing slash is not immediately preceded by another slash),
	// and add leading slash if missing.
	function normalize(path) {
	  path = `${path}`;
	  let i = path.length;
	  if (slash(path, i - 1) && !slash(path, i - 2)) path = path.slice(0, -1);
	  return path[0] === "/" ? path : `/${path}`;
	}

	// Walk backwards to find the first slash that is not the leading slash, e.g.:
	// "/foo/bar" ⇥ "/foo", "/foo" ⇥ "/", "/" ↦ "". (The root is special-cased
	// because the id of the root must be a truthy value.)
	function parentof(path) {
	  let i = path.length;
	  if (i < 2) return "";
	  while (--i > 1) if (slash(path, i)) break;
	  return path.slice(0, i);
	}

	// Slashes can be escaped; to determine whether a slash is a path delimiter, we
	// count the number of preceding backslashes escaping the forward slash: an odd
	// number indicates an escaped forward slash.
	function slash(path, i) {
	  if (path[i] === "/") {
	    let k = 0;
	    while (i > 0 && path[--i] === "\\") ++k;
	    if ((k & 1) === 0) return true;
	  }
	  return false;
	}

	/**
	 * Resolves the value at the given JSON path
	 * @private
	 * @param  {String} path [description]
	 * @param  {Object} obj  [description]
	 * @return {Object}      [description]
	 *
	 * @example
	 * let path = "/path/to/paradise";
	 * let obj = {
	 *   path: {
	 *     to: { paradise: "heaven"},
	 *     from: {...}
	 *   }
	 * };
	 * resolve( path, obj ); // "heaven"
	 */
	function resolve(path, obj) {
	  if (path.charAt(0) === '/') {
	    path = path.substring(1);
	  }
	  const arr = path.split('/');
	  let subpath;
	  let container = obj;
	  for (let i = 0; i < arr.length; i++) {
	    if (arr[i] === '*' && Array.isArray(container)) {
	      const carr = [];
	      subpath = arr.slice(i + 1).join('/');
	      for (let c = 0; c < container.length; c++) {
	        let v = resolve(subpath, container[c]);
	        // v.forEach(_ => _._parent = container[c]);
	        if (Array.isArray(v)) {
	          carr.push(...v);
	        } else {
	          carr.push(v);
	        }
	      }
	      return carr;
	      // return container.map(v => resolve(arr.slice(i + 1).join('/'), v));
	    }
	    if (!arr[i] && Array.isArray(container)) {
	      const carr = new Array(container.length);
	      subpath = arr.slice(i + 1).join('/');
	      for (let c = 0; c < container.length; c++) {
	        carr[c] = resolve(subpath, container[c]);
	      }
	      return carr;
	      // return container.map(v => resolve(arr.slice(i + 1).join('/'), v));
	    }
	    if (arr[i] in container) {
	      container = container[arr[i]];
	    }
	  }
	  return container;
	}
	function flattenTree(children, steps, arrIndexAtTargetDepth) {
	  let arr = [];
	  if (!children || !children.length) {
	    return arr;
	  }
	  if (steps <= 0) {
	    const nodes = arrIndexAtTargetDepth >= 0 ? [children[arrIndexAtTargetDepth]] : children;
	    arr = [...arr, ...nodes];
	  } else {
	    for (let i = 0; i < children.length; i++) {
	      if (children[i].children && children[i].children.length) {
	        arr = [...arr, ...flattenTree(children[i].children, steps - 1, arrIndexAtTargetDepth)];
	      }
	    }
	  }
	  return arr;
	}
	function treeAccessor(sourceDepth, targetDepth, arrIndexAtTargetDepth) {
	  if (sourceDepth === targetDepth) {
	    return d => d;
	  }
	  if (sourceDepth > targetDepth) {
	    // traverse upwards
	    const steps = Math.max(0, Math.min(100, sourceDepth - targetDepth));
	    return node => {
	      let n = node;
	      for (let i = 0; i < steps; ++i) {
	        n = n.parent;
	      }
	      return n;
	    };
	  }
	  if (targetDepth > sourceDepth) {
	    // flatten descendants
	    const steps = Math.max(0, Math.min(100, targetDepth - sourceDepth));
	    return node => flattenTree(node.children, steps - 1, arrIndexAtTargetDepth);
	  }
	  return false;
	}
	function findField$1(query, _ref) {
	  let {
	    cache
	  } = _ref;
	  if (typeof query === 'number') {
	    return cache.fields[query];
	  }
	  const allFields = cache.allFields;
	  if (typeof query === 'function') {
	    for (let i = 0; i < allFields.length; i++) {
	      if (query(allFields[i])) {
	        return allFields[i];
	      }
	    }
	    return false;
	  }
	  if (typeof query === 'string') {
	    for (let i = 0; i < allFields.length; i++) {
	      if (allFields[i].key() === query || allFields[i].title() === query) {
	        return allFields[i];
	      }
	    }
	  } else if (query && allFields.indexOf(query) !== -1) {
	    // assume 'query' is a field instance
	    return query;
	  }
	  throw Error("Field not found: ".concat(query));
	}
	const DIM_RX$1 = /^qDimensionInfo(?:\/(\d+))?/;
	const M_RX$1 = /^\/?qMeasureInfo\/(\d+)/;
	const ATTR_EXPR_RX$1 = /\/qAttrExprInfo\/(\d+)/;
	const ATTR_DIM_RX$1 = /\/qAttrDimInfo\/(\d+)/;
	function getColumnOrder(dataset) {
	  const qColumnOrder = dataset.raw().qColumnOrder;
	  const fields = dataset.fields();
	  return qColumnOrder && qColumnOrder.length === fields.length ? qColumnOrder : fields.map((f, i) => i);
	}
	function getDimensionColumnOrder(cube) {
	  const order = cube.qColumnOrder && cube.qColumnOrder.length ? cube.qColumnOrder : cube.qDimensionInfo.map((d, ii) => ii);
	  return order.filter(ii => ii < cube.qDimensionInfo.length);
	}
	function getFieldDepth(field, _ref) {
	  let {
	    cube
	  } = _ref;
	  if (!field) {
	    return -1;
	  }
	  let key = field.origin && field.origin() ? field.origin().key() : field.key();
	  let isFieldDimension = false;
	  let fieldIdx = -1; // cache.fields.indexOf(field);
	  let attrIdx = -1;
	  let attrDimIdx = -1;
	  let fieldDepth = -1;
	  let pseudoMeasureIndex = -1;
	  let measureIdx = -1;
	  let remainder = key;
	  const treeOrder = cube.qEffectiveInterColumnSortOrder;
	  const columnOrder = getDimensionColumnOrder(cube);
	  if (DIM_RX$1.test(remainder)) {
	    isFieldDimension = true;
	    fieldIdx = +DIM_RX$1.exec(remainder)[1];
	    remainder = key.replace(DIM_RX$1, '');
	  }
	  if (M_RX$1.test(remainder)) {
	    if (cube.qMode === 'K') {
	      pseudoMeasureIndex = +M_RX$1.exec(remainder)[1];
	    } else if (treeOrder && treeOrder.indexOf(-1) !== -1) {
	      pseudoMeasureIndex = +M_RX$1.exec(remainder)[1];
	      measureIdx = 0;
	    } else {
	      measureIdx = +M_RX$1.exec(remainder)[1];
	    }
	    remainder = remainder.replace(M_RX$1, '');
	  }
	  if (remainder) {
	    if (ATTR_DIM_RX$1.exec(remainder)) {
	      attrDimIdx = +ATTR_DIM_RX$1.exec(remainder)[1];
	    } else if (ATTR_EXPR_RX$1.exec(remainder)) {
	      attrIdx = +ATTR_EXPR_RX$1.exec(remainder)[1];
	    }
	  }
	  if (isFieldDimension) {
	    if (cube.qMode === 'S') {
	      fieldDepth = columnOrder[fieldIdx];
	    } else {
	      fieldDepth = treeOrder ? treeOrder.indexOf(fieldIdx) : fieldIdx;
	    }
	  } else if (treeOrder && treeOrder.indexOf(-1) !== -1) {
	    // if pseudo dimension exists in sort order
	    fieldDepth = treeOrder.indexOf(-1); // depth of pesudodimension
	  } else {
	    // assume measure is at the bottom of the tree
	    fieldDepth = cube.qDimensionInfo.length - (cube.qMode === 'K' ? 0 : 1);
	  }
	  return {
	    fieldDepth: fieldDepth + 1,
	    // +1 due to root node
	    pseudoMeasureIndex,
	    measureIdx,
	    attrDimIdx,
	    attrIdx
	  };
	}
	function getFieldAccessor(sourceDepthObject, targetDepthObject) {
	  let nodeFn = treeAccessor(sourceDepthObject.fieldDepth, targetDepthObject.fieldDepth, targetDepthObject.pseudoMeasureIndex);
	  let valueFn;
	  if (targetDepthObject.measureIdx >= 0) {
	    valueFn = node => node.data.qValues[targetDepthObject.measureIdx];
	  } else {
	    valueFn = node => node.data;
	  }
	  let attrFn;
	  if (targetDepthObject.attrDimIdx >= 0) {
	    attrFn = data => {
	      var _data$qAttrDims;
	      return data === null || data === void 0 || (_data$qAttrDims = data.qAttrDims) === null || _data$qAttrDims === void 0 ? void 0 : _data$qAttrDims.qValues[targetDepthObject.attrDimIdx];
	    };
	  } else if (targetDepthObject.attrIdx >= 0) {
	    attrFn = data => {
	      var _data$qAttrExps;
	      return data === null || data === void 0 || (_data$qAttrExps = data.qAttrExps) === null || _data$qAttrExps === void 0 ? void 0 : _data$qAttrExps.qValues[targetDepthObject.attrIdx];
	    };
	  }
	  return {
	    nodeFn,
	    attrFn,
	    valueFn
	  };
	}
	function datumExtract(propCfg, cell, _ref2) {
	  let {
	    key
	  } = _ref2;
	  const datum = {
	    value: typeof propCfg.value === 'function' ? propCfg.value(cell) : typeof propCfg.value !== 'undefined' ? propCfg.value : cell // eslint-disable-line no-nested-ternary
	  };
	  datum.label = typeof propCfg.label === 'function' ? propCfg.label(cell) : typeof propCfg.label !== 'undefined' ? String(propCfg.label) : String(datum.value); // eslint-disable-line no-nested-ternary

	  if (propCfg.field) {
	    datum.source = {
	      key,
	      field: propCfg.field.key()
	    };
	  }
	  return datum;
	}
	function doIt(_ref3) {
	  let {
	    propsArr,
	    props,
	    item,
	    itemData,
	    ret,
	    sourceKey
	  } = _ref3;
	  for (let i = 0; i < propsArr.length; i++) {
	    const pCfg = props[propsArr[i]];
	    const arr = pCfg.fields || [pCfg];
	    let coll;
	    let collStr;
	    if (pCfg.fields) {
	      coll = [];
	      collStr = [];
	    }
	    for (let j = 0; j < arr.length; j++) {
	      const p = arr[j];
	      let fn;
	      let str;
	      let value;
	      let nodes;
	      let cells;
	      let label;
	      if (p.type === 'primitive') {
	        value = p.value;
	        label = String(p.value);
	      } else {
	        if (typeof p.value === 'function') {
	          fn = v => p.value(v, item);
	        }
	        if (typeof p.label === 'function') {
	          str = v => p.label(v, item);
	        }
	        if (p.accessor) {
	          nodes = p.accessor(item);
	          if (Array.isArray(nodes)) {
	            // propably descendants
	            cells = nodes.map(p.valueAccessor);
	            if (p.attrAccessor) {
	              cells = cells.map(p.attrAccessor);
	            }
	            if (fn) {
	              value = cells.map(fn);
	              fn = null;
	            }
	            if (str) {
	              label = cells.map(str);
	              str = null;
	            }
	            value = p.reduce ? p.reduce(value) : value;
	            label = p.reduceLabel ? p.reduceLabel(label, value) : String(value);
	          } else {
	            value = p.attrAccessor ? p.attrAccessor(p.valueAccessor(nodes)) : p.valueAccessor(nodes);
	            label = value;
	          }
	        } else {
	          value = itemData;
	          label = itemData;
	        }
	      }
	      if (pCfg.fields) {
	        const v = fn ? fn(value) : value;
	        coll.push(v);
	        collStr.push(str && label != null ? str(label) : label != null ? label : String(v));
	      } else {
	        const v = fn ? fn(value) : value;
	        ret[propsArr[i]] = {
	          value: v,
	          label: str ? str(label) : label != null ? label : String(v)
	        };
	        if (p.field) {
	          ret[propsArr[i]].source = {
	            field: p.field.key(),
	            key: sourceKey
	          };
	        }
	      }
	    }
	    if (coll) {
	      ret[propsArr[i]] = {
	        value: typeof pCfg.value === 'function' ? pCfg.value(coll, item) : coll,
	        label: typeof pCfg.label === 'function' ? pCfg.label(collStr, item) : collStr
	      };
	    }
	  }
	}
	const getHierarchy = (cube, cache, config) => {
	  const rootPath = cube.qMode === 'K' ? '/qStackedDataPages/*/qData' : '/qTreeDataPages/*';
	  const childNodes = cube.qMode === 'K' ? 'qSubNodes' : 'qNodes';
	  const root = resolve(rootPath, cube);
	  if (!root || !root[0]) {
	    return null;
	  }
	  cache.tree = hierarchy(root[0], config.children || (node => node[childNodes]));
	  return cache.tree;
	};
	function getHierarchyForSMode(dataset) {
	  const matrix = dataset.raw().qDataPages.length ? dataset.raw().qDataPages[0].qMatrix : [];
	  const order = getColumnOrder(dataset);
	  const fields = dataset.fields();
	  const dimensions = dataset.fields().filter(f => f.type() === 'dimension').map(f => order.indexOf(fields.indexOf(f)));
	  const measures = dataset.fields().filter(f => f.type() === 'measure').map(f => order.indexOf(fields.indexOf(f)));
	  const root = {
	    __id: '__root',
	    qValues: []
	  };
	  const keys = {
	    __root: root
	  };
	  for (let r = 0; r < matrix.length; r++) {
	    const row = matrix[r];
	    let id = '__root';
	    // let parent = root;
	    let isNew = false;
	    for (let c = 0; c < dimensions.length; c++) {
	      var _cell$qElemNumber;
	      const cell = row[dimensions[c]];
	      const key = "".concat(id, "__").concat((_cell$qElemNumber = cell.qElemNumber) !== null && _cell$qElemNumber !== void 0 ? _cell$qElemNumber : cell.qElemNo);
	      if (!keys[key]) {
	        keys[key] = _objectSpread2({
	          __id: key,
	          __parent: id,
	          qValues: []
	        }, cell);
	        isNew = true;
	      }
	      id = key;
	    }
	    if (isNew) {
	      for (let c = 0; c < measures.length; c++) {
	        const cell = row[measures[c]];
	        keys[id].qValues.push(cell);
	      }
	    }
	  }
	  const nodes = Object.keys(keys).map(key => keys[key]);
	  const h = stratify().id(d => d.__id).parentId(d => d.__parent)(nodes);
	  return h;
	}
	const attachPropsAccessors = _ref4 => {
	  let {
	    propsArr,
	    props,
	    cube,
	    cache,
	    itemDepthObject,
	    f
	  } = _ref4;
	  for (let i = 0; i < propsArr.length; i++) {
	    const pCfg = props[propsArr[i]];
	    const arr = pCfg.fields ? pCfg.fields : [pCfg];
	    for (let j = 0; j < arr.length; j++) {
	      const p = arr[j];
	      if (p.field !== f) {
	        const depthObject = getFieldDepth(p.field, {
	          cube});
	        const accessors = getFieldAccessor(itemDepthObject, depthObject);
	        p.accessor = accessors.nodeFn; // nodes accessor
	        p.valueAccessor = accessors.valueFn; // cell accessor
	        p.attrAccessor = accessors.attrFn; // attr cell accessor
	      }
	    }
	  }
	};
	function augment() {
	  let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	  let dataset = arguments.length > 1 ? arguments[1] : undefined;
	  let cache = arguments.length > 2 ? arguments[2] : undefined;
	  let util = arguments.length > 3 ? arguments[3] : undefined;
	  const cube = dataset.raw();
	  const sourceKey = dataset.key();
	  const h = cube.qMode === 'S' ? getHierarchyForSMode(dataset) : getHierarchy(cube, cache, config);
	  if (!h) {
	    return null;
	  }
	  const height = h.height;
	  const propDefs = [];
	  for (let i = 0; i <= height; i++) {
	    let f = null;
	    if (i > 0) {
	      if (cube.qMode === 'S') {
	        const order = getDimensionColumnOrder(cube);
	        let idx = order[i - 1];
	        f = cache.fields[idx];
	      } else {
	        let idx = cube.qEffectiveInterColumnSortOrder[i - 1];
	        // if (idx === -1) { // pseudo
	        //   let childIdx = node.parent.children.indexOf(node);
	        //   idx = cube.qDimensionInfo.length + childIdx; // measure field
	        // }
	        if (i > cube.qEffectiveInterColumnSortOrder.length) {
	          idx = cube.qDimensionInfo.length;
	        }
	        f = cache.fields[idx];
	      }
	    }
	    const {
	      props,
	      main
	    } = util.normalizeConfig(_objectSpread2(_objectSpread2({}, config), {}, {
	      field: f ? f.key() : undefined
	    }), dataset);
	    const propsArr = Object.keys(props);
	    propDefs[i] = {
	      propsArr,
	      props,
	      main
	    };
	    const itemDepthObject = f ? getFieldDepth(f, {
	      cube}) : {
	      fieldDepth: 0
	    };
	    attachPropsAccessors({
	      propsArr,
	      props,
	      cube,
	      cache,
	      itemDepthObject,
	      f
	    });
	  }
	  const replica = h.copy();
	  const replicaDescendants = replica.descendants();
	  const descendants = h.descendants();
	  for (let i = 0; i < descendants.length; i++) {
	    const propsArr = propDefs[descendants[i].depth].propsArr;
	    const props = propDefs[descendants[i].depth].props;
	    const main = propDefs[descendants[i].depth].main;
	    const item = replicaDescendants[i];
	    const itemData = item.data; // main.valueAccessor(currentOriginal);

	    const ret = datumExtract(main, itemData, {
	      key: sourceKey
	    });
	    doIt({
	      propsArr,
	      props,
	      item,
	      itemData,
	      ret,
	      sourceKey});
	    descendants[i].data = ret;
	  }
	  return h;
	}
	function extract(config, dataset, cache, util) {
	  const cfgs = Array.isArray(config) ? config : [config];
	  let dataItems = [];
	  for (let g = 0; g < cfgs.length; g++) {
	    if (typeof cfgs[g].field !== 'undefined') {
	      const cube = dataset.raw();
	      const sourceKey = dataset.key();
	      const h = getHierarchy(cube, cache, config);
	      if (!h) {
	        continue;
	      }
	      const f = typeof cfgs[g].field === 'object' ? cfgs[g].field : dataset.field(cfgs[g].field);
	      const {
	        props,
	        main
	      } = util.normalizeConfig(cfgs[g], dataset);
	      const propsArr = Object.keys(props);
	      const itemDepthObject = getFieldDepth(f, {
	        cube});
	      const {
	        nodeFn,
	        attrFn,
	        valueFn
	      } = getFieldAccessor({
	        fieldDepth: 0
	      }, itemDepthObject);
	      attachPropsAccessors({
	        propsArr,
	        props,
	        cube,
	        cache,
	        itemDepthObject,
	        f
	      });
	      const track = !!cfgs[g].trackBy;
	      const trackType = typeof cfgs[g].trackBy;
	      const tracker = {};
	      const trackedItems = [];
	      const items = nodeFn(cache.tree);
	      const mapped = [];
	      for (let i = 0; i < items.length; i++) {
	        const item = items[i];
	        const itemData = attrFn ? attrFn(valueFn(item)) : valueFn(item);
	        const exclude = main.filter && !main.filter(itemData);
	        if (exclude) {
	          continue;
	        }
	        const ret = datumExtract(main, itemData, {
	          key: sourceKey
	        });
	        doIt({
	          propsArr,
	          props,
	          item,
	          itemData,
	          ret,
	          sourceKey
	        });
	        // collect items based on the trackBy value
	        // items with the same trackBy value are placed in an array and reduced later
	        if (track) {
	          util.track({
	            cfg: cfgs[g],
	            itemData,
	            obj: ret,
	            target: trackedItems,
	            tracker,
	            trackType
	          });
	        }
	        mapped.push(ret);
	      }
	      // reduce if items have been grouped
	      const tmp = track ? util.collect(trackedItems, {
	        main,
	        propsArr,
	        props
	      }) : mapped;
	      dataItems = [...dataItems, ...tmp];
	    }
	  }
	  return dataItems;
	}
	var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
	function createCommonjsModule(fn, module) {
	  return module = {
	    exports: {}
	  }, fn(module, module.exports), module.exports;
	}
	var format_min = createCommonjsModule(function (module) {
	  /*! javascript-number-formatter - v1.1.11 - http://mottie.github.com/javascript-number-formatter/ * © ecava */
	  !function (a, b) {
	    module.exports = b();
	  }(commonjsGlobal, function () {
	    return function (a, b) {
	      if (!a || isNaN(+b)) return b;
	      var c,
	        d,
	        e,
	        f,
	        g,
	        h,
	        i,
	        j,
	        k,
	        l,
	        m = a.length,
	        n = a.search(/[0-9\-\+#]/),
	        o = n > 0 ? a.substring(0, n) : "",
	        p = a.split("").reverse().join(""),
	        q = p.search(/[0-9\-\+#]/),
	        r = m - q,
	        s = a.substring(r, r + 1),
	        t = r + ("." === s || "," === s ? 1 : 0),
	        u = q > 0 ? a.substring(t, m) : "";
	      if (a = a.substring(n, t), b = "-" === a.charAt(0) ? -b : +b, c = b < 0 ? b = -b : 0, d = a.match(/[^\d\-\+#]/g), e = d && d[d.length - 1] || ".", f = d && d[1] && d[0] || ",", a = a.split(e), b = b.toFixed(a[1] && a[1].length), b = +b + "", h = a[1] && a[1].lastIndexOf("0"), j = b.split("."), (!j[1] || j[1] && j[1].length <= h) && (b = (+b).toFixed(h + 1)), k = a[0].split(f), a[0] = k.join(""), g = a[0] && a[0].indexOf("0"), g > -1) for (; j[0].length < a[0].length - g;) j[0] = "0" + j[0];else 0 === +j[0] && (j[0] = "");
	      if (b = b.split("."), b[0] = j[0], i = k[1] && k[k.length - 1].length) {
	        for (l = b[0], p = "", r = l.length % i, m = l.length, t = 0; t < m; t++) p += l.charAt(t), !((t - r + 1) % i) && t < m - i && (p += f);
	        b[0] = p;
	      }
	      return b[1] = a[1] && b[1] ? e + b[1] : "", d = b.join(""), "0" !== d && "" !== d || (c = false), o + ((c ? "-" : "") + d) + u;
	    };
	  });
	});

	// 1.95.toFixed(1) = 1.9
	// 2.95.toFixed(1) = 3.0
	const EPSILON$1 = 1e-15; // To make sure toFixed always round up.

	function escapeRegExp$1(str) {
	  return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
	}
	const SIprefixes = {
	    3: 'k',
	    6: 'M',
	    9: 'G',
	    12: 'T',
	    15: 'P',
	    18: 'E',
	    21: 'Z',
	    24: 'Y',
	    '-3': 'm',
	    '-6': 'μ',
	    '-9': 'n',
	    '-12': 'p',
	    '-15': 'f',
	    '-18': 'a',
	    '-21': 'z',
	    '-24': 'y'
	  },
	  percentage = /%\)?$/,
	  //    scientific = /e[\+\-][0-9]+/,
	  radix = /^\(r(0[2-9]|[12]\d|3[0-6])\)/i,
	  oct = /^\(oct\)/i,
	  dec = /^\(dec\)/i,
	  hex$1 = /^\(hex\)/i,
	  bin = /^\(bin\)/i,
	  rom = /^\(rom\)/i,
	  functional = /^(\(rom\)|\(bin\)|\(hex\)|\(dec\)|\(oct\)|\(r(0[2-9]|[12]\d|3[0-6])\))/i,
	  prec = /#|0/g;
	function formatRadix(value, fradix, pattern, decimal) {
	  value = value.toString(fradix);
	  if (pattern[1] === pattern[1].toUpperCase()) {
	    value = value.toUpperCase();
	  }
	  if (value.length - value.indexOf('.') > 10) {
	    // limit to 10 decimal places
	    value = value.slice(0, value.indexOf('.') + 11);
	  }
	  return value.replace('.', decimal || '.');
	}

	// value must be an integer
	// value must not be in scientific notation
	function formatRoman(value, pattern) {
	  let i,
	    s = '',
	    v = Number(String(value).slice(-3)),
	    nThousands = (value - v) / 1000,
	    decimal = [0, 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900].reverse(),
	    numeral = ['0', 'I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM'].reverse();
	  while (v > 0) {
	    for (i = 0; i < decimal.length; i++) {
	      if (decimal[i] <= v) {
	        s += numeral[i];
	        v -= decimal[i];
	        break;
	      }
	    }
	  }
	  for (i = 0; i < nThousands; i++) {
	    s = "M".concat(s);
	  }
	  if (pattern[1] !== pattern[1].toUpperCase()) {
	    s = s.toLowerCase();
	  }
	  return s;
	}
	function formatFunctional(value, pattern, d) {
	  let temp;
	  if (radix.test(pattern)) {
	    value = formatRadix(value, Number(/\d{2}/.exec(pattern)[0]), pattern, d);
	  } else if (oct.test(pattern)) {
	    value = formatRadix(value, 8, pattern, d);
	  } else if (dec.test(pattern)) {
	    value = formatRadix(value, 10, pattern, d);
	  } else if (hex$1.test(pattern)) {
	    value = formatRadix(value, 16, pattern, d);
	  } else if (bin.test(pattern)) {
	    value = formatRadix(value, 2, pattern, d);
	  } else if (rom.test(pattern)) {
	    temp = '';
	    if (value < 0) {
	      temp = '-';
	      value = -value;
	    }
	    value = Math.floor(value);
	    if (value === 0) {
	      value = '0';
	    } else if (value <= 500000) {
	      // limit in engine
	      value = formatRoman(value, pattern);
	      value = temp + value;
	    } else {
	      value = pattern + temp + value.toExponential(0); // to return same result as engine
	    }
	  }
	  return value;
	}
	function escape(value, flags, justStr) {
	  const str = escapeRegExp$1(value);
	  if (justStr) {
	    return str;
	  }
	  return new RegExp(str || '', flags);
	}
	function createRegExp$1(thousand, decimal) {
	  if (decimal) {
	    decimal = escapeRegExp$1(decimal);
	  }
	  if (thousand) {
	    thousand = escapeRegExp$1(thousand);
	  }
	  return new RegExp("(?:[#0]+".concat(thousand, ")?[#0]+(?:").concat(decimal, "[#0]+)?"));
	}
	function getAbbreviations(localeInfo, listSeparator) {
	  if (!localeInfo || !localeInfo.qNumericalAbbreviation) {
	    return SIprefixes;
	  }
	  const abbreviations = {};
	  let abbrs = localeInfo.qNumericalAbbreviation.split(listSeparator);
	  abbrs.forEach(abbreviation => {
	    let abbreviationTuple = abbreviation.split(':');
	    if (abbreviationTuple.length === 2) {
	      abbreviations[abbreviationTuple[0]] = abbreviationTuple[1];
	    }
	  });
	  return abbreviations;
	}
	function preparePattern(o, t, d, abbreviate) {
	  let parts,
	    lastPart,
	    pattern = o.pattern,
	    numericPattern,
	    prefix,
	    postfix,
	    groupTemp,
	    decTemp,
	    temp,
	    regex;
	  if (abbreviate) {
	    o.abbreviate = true;
	  }

	  // extract the numeric part from the pattern
	  regex = createRegExp$1(t, d);
	  numericPattern = pattern.match(regex);
	  numericPattern = numericPattern ? numericPattern[0] : '';
	  prefix = numericPattern ? pattern.substr(0, pattern.indexOf(numericPattern)) : pattern;
	  postfix = numericPattern ? pattern.substring(pattern.indexOf(numericPattern) + numericPattern.length) : '';
	  if (!numericPattern) {
	    numericPattern = pattern ? '#' : '##########';
	  }
	  if (t && t === d) {
	    // ignore grouping if grouping separator is same as decimal separator
	    // extract decimal part
	    parts = numericPattern.split(d);
	    lastPart = parts.pop();
	    numericPattern = parts.join('') + d + lastPart;
	    t = '';
	  }

	  // formatting library does not support multiple characters as separator (nor +-).
	  // do a temporary replacement
	  groupTemp = t;
	  t = /,/.test(d) ? '¤' : ',';
	  if (groupTemp) {
	    numericPattern = numericPattern.replace(escape(groupTemp, 'g'), t);
	  }
	  decTemp = d;
	  d = '.';
	  if (decTemp) {
	    numericPattern = numericPattern.replace(escape(decTemp, 'g'), d);
	  }
	  temp = numericPattern.match(/#/g);
	  temp = temp ? temp.length : 0;
	  const splitPattern = pattern.split(decTemp);
	  let matchPrecisionResult;
	  if (splitPattern[1]) {
	    matchPrecisionResult = splitPattern[1].match(prec);
	  }
	  o.prefix = prefix || '';
	  o.postfix = postfix || '';
	  o.pattern = pattern;
	  o.maxPrecision = matchPrecisionResult ? matchPrecisionResult.length : 2;
	  o.percentage = percentage.test(pattern);
	  o.numericPattern = numericPattern || '';
	  o.numericRegex = new RegExp("".concat(escape(t, null, true), "|").concat(escape(d, null, true)), 'g');
	  o.groupTemp = groupTemp;
	  o.decTemp = decTemp;
	  o.t = t;
	  o.d = d;
	  o.temp = temp;
	}
	class NumberFormatter {
	  /**
	   * @name NumberFormatter
	   * @constructs
	   * @param {Object} localeInfo
	   * @param {String} pattern
	   * @param {String} [thousand]
	   * @param {String} [decimal]
	   * @param {String} [type]
	   */
	  constructor(localeInfo, pattern, thousand, decimal, type) {
	    this.localeInfo = localeInfo;
	    this.pattern = pattern;
	    this.thousandDelimiter = thousand || ',';
	    this.decimalDelimiter = decimal || '.';
	    this.type = type || 'numeric';

	    // FIXME qListSep?
	    // this.patternSeparator = this.localeInfo && this.localeInfo.qListSep ? this.localeInfo.qListSep : ';';
	    this.patternSeparator = ';';
	    this.abbreviations = getAbbreviations(localeInfo, this.patternSeparator);
	    this.prepare();
	  }
	  clone() {
	    const n = new NumberFormatter(this.localeInfo, this.pattern, this.thousandDelimiter, this.decimalDelimiter, this.type);
	    n.subtype = this.subtype;
	    return n;
	  }

	  /**
	   * Formats a number according to a specific pattern.
	   * Use # for optional numbers and 0 for padding.
	   * @param {Number} value Number to format.
	   * @param {String} [pattern] The pattern to apply.
	   * @param {String} [t] Grouping separator.
	   * @param {String} [d] Decimal delimiter.
	   * @example
	   * format(10, "0") // 10;
	   * format(10, "#") // 10;
	   * format(10, "##.#") // 10;
	   * format(10, "##.0") // 10.0;
	   * format(10, "000") // 010;
	   * format(10.123, "0.0") // 10.1;
	   * format(10.123, "0.00##") // 10.123; // at least 2 decimals, never more than 4
	   * format(123456789, "#,###") // 123,456,789;
	   * format(123456789, "####-####", "-") // 1-2345-6789;
	   *
	   * format(0.257, "0.0%") // 25.7%; // will multiply by 100
	   * format(9876, "$#,###") // $9,876;
	   * format(-9876, "$#,###;$(#,###)") // $(9,876); // use ; for alternative formatting for negative values
	   * format(10, "(r16)") // a; // radix 16
	   * format(15, "(hex)") // f; // same as (r16)
	   * format(15, "(HEX)") // F;
	   * format(10, "(bin)") // 1010; // same as (r02)
	   * format(10, "(oct)") // 12; // same as (r08)
	   */
	  format(value, pattern, t, d) {
	    this.prepare(pattern, t, d);
	    return this.formatValue(value);
	  }
	  prepare(pattern, t, d) {
	    let prep;
	    if (typeof pattern === 'undefined') {
	      pattern = this.pattern;
	    }
	    if (typeof t === 'undefined') {
	      t = this.thousandDelimiter;
	    }
	    if (typeof d === 'undefined') {
	      d = this.decimalDelimiter;
	    }
	    if (!pattern) {
	      this._prepared = {
	        pattern: false
	      };
	      return;
	    }
	    this._prepared = {
	      positive: {
	        d,
	        t,
	        abbreviate: false,
	        isFunctional: false,
	        prefix: '',
	        postfix: ''
	      },
	      negative: {
	        d,
	        t,
	        abbreviate: false,
	        isFunctional: false,
	        prefix: '',
	        postfix: ''
	      },
	      zero: {
	        d,
	        t,
	        abbreviate: false,
	        isFunctional: false,
	        prefix: '',
	        postfix: ''
	      }
	    };
	    prep = this._prepared;
	    pattern = pattern.split(this.patternSeparator);
	    prep.positive.pattern = pattern[0];
	    prep.negative.pattern = pattern[1];
	    prep.zero.pattern = pattern[2];
	    if (functional.test(pattern[0])) {
	      prep.positive.isFunctional = true;
	    }
	    if (!pattern[1]) {
	      prep.negative = false;
	    } else if (functional.test(pattern[1])) {
	      prep.negative.isFunctional = true;
	    }
	    if (!pattern[2]) {
	      prep.zero = false;
	    } else if (functional.test(pattern[2])) {
	      prep.zero.isFunctional = true;
	    }
	    const abbreviate = this.type === 'U';
	    if (!prep.positive.isFunctional) {
	      preparePattern(prep.positive, t, d, abbreviate);
	    }
	    if (prep.negative && !prep.negative.isFunctional) {
	      preparePattern(prep.negative, t, d, abbreviate);
	    }
	    if (prep.zero && !prep.zero.isFunctional) {
	      preparePattern(prep.zero, t, d, abbreviate);
	    }
	  }
	  formatValue(value) {
	    let prep = this._prepared,
	      temp,
	      exponent,
	      abbr = '',
	      absValue,
	      num,
	      sciValue = '',
	      d,
	      t,
	      i,
	      numericPattern,
	      decimalPartPattern,
	      original = value;
	    if (isNaN(value)) {
	      return "".concat(original);
	    }
	    value = +value;
	    if (prep.pattern === false) {
	      return value.toString();
	    }
	    if (value === 0 && prep.zero) {
	      prep = prep.zero;
	      return prep.pattern;
	    }
	    if (value < 0 && prep.negative) {
	      prep = prep.negative;
	      value = -value;
	    } else {
	      prep = prep.positive;
	    }
	    d = prep.d;
	    t = prep.t;
	    if (prep.isFunctional) {
	      value = formatFunctional(value, prep.pattern, d);
	    } else {
	      if (prep.percentage) {
	        value *= 100;
	      }
	      if (prep.abbreviate) {
	        const abbrArray = Object.keys(this.abbreviations).map(key => parseInt(key, 10)).sort((a, b) => a - b);
	        let lowerAbbreviation;
	        let upperAbbreviation = abbrArray[0];
	        i = 0;
	        exponent = Number(Number(value).toExponential().split('e')[1]);
	        while (upperAbbreviation <= exponent && i < abbrArray.length) {
	          i++;
	          upperAbbreviation = abbrArray[i];
	        }
	        if (i > 0) {
	          lowerAbbreviation = abbrArray[i - 1];
	        }
	        let suggestedAbbrExponent;

	        // value and lower abbreviation is for values above 10, use the lower (move to the left <==)
	        if (lowerAbbreviation && exponent > 0 && lowerAbbreviation > 0) {
	          suggestedAbbrExponent = lowerAbbreviation;
	          // value and lower abbreviation is for values below 0.1 (move to the right ==>)
	        } else if (exponent < 0 && lowerAbbreviation < 0 || !lowerAbbreviation) {
	          // upper abbreviation is also for values below 0.1 and precision allows for using the upper abbreviation(move to the right ==>)
	          if (upperAbbreviation < 0 && upperAbbreviation - exponent <= prep.maxPrecision) {
	            suggestedAbbrExponent = upperAbbreviation;
	            // lower abbrevaition is smaller than exponent and we can't get away with not abbreviating
	          } else if (lowerAbbreviation <= exponent && !(upperAbbreviation > 0 && -exponent <= prep.maxPrecision)) {
	            // (move to left <==)
	            suggestedAbbrExponent = lowerAbbreviation;
	          }
	        }
	        if (suggestedAbbrExponent) {
	          abbr = this.abbreviations[suggestedAbbrExponent];
	          value /= 10 ** suggestedAbbrExponent;
	        }
	      }
	      absValue = Math.abs(value);
	      temp = prep.temp;
	      numericPattern = prep.numericPattern;
	      decimalPartPattern = numericPattern.split(d)[1];
	      if (this.type === 'I') {
	        value = Math.round(value);
	      }
	      num = value;
	      if (!decimalPartPattern && numericPattern.slice(-1)[0] === '#') {
	        if (absValue >= 10 ** temp || absValue < 1 || absValue < 1e-4) {
	          if (value === 0) {
	            value = '0';
	          } else if (absValue < 1e-4 || absValue >= 1e20) {
	            // engine always formats values < 1e-4 in scientific form, values >= 1e20 can only be represented in scientific form
	            value = num.toExponential(Math.max(1, Math.min(14, temp)) - 1);
	            value = value.replace(/\.?0+(?=e)/, '');
	            sciValue = '';
	          } else {
	            value = value.toPrecision(Math.max(1, Math.min(14, temp)));
	            if (value.indexOf('.') >= 0) {
	              value = value.replace(value.indexOf('e') < 0 ? /0+$/ : /\.?0+(?=e)/, '');
	              value = value.replace('.', d);
	            }
	          }
	        } else {
	          numericPattern += d;
	          temp = Math.max(0, Math.min(20, temp - Math.ceil(Math.log(absValue) / Math.log(10))));
	          for (i = 0; i < temp; i++) {
	            numericPattern += '#';
	          }
	          value = format_min(numericPattern, value);
	        }
	      } else if (absValue >= 1e15 || absValue > 0 && absValue <= 1e-14) {
	        value = absValue ? absValue.toExponential(15).replace(/\.?0+(?=e)/, '') : '0';
	      } else {
	        const sign = value < 0 ? -1 : 1;
	        const wholePart = Number((value + EPSILON$1 * sign).toFixed(Math.min(20, decimalPartPattern ? decimalPartPattern.length : 0)).split('.')[0]);
	        let wholePartPattern = numericPattern.split(d)[0];
	        wholePartPattern += d;
	        value = format_min(wholePartPattern, wholePart) || '0';
	        if (decimalPartPattern) {
	          const nDecimals = Math.max(0, Math.min(14, decimalPartPattern.length)); // the length of e.g. 0000#####
	          const nZeroes = decimalPartPattern.replace(/#+$/, '').length;
	          let decimalPart = (this.type === 'I' ? 0 : absValue % 1 + EPSILON$1).toFixed(nDecimals).slice(2).replace(/0+$/, ''); // remove trailing zeroes

	          for (i = decimalPart.length; i < nZeroes; i++) {
	            decimalPart += '0';
	          }
	          if (decimalPart) {
	            value += d + decimalPart;
	          }
	        } else if (wholePart === 0) {
	          // to avoid "-" being prefixed to value
	          num = 0;
	        }
	      }
	      value = value.replace(prep.numericRegex, m => {
	        if (m === t) {
	          return prep.groupTemp;
	        }
	        if (m === d) {
	          return prep.decTemp;
	        }
	        return '';
	      });
	      if (num < 0 && !/^-/.test(value)) {
	        value = "-".concat(value);
	      }
	    }
	    return prep.prefix + value + sciValue + abbr + prep.postfix;
	  }
	  static getStaticFormatter() {
	    return {
	      prepare() {},
	      formatValue(v) {
	        return "".concat(v);
	      }
	    };
	  }
	}
	function numberFormatFactory() {
	  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
	    args[_key] = arguments[_key];
	  }
	  return new NumberFormatter(...args);
	}
	function memoize(func) {
	  let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	  const {
	    size = 5000,
	    multipleArguments = false,
	    toKey = arg => arg
	  } = opts;
	  let cache = Object.create(null);
	  let index = Object.create(null);
	  let counter = 0;
	  let fifo = 0; // First-In-First-Out index
	  let cacher;
	  let k;
	  if (multipleArguments) {
	    cacher = function () {
	      k = toKey(...arguments);
	      if (cacher.has(k)) {
	        return cacher.get(k);
	      }
	      return cacher.set(k, func(...arguments));
	    };
	  } else {
	    cacher = arg => {
	      k = toKey(arg);
	      if (cacher.has(k)) {
	        return cacher.get(k);
	      }
	      return cacher.set(k, func(arg));
	    };
	  }
	  cacher.set = (key, val) => {
	    if (counter >= size) {
	      delete cache[index[fifo]];
	      delete index[fifo];
	      counter--;
	      fifo++;
	    }
	    cache[key] = val;
	    index[counter] = key;
	    counter++;
	    return val;
	  };
	  cacher.get = key => cache[key];
	  cacher.has = key => key in cache;
	  cacher.clear = () => {
	    cache = Object.create(null);
	    index = Object.create(null);
	    counter = 0;
	    fifo = 0;
	  };
	  cacher.size = () => counter;
	  return cacher;
	}
	function formatter$1(pattern, thousand, decimal, qType, localeInfo) {
	  const qformat = numberFormatFactory(localeInfo, pattern, thousand, decimal, qType);
	  const memoized = memoize(qformat.formatValue.bind(qformat), {
	    // Handle NaN and cases where toString yields different result than +operator. Ex. a Date.
	    toKey: value => isNaN(value) ? value : +value
	  });

	  /**
	   * Format a value according to the specified pattern created at construct
	   *
	   * @param  {Number} value   The number to be formatted
	   * @return {String}         [description]
	   */
	  function format(value) {
	    return memoized(value);
	  }

	  /**
	   * Format a value according to a specific pattern
	   * that is not the one specified in the constructor
	   *
	   * @param  {String} p   Pattern
	   * @param  {Number} v   Value
	   * @param  {String} t   Thousand
	   * @param  {String} d   Decimal
	   * @return {String}     Formatted value
	   */
	  format.format = function formatFn(p, v, t, d) {
	    memoized.clear();
	    return qformat.format(v, p, t, d);
	  };

	  /**
	   * Change the pattern on existing formatter
	   *
	   * @param  {String} p     Pattern (optional)
	   * @return {String}       Returns the pattern
	   */
	  format.pattern = function patternFn(p) {
	    if (p) {
	      memoized.clear();
	      qformat.pattern = p;
	      qformat.prepare();
	    }
	    return qformat.pattern;
	  };

	  /**
	   * Set the locale for the formatter
	   *
	   * @param  {Object} args   Locale object for formatting
	   * @return {Undefined}      Returns nothing
	   */
	  /* format.locale = function( ...args ) {
	    locale = formatLocale( ...args );
	    d3format = locale.format( pattern );
	     return this;
	  }; */

	  return format;
	}

	/* eslint import/prefer-default-export: 0 */

	const TYPES = {
	  DATE: 'D',
	  TIME: 'T',
	  DATE_TIME: 'TS',
	  INTERVAL: 'IV'
	};
	const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
	const DAYS_ABBR = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
	const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
	const MONTHS_ABBR = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
	const SECONDS_PER_DAY = 86400;
	function pad(s, n) {
	  for (let i = s.length; i < n; i++) {
	    s = "0".concat(s);
	  }
	  return s;
	}
	function parseDate(d, twelveFormat) {
	  let h = d.getUTCHours();
	  let day = d.getUTCDay() - 1;
	  if (twelveFormat) {
	    h %= 12;
	    if (!h) {
	      // h == 0 -> 12
	      h = 12;
	    }
	  }
	  if (day < 0) {
	    day = 6;
	  }
	  return {
	    year: d.getUTCFullYear(),
	    month: d.getUTCMonth(),
	    day,
	    date: d.getUTCDate(),
	    h,
	    m: d.getUTCMinutes(),
	    s: d.getUTCSeconds(),
	    f: d.getUTCMilliseconds(),
	    t: d.getUTCHours() >= 12 ? 'pm' : 'am'
	  };
	}
	function getRemainder(value) {
	  let s = value.toString().split('.');
	  if (s[1]) {
	    s = Number("0.".concat(s[1]));
	  } else {
	    return 0;
	  }
	  return s;
	}
	function parseIntervalDays(days) {
	  const d = days;
	  const h = 24 * getRemainder(d);
	  const m = 60 * getRemainder(h);
	  const s = 60 * getRemainder(m);
	  const ms = 1000 * getRemainder(s);
	  return {
	    d: Math.floor(d),
	    h: Math.floor(h),
	    m: Math.floor(m),
	    s: Math.floor(s),
	    f: Math.round(ms)
	  };
	}
	function parseInterval(days, pattern) {
	  let units = parseIntervalDays(days),
	    d = units.d,
	    h = units.h,
	    m = units.m,
	    s = units.s,
	    f = units.f,
	    w = 0,
	    date;
	  if (/w+|t+/gi.test(pattern)) {
	    date = new Date(Date.UTC(1899, 11, 30 + Math.floor(days), 0, 0, Math.round(SECONDS_PER_DAY * (days - Math.floor(days)))));
	    if (isNaN(date.getTime())) {
	      date = null;
	    }
	  }
	  if (!/D+/gi.test(pattern)) {
	    h += d * 24;
	  }
	  if (!/h+/gi.test(pattern)) {
	    m += h * 60;
	  }
	  if (!/m+/gi.test(pattern)) {
	    s += m * 60;
	  }
	  if (/w+/gi.test(pattern)) {
	    w = date ? date.getDay() - 1 : 0;
	    if (w < 0) {
	      w = 6;
	    }
	  }
	  let someT = '';
	  if (date) {
	    someT = date.getUTCHours() >= 12 ? 'pm' : 'am';
	  }
	  return {
	    year: 0,
	    month: 0,
	    day: w,
	    date: d,
	    h,
	    m,
	    s,
	    f,
	    t: someT
	  };
	}
	function getMasks(inst, d) {
	  return {
	    'Y+|y+': {
	      Y: "".concat(Number("".concat(d.year).slice(-2))),
	      YY: pad("".concat(d.year).slice(-2), 2),
	      YYY: pad("".concat(d.year).slice(-3), 3),
	      def(m) {
	        // default
	        return pad("".concat(d.year), m.length);
	      }
	    },
	    'M+': {
	      M: d.month + 1,
	      MM: pad("".concat(d.month + 1), 2),
	      MMM: inst.locale_months_abbr[d.month],
	      def: inst.locale_months[d.month]
	    },
	    'W+|w+': {
	      W: d.day,
	      WW: pad("".concat(d.day), 2),
	      WWW: inst.locale_days_abbr[d.day],
	      def: inst.locale_days[d.day]
	    },
	    'D+|d+': {
	      D: d.date,
	      def(m) {
	        return pad("".concat(d.date), m.length);
	      }
	    },
	    'h+|H+': {
	      h: d.h,
	      def(m) {
	        return pad("".concat(d.h), m.length);
	      }
	    },
	    'm+': {
	      m: d.m,
	      def(m) {
	        return pad("".concat(d.m), m.length);
	      }
	    },
	    's+|S+': {
	      s: d.s,
	      def(m) {
	        return pad("".concat(d.s), m.length);
	      }
	    },
	    'f+|F+': {
	      def(m) {
	        let f = "".concat(d.f),
	          n = m.length - f.length;
	        if (n > 0) {
	          for (let i = 0; i < n; i++) {
	            f += '0';
	          }
	        } else if (n < 0) {
	          f = f.slice(0, m.length);
	        }
	        return f;
	      }
	    },
	    't{1,2}|T{1,2}': {
	      def(m) {
	        let t = d.t;
	        if (m[0].toUpperCase() === m[0]) {
	          t = t.toUpperCase();
	        }
	        t = t.slice(0, m.length);
	        return t;
	      }
	    }
	  };
	}
	class DateFormatter {
	  /**
	   * @name DateFormatter
	   * @constructs
	   * @param {Object} localeInfo
	   * @param {String} pattern
	   */
	  constructor(localeInfo, pattern, qtype) {
	    const info = localeInfo || {};
	    if (!info.qCalendarStrings) {
	      info.qCalendarStrings = {
	        qLongDayNames: DAYS,
	        qDayNames: DAYS_ABBR,
	        qLongMonthNames: MONTHS,
	        qMonthNames: MONTHS_ABBR
	      };
	    }
	    this.localeInfo = info;
	    this.locale_days = info.qCalendarStrings.qLongDayNames.slice();
	    this.locale_days_abbr = info.qCalendarStrings.qDayNames.slice();
	    this.locale_months = info.qCalendarStrings.qLongMonthNames.slice();
	    this.locale_months_abbr = info.qCalendarStrings.qMonthNames.slice();
	    if (!pattern) {
	      const patternMap = {
	        [TYPES.TIME]: info.qTimeFmt || 'hh:mm:ss',
	        [TYPES.DATE]: info.qDateFmt || 'YYYY-MM-DD',
	        [TYPES.DATE_TIME]: info.qTimestampFmt || 'YYYY-MM-DD hh:mm:ss'
	      };
	      pattern = patternMap[qtype];
	    }
	    this.pattern = pattern;
	  }
	  clone() {
	    const n = new DateFormatter(this.localeInfo, this.pattern);
	    n.subtype = this.subtype;
	    return n;
	  }

	  /**
	   * Formats a date according to given pattern
	   * @param {Date} date The date to format.
	   * @param {String} pattern The desired format of the date
	   * var d = new Date(2013, 8, 15, 13, 55, 40, 987);
	   * var n = new DateFormatter();
	   * @example
	   * m.format( d, 'YYYY-MM-DD hh:mm:ss.ffff') // 2013-08-15 13:55:40.9870
	   * m.format( d, 'h:m:s tt') // 1:55:40 pm
	   * m.format( d, 'h:m:s TT') // 1:55:40 PM
	   * m.format( d, 'M/D/YYYY') // 8/15/2013
	   * m.format( d, 'WWWW DD MMM') // Thursday 15 Aug
	   * m.format( d, 'WWW DD MMMM @ hh:mm:ss') // Thu 15 August @ 13:55:40
	   */
	  format(date, pattern) {
	    // Fallback pattern is set in constructor
	    if (!pattern) {
	      pattern = this.pattern ? this.pattern : 'YYYY-MM-DD hh:mm:ss';
	    }
	    pattern = pattern.replace(/\[.+]|\[|]/g, '');
	    const hasTwelveFlag = /t+/gi.test(pattern);
	    let parsedDate;
	    if (date instanceof Date) {
	      parsedDate = parseDate(date, hasTwelveFlag);
	    } else {
	      if (date < 0) {
	        // parseInterval don't support for negative values
	        date = -date;
	        pattern = "-".concat(pattern);
	      }
	      parsedDate = parseInterval(date, pattern);
	    }
	    // remove [] and everything inside it

	    const masks = getMasks(this, parsedDate);
	    const masksArr = [];
	    for (const mask in masks) {
	      if (Object.prototype.hasOwnProperty.call(masks, mask)) {
	        masksArr.push(mask);
	      }
	    }
	    const dateTimeRegex = new RegExp(masksArr.join('|'), 'g');
	    const result = pattern.replace(dateTimeRegex, m => {
	      let r;
	      let mask;
	      for (mask in masks) {
	        if (Object.prototype.hasOwnProperty.call(masks, mask)) {
	          r = new RegExp(mask);
	          if (r.test(m)) {
	            break;
	          }
	        }
	      }
	      if (!r) {
	        return '';
	      }
	      let value;
	      for (const submask in masks[mask]) {
	        if (submask === m || submask.toLowerCase() === m) {
	          value = masks[mask][submask];
	          if (typeof value === 'undefined') {
	            value = masks[mask][submask.toLowerCase()];
	          }
	          break;
	        }
	      }
	      if (typeof value === 'undefined') {
	        value = masks[mask].def;
	      }
	      if (typeof value === 'function') {
	        value = value(m);
	      }
	      return value;
	    });
	    return result;
	  }
	}
	function dateFormatFactory() {
	  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
	    args[_key] = arguments[_key];
	  }
	  return new DateFormatter(...args);
	}
	const MS_PER_DAY = 86400000;
	function QlikTimeToDate(value) {
	  return new Date(Date.UTC(1899, 11, 30 + Math.floor(value), 0, 0, 0, Math.round(MS_PER_DAY * (value - Math.floor(value)))));
	}
	function formatter(pattern) {
	  let qtype = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'TS';
	  let localeInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
	  let qformat = dateFormatFactory(localeInfo, pattern, qtype);
	  let memoized = memoize(qformat.format.bind(qformat), {
	    toKey: date => typeof date === 'object' && typeof date.getTime === 'function' ? date.getTime() : date
	  });

	  /**
	   * Prepare a value according to the specified qtype
	   *
	   * @param  {Number} value The value to be formatted
	   * @return {Number}       The converted value (if applied)
	   */
	  function prepare(value) {
	    if (qtype !== TYPES.INTERVAL) {
	      return QlikTimeToDate(value);
	    }
	    return value;
	  }

	  /**
	   * Format a value according to the specified pattern created at construct
	   *
	   * @param  {Date} value   The number to be formatted
	   * @return {String}         [description]
	   */
	  function format(value) {
	    value = prepare(value);
	    return memoized(value);
	  }

	  /**
	   * Format a value according to a specific pattern
	   * that is not the one specified in the constructor
	   *
	   * @param  {String} p   Pattern
	   * @param  {Date} v   Value
	   * @return {String}     Formatted value
	   */
	  format.format = function formatFn(p, v) {
	    memoized.clear();
	    v = prepare(v);
	    return qformat.format(v, p);
	  };

	  /**
	   * Set the locale for the formatter
	   *
	   * @param  {Object} args   Locale object for formatting
	   * @return {Undefined}      Returns nothing
	   */
	  format.locale = function locale(li) {
	    qformat = dateFormatFactory(li, pattern, qtype);
	    memoized = memoize(qformat.format.bind(qformat), {
	      toKey: date => typeof date === 'object' ? date.getTime() : date
	    });
	    return this;
	  };

	  /**
	   * Get or set the QType
	   *
	   * @param  {String} nqt New qType (optional)
	   * @return {String}     Current qtype
	   */
	  format.qtype = function qtypeFn(nqt) {
	    if (nqt !== undefined) {
	      qtype = nqt;
	      memoized.clear();
	    }
	    return qtype;
	  };
	  return format;
	}
	function createFromMetaInfo(meta, localeInfo) {
	  if (meta && meta.qNumFormat && ['D', 'T', 'TS', 'IV'].indexOf(meta.qNumFormat.qType) !== -1) {
	    return formatter(meta.qNumFormat.qFmt, meta.qNumFormat.qType, localeInfo);
	  }
	  let pattern = '#';
	  let thousand = localeInfo && typeof localeInfo.qThousandSep !== 'undefined' ? localeInfo.qThousandSep : ',';
	  let decimal = localeInfo && typeof localeInfo.qDecimalSep !== 'undefined' ? localeInfo.qDecimalSep : '.';
	  let type = 'U';
	  let isAuto = meta && !!meta.qIsAutoFormat;
	  if (meta && meta.qNumFormat) {
	    pattern = meta.qNumFormat.qFmt || pattern;
	    thousand = meta.qNumFormat.qThou || thousand;
	    decimal = meta.qNumFormat.qDec || decimal;
	    type = meta.qNumFormat.qType || type;
	    isAuto = isAuto && ['M'].indexOf(meta.qNumFormat.qType) === -1;
	  } else {
	    isAuto = true;
	  }
	  if (isAuto || type === 'U') {
	    pattern = "#".concat(decimal, "##");
	    type = 'U';
	  }
	  return formatter$1(pattern, thousand, decimal, type, localeInfo);
	}
	function qField() {
	  let {
	    meta,
	    id,
	    key,
	    localeInfo,
	    fieldExtractor,
	    value,
	    type,
	    sourceField
	  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	  let values;
	  const valueFn = value || (type === 'dimension' ? d => d === null || d === void 0 ? void 0 : d.qElemNo : d => d === null || d === void 0 ? void 0 : d.qValue);
	  const labelFn = d => (d === null || d === void 0 ? void 0 : d.qText) || '';
	  const reduce = type === 'dimension' ? 'first' : 'avg';
	  const formatter = createFromMetaInfo(meta, localeInfo);
	  const reduceLabel = type === 'dimension' ? 'first' : (labels, v) => formatter(v);
	  const f = {
	    id: () => id,
	    key: () => key,
	    raw: () => meta,
	    title: () => meta.qFallbackTitle || meta.label,
	    type: () => type,
	    origin: () => sourceField,
	    items: () => {
	      if (!values) {
	        values = fieldExtractor(f);
	      }
	      return values;
	    },
	    min: () => meta.qMin,
	    max: () => meta.qMax,
	    value: valueFn,
	    label: labelFn,
	    reduce,
	    reduceLabel,
	    formatter: () => formatter,
	    tags: () => meta.qTags
	  };
	  return f;
	}
	function createFields(path, obj, prefix, parentKey, opts) {
	  return (obj[path] || []).map((meta, i) => {
	    const fieldKey = "".concat(parentKey ? "".concat(parentKey, "/") : '').concat(path, "/").concat(i);
	    const f = {
	      instance: qField(extend$3({
	        id: "".concat(prefix ? "".concat(prefix, "/") : '').concat(fieldKey),
	        key: fieldKey,
	        meta
	      }, opts))
	    };
	    f.attrDims = createFields('qAttrDimInfo', meta, prefix, fieldKey, extend$3({}, opts, {
	      value: v => v === null || v === void 0 ? void 0 : v.qElemNo,
	      type: 'dimension'
	    }));
	    f.attrExps = createFields('qAttrExprInfo', meta, prefix, fieldKey, extend$3({}, opts, {
	      value: v => v === null || v === void 0 ? void 0 : v.qNum,
	      type: 'measure'
	    }));
	    f.measures = createFields('qMeasureInfo', meta, prefix, fieldKey, extend$3({}, opts, {
	      value: v => v === null || v === void 0 ? void 0 : v.qValue,
	      type: 'measure'
	    }));
	    return f;
	  });
	}
	function q() {
	  let {
	    key,
	    data,
	    config = {}
	  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	  const cache = {
	    fields: [],
	    wrappedFields: [],
	    allFields: [],
	    virtualFields: []
	  };
	  const cube = data;
	  if (!cube) {
	    throw new Error('Missing "data" input');
	  }
	  if (!cube.qDimensionInfo) {
	    throw new Error('The "data" input is not recognized as a hypercube');
	  }
	  const deps = q.util;
	  const opts = {
	    cache,
	    cube,
	    localeInfo: config.localeInfo,
	    fieldExtractor: null,
	    pages: null,
	    hierarchy: () => null,
	    virtualFields: config.virtualFields
	  };
	  const dataset = {
	    key: () => key,
	    raw: () => cube,
	    field: query => findField$1(query, opts),
	    fields: () => cache.fields.slice(),
	    extract: extractionConfig => opts.extractor(extractionConfig, dataset, cache, deps),
	    hierarchy: hierarchyConfig => opts.hierarchy(hierarchyConfig, dataset, cache, deps),
	    _cache: () => cache
	  };
	  if (cube.qMode === 'K' || cube.qMode === 'T' || !cube.qMode && cube.qNodesOnDim) {
	    opts.extractor = extract;
	    opts.hierarchy = augment;
	    opts.pages = cube.qMode === 'K' ? cube.qStackedDataPages : cube.qTreeDataPages;
	  } else if (cube.qMode === 'S') {
	    opts.extractor = extract$1;
	    opts.pages = cube.qDataPages;
	    opts.hierarchy = augment;
	  } else {
	    opts.extractor = () => []; // TODO - throw unsupported error?
	  }
	  opts.fieldExtractor = f => opts.extractor({
	    field: f
	  }, dataset, cache, deps);
	  const dimAcc = cube.qMode === 'S' ? d => d.qElemNumber : undefined;
	  const measAcc = cube.qMode === 'S' ? d => d.qNum : undefined;
	  cache.wrappedFields.push(...createFields('qDimensionInfo', cube, key, '', extend$3({}, opts, {
	    value: dimAcc,
	    type: 'dimension'
	  })));
	  cache.wrappedFields.push(...createFields('qMeasureInfo', cube, key, '', extend$3({}, opts, {
	    value: measAcc,
	    type: 'measure'
	  })));
	  cache.fields = cache.wrappedFields.map(f => f.instance);
	  const traverse = arr => {
	    arr.forEach(f => {
	      cache.allFields.push(f.instance);
	      traverse(f.measures);
	      traverse(f.attrDims);
	      traverse(f.attrExps);
	    });
	  };
	  traverse(cache.wrappedFields);
	  (config.virtualFields || []).forEach(v => {
	    // key: 'temporal',
	    // from: 'qDimensionInfo/0',
	    // override: {
	    //   value: v => v.qNum,
	    // },
	    const sourceField = dataset.field(v.from);
	    const f = qField(_objectSpread2({
	      meta: sourceField.raw(),
	      id: "".concat(key, "/").concat(v.key),
	      sourceField,
	      fieldExtractor: ff => opts.extractor({
	        field: ff
	      }, dataset, cache, deps),
	      key: v.key,
	      type: sourceField.type(),
	      localeInfo: opts.localeInfo,
	      value: sourceField.value
	    }, v.override || {}));
	    cache.virtualFields.push(f);
	  });
	  cache.allFields.push(...cache.virtualFields);
	  return dataset;
	}
	const LAYOUT_TO_PROP = [['qHyperCube', 'qHyperCubeDef'], ['qTreeData', 'qTreeDataDef'], ['qDimensionInfo', 'qDimensions'], ['qMeasureInfo', 'qMeasures'], ['qAttrDimInfo', 'qAttributeDimensions'], ['qAttrExprInfo', 'qAttributeExpressions']];
	const DIM_RX = /\/qDimensionInfo(?:\/(\d+))?/;
	const M_RX = /\/qMeasureInfo\/(\d+)/;
	const ATTR_DIM_RX = /\/qAttrDimInfo\/(\d+)(?:\/(\d+))?/;
	const ATTR_EXPR_RX = /\/qAttrExprInfo\/(\d+)/;
	const HC_RX = /\/?qHyperCube/;
	const TD_RX = /\/?qTreeData/;
	const SHORTEN_HC = path => "".concat(path.substr(0, path.indexOf('/qHyperCubeDef') + 14)); // 14 = length of '/qHyperCubeDef'
	const SHORTEN_TD = path => "".concat(path.substr(0, path.indexOf('/qTreeDataDef') + 13)); // 13 = length of '/qTreeDataDef'

	function extractFieldFromId(id, layout) {
	  let path = id;
	  let dimensionIdx = -1;
	  let measureIdx = -1;
	  let pathToCube = '';
	  let shortenizer = p => p;
	  if (HC_RX.test(id)) {
	    pathToCube = "".concat(path.substr(0, path.indexOf('qHyperCube') + 10)); // 10 = length of 'qHyperCube'
	    shortenizer = SHORTEN_HC;
	  } else if (TD_RX.test(id)) {
	    pathToCube = "".concat(path.substr(0, path.indexOf('qTreeData') + 9)); // 9 = length of 'qTreeData'
	    shortenizer = SHORTEN_TD;
	  }
	  let shortenPath = true;
	  if (DIM_RX.test(id)) {
	    dimensionIdx = +DIM_RX.exec(id)[1];
	  }
	  if (M_RX.test(id)) {
	    measureIdx = +M_RX.exec(id)[1];
	  }
	  if (ATTR_DIM_RX.test(id)) {
	    measureIdx = -1;
	    dimensionIdx = 0;
	    const attrCol = +ATTR_DIM_RX.exec(path)[2];
	    if (!isNaN(attrCol)) {
	      dimensionIdx = attrCol;
	      path = path.replace(/\/\d+$/, '');
	    }
	    shortenPath = false;
	  }
	  if (ATTR_EXPR_RX.test(id)) {
	    // depends on number of measures + number of attr expressions
	    // in dimensions and measures before this one
	    const offset = measureIdx;
	    if (layout) {
	      measureIdx = 0;
	      const hc = resolve(pathToCube, layout);

	      // offset by number of measures
	      measureIdx += (hc.qMeasureInfo || []).length;

	      // offset by total number of attr expr in dimensions
	      // (assuming attr expr in dimensions are ordered first)
	      if (dimensionIdx > -1) {
	        measureIdx = hc.qDimensionInfo.slice(0, dimensionIdx).reduce((v, dim) => v + dim.qAttrExprInfo.length, measureIdx);
	        dimensionIdx = -1;
	      } else {
	        measureIdx = hc.qDimensionInfo.reduce((v, dim) => v + dim.qAttrExprInfo.length, measureIdx);
	        // offset by total number of attr expr in measures before 'index'
	        measureIdx = hc.qMeasureInfo.slice(0, offset).reduce((v, meas) => v + meas.qAttrExprInfo.length, measureIdx);
	      }

	      // offset by the actual column value for the attribute expression itself
	      measureIdx += +ATTR_EXPR_RX.exec(path)[1];
	    } else if (dimensionIdx > -1) {
	      dimensionIdx = -1;
	      measureIdx = +ATTR_EXPR_RX.exec(path)[1];
	    } else {
	      measureIdx += +ATTR_EXPR_RX.exec(path)[1] + 1;
	    }
	  }
	  LAYOUT_TO_PROP.forEach(_ref => {
	    let [v, prop] = _ref;
	    path = path.replace(v, prop);
	  });
	  if (shortenPath) {
	    path = shortenizer(path);
	  }
	  if (path && path[0] !== '/') {
	    path = "/".concat(path);
	  }
	  return {
	    measureIdx,
	    dimensionIdx,
	    path
	  };
	}

	/**
	 * Helper method to generate suitable QIX selection methods and parameters based on a brush instance.
	 * @alias brush
	 * @memberof picasso.q
	 * @param {Brush} brush A brush instance
	 * @param {object} [opts]
	 * @param {boolean} [opts.byCells=false] Whether to prefer selection by row index.
	 * @param {string} [opts.primarySource] Field source to extract row indices from. If not specified, indices from first source are used.
	 * @param {boolean} [opts.orMode=true] If false, combine measure range selections.
	 * @param {object} [layout] QIX data layout. Needed only when brushing on attribute expressions, to be able to calculate the measure index.
	 * @return {object[]} An array of relevant selections
	 */
	function qBrush(brush) {
	  let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	  let layout = arguments.length > 2 ? arguments[2] : undefined;
	  const byCells = opts.byCells;
	  const primarySource = opts.primarySource;
	  const selections = [];
	  const methods = {};
	  const isActive = brush.isActive();
	  let hasValues = false;
	  brush.brushes().forEach(b => {
	    const info = extractFieldFromId(b.id, layout);
	    if (b.type === 'range' && info.measureIdx > -1 && info.dimensionIdx > -1) {
	      const ranges = b.brush.ranges();
	      if (ranges.length) {
	        hasValues = true;
	        if (!methods.multiRangeSelectTreeDataValues) {
	          methods.multiRangeSelectTreeDataValues = {
	            path: info.path,
	            ranges: []
	          };
	        }
	        ranges.forEach(range => methods.multiRangeSelectTreeDataValues.ranges.push({
	          qMeasureIx: info.measureIdx,
	          qDimensionIx: info.dimensionIdx,
	          qRange: {
	            qMin: range.min,
	            qMax: range.max,
	            qMinInclEq: true,
	            qMaxInclEq: true
	          }
	        }));
	      }
	    } else {
	      if (b.type === 'range' && info.measureIdx > -1) {
	        const ranges = b.brush.ranges();
	        if (ranges.length) {
	          hasValues = true;
	          if (!methods.rangeSelectHyperCubeValues) {
	            methods.rangeSelectHyperCubeValues = {
	              path: info.path,
	              ranges: []
	            };
	          }
	          ranges.forEach(range => methods.rangeSelectHyperCubeValues.ranges.push({
	            qMeasureIx: info.measureIdx,
	            qRange: {
	              qMin: range.min,
	              qMax: range.max,
	              qMinInclEq: true,
	              qMaxInclEq: true
	            }
	          }));
	        }
	      }
	      if (b.type === 'range' && info.dimensionIdx > -1) {
	        const ranges = b.brush.ranges();
	        if (ranges.length) {
	          hasValues = true;
	          if (!methods.selectHyperCubeContinuousRange) {
	            methods.selectHyperCubeContinuousRange = {
	              path: info.path,
	              ranges: []
	            };
	          }
	          ranges.forEach(range => methods.selectHyperCubeContinuousRange.ranges.push({
	            qDimIx: info.dimensionIdx,
	            qRange: {
	              qMin: range.min,
	              qMax: range.max,
	              qMinInclEq: true,
	              qMaxInclEq: false
	            }
	          }));
	        }
	      }
	      if (b.type === 'value' && info.dimensionIdx > -1) {
	        if (byCells) {
	          if (layout && layout.qHyperCube && (layout.qHyperCube.qMode === 'P' || layout.qHyperCube.qMode === 'T' || layout.qHyperCube.qMode === 'K')) {
	            const hyperCube = layout.qHyperCube;
	            const noOfLeftDims = hyperCube.qNoOfLeftDims;
	            const dimInterColSortIdx = hyperCube.qEffectiveInterColumnSortOrder.indexOf(info.dimensionIdx);
	            if (!methods.selectPivotCells) {
	              methods.selectPivotCells = {
	                path: info.path,
	                cells: []
	              };
	            }
	            if (b.id === primarySource || !primarySource) {
	              const validValues = b.brush.values().map(s => +s).filter(v => !isNaN(v));
	              if ((noOfLeftDims === 0 || dimInterColSortIdx >= noOfLeftDims) && noOfLeftDims > -1) {
	                validValues.forEach(val => {
	                  methods.selectPivotCells.cells.push({
	                    qType: 'T',
	                    qCol: val,
	                    qRow: dimInterColSortIdx - noOfLeftDims
	                  });
	                });
	              } else {
	                validValues.forEach(val => {
	                  methods.selectPivotCells.cells.push({
	                    qType: 'L',
	                    qCol: info.dimensionIdx,
	                    qRow: val
	                  });
	                });
	              }
	              hasValues = !!methods.selectPivotCells.cells.length;
	            }
	          } else {
	            if (!methods.selectHyperCubeCells) {
	              methods.selectHyperCubeCells = {
	                path: info.path,
	                cols: []
	              };
	            }
	            methods.selectHyperCubeCells.cols.push(info.dimensionIdx);
	            if (b.id === primarySource || !primarySource && !methods.selectHyperCubeCells.values) {
	              methods.selectHyperCubeCells.values = b.brush.values().map(s => +s).filter(v => !isNaN(v));
	              hasValues = !!methods.selectHyperCubeCells.values.length;
	            }
	          }
	        } else {
	          const values = b.brush.values().map(s => +s).filter(v => !isNaN(v));
	          hasValues = !!values.length;
	          selections.push({
	            params: [info.path, info.dimensionIdx, values, false],
	            method: 'selectHyperCubeValues'
	          });
	        }
	      }
	    }
	  });
	  if (!hasValues && isActive) {
	    return [{
	      method: 'resetMadeSelections',
	      params: []
	    }];
	  }
	  if (methods.rangeSelectHyperCubeValues) {
	    var _opts$orMode;
	    selections.push({
	      method: 'rangeSelectHyperCubeValues',
	      params: [methods.rangeSelectHyperCubeValues.path, methods.rangeSelectHyperCubeValues.ranges, [], (_opts$orMode = opts.orMode) !== null && _opts$orMode !== void 0 ? _opts$orMode : true]
	    });
	  }
	  if (methods.selectHyperCubeContinuousRange) {
	    selections.push({
	      method: 'selectHyperCubeContinuousRange',
	      params: [methods.selectHyperCubeContinuousRange.path, methods.selectHyperCubeContinuousRange.ranges]
	    });
	  }
	  if (methods.selectHyperCubeCells) {
	    selections.push({
	      method: 'selectHyperCubeCells',
	      params: [methods.selectHyperCubeCells.path, methods.selectHyperCubeCells.values, methods.selectHyperCubeCells.cols]
	    });
	  }
	  if (methods.selectPivotCells) {
	    selections.push({
	      method: 'selectPivotCells',
	      params: [methods.selectPivotCells.path, methods.selectPivotCells.cells]
	    });
	  }
	  if (methods.multiRangeSelectTreeDataValues) {
	    selections.push({
	      method: 'multiRangeSelectTreeDataValues',
	      params: [methods.multiRangeSelectTreeDataValues.path, methods.multiRangeSelectTreeDataValues.ranges]
	    });
	  }
	  return selections;
	}
	function initialize$1(picasso) {
	  q.util = picasso.data('matrix').util;
	  picasso.data('q', q);
	  picasso.formatter('q-number', formatter$1);
	  picasso.formatter('q-time', formatter);
	}
	initialize$1.qBrushHelper = qBrush; // deprecated
	initialize$1.selections = qBrush;

	/*
	* picasso-plugin-hammer v2.8.2
	* Copyright (c) 2025 QlikTech International AB
	* Released under the MIT license.
	*/

	const translateKnownTypes = {
	  click: 'Tap',
	  Click: 'Tap',
	  tap: 'Tap',
	  pan: 'Pan',
	  swipe: 'Swipe',
	  rotate: 'Rotate',
	  press: 'Press',
	  pinch: 'Pinch'
	};

	/**
	 * Helper function for translating typical non-hammer gesture to a hammer gesture. Currently only supporting 'click'
	 * @param {String} type Gesture type
	 * @private
	 */
	function getGestureType(type) {
	  return translateKnownTypes[type] || type;
	}

	/**
	 * Manages event handlers for HammerJS.
	 * @param {Hammer} Hammered - The Hammer instance
	 */
	function hammered(Hammered) {
	  return function hammer(chart, mediator, element) {
	    let settings;
	    let instance;
	    let mc;
	    let key;
	    let hammerGestures = [];
	    let isOn = true;
	    /**
	     * Set default settings
	     * @private
	     */
	    function setDefaultSettings(newSettings) {
	      key = newSettings.key; //eslint-disable-line
	      settings = newSettings;
	      instance = {
	        chart,
	        mediator,
	        settings
	      };
	      settings.gestures = settings.gestures || [];
	      if (settings.enable === undefined) {
	        settings.enable = true;
	      }
	    }

	    /**
	     * @private
	     * add hammer recognizers based on settings
	     */
	    function addRecognizers() {
	      if (typeof settings.enable === 'function') {
	        settings.enable = settings.enable.bind(instance)();
	      }
	      if (!settings.enable) {
	        return; // interaction is disabled
	      }
	      settings.gestures.forEach(gesture => {
	        gesture.options = gesture.options || {};
	        // handle action enable
	        if (gesture.options.enable === undefined) {
	          gesture.options.enable = true;
	        }
	        if (typeof gesture.options.enable === 'function') {
	          gesture.options.enable = gesture.options.enable.bind(instance);
	        }
	        // setup hammer gestures
	        const type = getGestureType(gesture.type);
	        if (Hammered && Hammered[type]) {
	          gesture.options.event = gesture.options.event || gesture.type.toLowerCase();
	          mc = mc || new Hammered.Manager(element);
	          mc.add(new Hammered[type](gesture.options));
	          Object.keys(gesture.events).forEach(eventName => {
	            gesture.events[eventName] = gesture.events[eventName].bind(instance);
	            mc.on(eventName, gesture.events[eventName]);
	          });
	          hammerGestures.push(gesture);
	        }
	      });

	      // setup mixing hammer gestures
	      settings.gestures.forEach(gesture => {
	        const type = getGestureType(gesture.type);
	        if (Hammered && Hammered[type]) {
	          if (gesture.recognizeWith) {
	            mc.get(gesture.options.event).recognizeWith(gesture.recognizeWith.split(' ').filter(e => e !== ''));
	          }
	          if (gesture.requireFailure) {
	            mc.get(gesture.options.event).requireFailure(gesture.requireFailure.split(' ').filter(e => e !== ''));
	          }
	        }
	      });
	    }
	    /**
	     * @private
	     * removes all added hammer recognizers and native events
	     */
	    function removeAddedEvents() {
	      // remove hammer recognizers and registered events
	      hammerGestures.forEach(gesture => {
	        Object.keys(gesture.events).forEach(eventName => {
	          mc.off(eventName, gesture.events[eventName]);
	        });
	        mc.remove(gesture.options.event);
	      });
	      hammerGestures = [];
	    }
	    return {
	      /**
	       * Getter for the key.
	       */
	      get key() {
	        return key;
	      },
	      /**
	       * Updates this with new settings
	       * @typedef settings
	       * @type {object}
	       * @property {string} [type] - The interaction type. Is 'hammer' for this component
	       * @property {boolean|function} [enable] - Should the interaction be enabled or not.
	       * This is only run when adding event handlers. In effect at startup, update or during on/off.
	       * It does not run during every event loop.
	       * @property {object} [events] - The keys in this object is the names of native events
	       * that should be added to the chart element and they should all point to function which
	       * will be the corresponding event handler.
	       */
	      set(newSettings) {
	        setDefaultSettings(newSettings);
	        removeAddedEvents();
	        if (isOn) {
	          addRecognizers();
	        }
	      },
	      /**
	       * Turns off interactions
	       */
	      off() {
	        isOn = false;
	        removeAddedEvents();
	      },
	      /**
	       * Turns off interactions
	       */
	      on() {
	        isOn = true;
	        if (hammerGestures.length === 0) {
	          addRecognizers();
	        }
	      },
	      /**
	       * Destroys and unbinds all event handlers
	       */
	      destroy() {
	        removeAddedEvents();
	        if (mc) {
	          mc.destroy();
	        }
	        mc = null;
	        instance = null;
	        settings = null;
	      }
	    };
	  };
	}

	/* global Hammer */
	function initialize(picassoOrHammer) {
	  const isPicasso = typeof picassoOrHammer.interaction === 'function';
	  if (!isPicasso) {
	    return picasso => {
	      picasso.interaction('hammer', hammered(picassoOrHammer));
	    };
	  }
	  picassoOrHammer.interaction('hammer', hammered(Hammer));
	  return undefined;
	}

	var hammer = {exports: {}};

	/*! Hammer.JS - v2.0.7 - 2016-04-22
	 * http://hammerjs.github.io/
	 *
	 * Copyright (c) 2016 Jorik Tangelder;
	 * Licensed under the MIT license */
	var hasRequiredHammer;
	function requireHammer() {
	  if (hasRequiredHammer) return hammer.exports;
	  hasRequiredHammer = 1;
	  (function (module) {
	    (function (window, document, exportName, undefined$1) {

	      var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
	      var TEST_ELEMENT = document.createElement('div');
	      var TYPE_FUNCTION = 'function';
	      var round = Math.round;
	      var abs = Math.abs;
	      var now = Date.now;

	      /**
	       * set a timeout with a given scope
	       * @param {Function} fn
	       * @param {Number} timeout
	       * @param {Object} context
	       * @returns {number}
	       */
	      function setTimeoutContext(fn, timeout, context) {
	        return setTimeout(bindFn(fn, context), timeout);
	      }

	      /**
	       * if the argument is an array, we want to execute the fn on each entry
	       * if it aint an array we don't want to do a thing.
	       * this is used by all the methods that accept a single and array argument.
	       * @param {*|Array} arg
	       * @param {String} fn
	       * @param {Object} [context]
	       * @returns {Boolean}
	       */
	      function invokeArrayArg(arg, fn, context) {
	        if (Array.isArray(arg)) {
	          each(arg, context[fn], context);
	          return true;
	        }
	        return false;
	      }

	      /**
	       * walk objects and arrays
	       * @param {Object} obj
	       * @param {Function} iterator
	       * @param {Object} context
	       */
	      function each(obj, iterator, context) {
	        var i;
	        if (!obj) {
	          return;
	        }
	        if (obj.forEach) {
	          obj.forEach(iterator, context);
	        } else if (obj.length !== undefined$1) {
	          i = 0;
	          while (i < obj.length) {
	            iterator.call(context, obj[i], i, obj);
	            i++;
	          }
	        } else {
	          for (i in obj) {
	            obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
	          }
	        }
	      }

	      /**
	       * wrap a method with a deprecation warning and stack trace
	       * @param {Function} method
	       * @param {String} name
	       * @param {String} message
	       * @returns {Function} A new function wrapping the supplied method.
	       */
	      function deprecate(method, name, message) {
	        var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
	        return function () {
	          var e = new Error('get-stack-trace');
	          var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
	          var log = window.console && (window.console.warn || window.console.log);
	          if (log) {
	            log.call(window.console, deprecationMessage, stack);
	          }
	          return method.apply(this, arguments);
	        };
	      }

	      /**
	       * extend object.
	       * means that properties in dest will be overwritten by the ones in src.
	       * @param {Object} target
	       * @param {...Object} objects_to_assign
	       * @returns {Object} target
	       */
	      var assign;
	      if (typeof Object.assign !== 'function') {
	        assign = function assign(target) {
	          if (target === undefined$1 || target === null) {
	            throw new TypeError('Cannot convert undefined or null to object');
	          }
	          var output = Object(target);
	          for (var index = 1; index < arguments.length; index++) {
	            var source = arguments[index];
	            if (source !== undefined$1 && source !== null) {
	              for (var nextKey in source) {
	                if (source.hasOwnProperty(nextKey)) {
	                  output[nextKey] = source[nextKey];
	                }
	              }
	            }
	          }
	          return output;
	        };
	      } else {
	        assign = Object.assign;
	      }

	      /**
	       * extend object.
	       * means that properties in dest will be overwritten by the ones in src.
	       * @param {Object} dest
	       * @param {Object} src
	       * @param {Boolean} [merge=false]
	       * @returns {Object} dest
	       */
	      var extend = deprecate(function extend(dest, src, merge) {
	        var keys = Object.keys(src);
	        var i = 0;
	        while (i < keys.length) {
	          if (!merge || merge && dest[keys[i]] === undefined$1) {
	            dest[keys[i]] = src[keys[i]];
	          }
	          i++;
	        }
	        return dest;
	      }, 'extend', 'Use `assign`.');

	      /**
	       * merge the values from src in the dest.
	       * means that properties that exist in dest will not be overwritten by src
	       * @param {Object} dest
	       * @param {Object} src
	       * @returns {Object} dest
	       */
	      var merge = deprecate(function merge(dest, src) {
	        return extend(dest, src, true);
	      }, 'merge', 'Use `assign`.');

	      /**
	       * simple class inheritance
	       * @param {Function} child
	       * @param {Function} base
	       * @param {Object} [properties]
	       */
	      function inherit(child, base, properties) {
	        var baseP = base.prototype,
	          childP;
	        childP = child.prototype = Object.create(baseP);
	        childP.constructor = child;
	        childP._super = baseP;
	        if (properties) {
	          assign(childP, properties);
	        }
	      }

	      /**
	       * simple function bind
	       * @param {Function} fn
	       * @param {Object} context
	       * @returns {Function}
	       */
	      function bindFn(fn, context) {
	        return function boundFn() {
	          return fn.apply(context, arguments);
	        };
	      }

	      /**
	       * let a boolean value also be a function that must return a boolean
	       * this first item in args will be used as the context
	       * @param {Boolean|Function} val
	       * @param {Array} [args]
	       * @returns {Boolean}
	       */
	      function boolOrFn(val, args) {
	        if (typeof val == TYPE_FUNCTION) {
	          return val.apply(args ? args[0] || undefined$1 : undefined$1, args);
	        }
	        return val;
	      }

	      /**
	       * use the val2 when val1 is undefined
	       * @param {*} val1
	       * @param {*} val2
	       * @returns {*}
	       */
	      function ifUndefined(val1, val2) {
	        return val1 === undefined$1 ? val2 : val1;
	      }

	      /**
	       * addEventListener with multiple events at once
	       * @param {EventTarget} target
	       * @param {String} types
	       * @param {Function} handler
	       */
	      function addEventListeners(target, types, handler) {
	        each(splitStr(types), function (type) {
	          target.addEventListener(type, handler, false);
	        });
	      }

	      /**
	       * removeEventListener with multiple events at once
	       * @param {EventTarget} target
	       * @param {String} types
	       * @param {Function} handler
	       */
	      function removeEventListeners(target, types, handler) {
	        each(splitStr(types), function (type) {
	          target.removeEventListener(type, handler, false);
	        });
	      }

	      /**
	       * find if a node is in the given parent
	       * @method hasParent
	       * @param {HTMLElement} node
	       * @param {HTMLElement} parent
	       * @return {Boolean} found
	       */
	      function hasParent(node, parent) {
	        while (node) {
	          if (node == parent) {
	            return true;
	          }
	          node = node.parentNode;
	        }
	        return false;
	      }

	      /**
	       * small indexOf wrapper
	       * @param {String} str
	       * @param {String} find
	       * @returns {Boolean} found
	       */
	      function inStr(str, find) {
	        return str.indexOf(find) > -1;
	      }

	      /**
	       * split string on whitespace
	       * @param {String} str
	       * @returns {Array} words
	       */
	      function splitStr(str) {
	        return str.trim().split(/\s+/g);
	      }

	      /**
	       * find if a array contains the object using indexOf or a simple polyFill
	       * @param {Array} src
	       * @param {String} find
	       * @param {String} [findByKey]
	       * @return {Boolean|Number} false when not found, or the index
	       */
	      function inArray(src, find, findByKey) {
	        if (src.indexOf && !findByKey) {
	          return src.indexOf(find);
	        } else {
	          var i = 0;
	          while (i < src.length) {
	            if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
	              return i;
	            }
	            i++;
	          }
	          return -1;
	        }
	      }

	      /**
	       * convert array-like objects to real arrays
	       * @param {Object} obj
	       * @returns {Array}
	       */
	      function toArray(obj) {
	        return Array.prototype.slice.call(obj, 0);
	      }

	      /**
	       * unique array with objects based on a key (like 'id') or just by the array's value
	       * @param {Array} src [{id:1},{id:2},{id:1}]
	       * @param {String} [key]
	       * @param {Boolean} [sort=False]
	       * @returns {Array} [{id:1},{id:2}]
	       */
	      function uniqueArray(src, key, sort) {
	        var results = [];
	        var values = [];
	        var i = 0;
	        while (i < src.length) {
	          var val = src[i][key] ;
	          if (inArray(values, val) < 0) {
	            results.push(src[i]);
	          }
	          values[i] = val;
	          i++;
	        }
	        {
	          {
	            results = results.sort(function sortUniqueArray(a, b) {
	              return a[key] > b[key];
	            });
	          }
	        }
	        return results;
	      }

	      /**
	       * get the prefixed property
	       * @param {Object} obj
	       * @param {String} property
	       * @returns {String|Undefined} prefixed
	       */
	      function prefixed(obj, property) {
	        var prefix, prop;
	        var camelProp = property[0].toUpperCase() + property.slice(1);
	        var i = 0;
	        while (i < VENDOR_PREFIXES.length) {
	          prefix = VENDOR_PREFIXES[i];
	          prop = prefix ? prefix + camelProp : property;
	          if (prop in obj) {
	            return prop;
	          }
	          i++;
	        }
	        return undefined$1;
	      }

	      /**
	       * get a unique id
	       * @returns {number} uniqueId
	       */
	      var _uniqueId = 1;
	      function uniqueId() {
	        return _uniqueId++;
	      }

	      /**
	       * get the window object of an element
	       * @param {HTMLElement} element
	       * @returns {DocumentView|Window}
	       */
	      function getWindowForElement(element) {
	        var doc = element.ownerDocument || element;
	        return doc.defaultView || doc.parentWindow || window;
	      }
	      var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
	      var SUPPORT_TOUCH = 'ontouchstart' in window;
	      var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined$1;
	      var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
	      var INPUT_TYPE_TOUCH = 'touch';
	      var INPUT_TYPE_PEN = 'pen';
	      var INPUT_TYPE_MOUSE = 'mouse';
	      var INPUT_TYPE_KINECT = 'kinect';
	      var COMPUTE_INTERVAL = 25;
	      var INPUT_START = 1;
	      var INPUT_MOVE = 2;
	      var INPUT_END = 4;
	      var INPUT_CANCEL = 8;
	      var DIRECTION_NONE = 1;
	      var DIRECTION_LEFT = 2;
	      var DIRECTION_RIGHT = 4;
	      var DIRECTION_UP = 8;
	      var DIRECTION_DOWN = 16;
	      var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
	      var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
	      var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
	      var PROPS_XY = ['x', 'y'];
	      var PROPS_CLIENT_XY = ['clientX', 'clientY'];

	      /**
	       * create new input type manager
	       * @param {Manager} manager
	       * @param {Function} callback
	       * @returns {Input}
	       * @constructor
	       */
	      function Input(manager, callback) {
	        var self = this;
	        this.manager = manager;
	        this.callback = callback;
	        this.element = manager.element;
	        this.target = manager.options.inputTarget;

	        // smaller wrapper around the handler, for the scope and the enabled state of the manager,
	        // so when disabled the input events are completely bypassed.
	        this.domHandler = function (ev) {
	          if (boolOrFn(manager.options.enable, [manager])) {
	            self.handler(ev);
	          }
	        };
	        this.init();
	      }
	      Input.prototype = {
	        /**
	         * should handle the inputEvent data and trigger the callback
	         * @virtual
	         */
	        handler: function () {},
	        /**
	         * bind the events
	         */
	        init: function () {
	          this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
	          this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
	          this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
	        },
	        /**
	         * unbind the events
	         */
	        destroy: function () {
	          this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
	          this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
	          this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
	        }
	      };

	      /**
	       * create new input type manager
	       * called by the Manager constructor
	       * @param {Hammer} manager
	       * @returns {Input}
	       */
	      function createInputInstance(manager) {
	        var Type;
	        var inputClass = manager.options.inputClass;
	        if (inputClass) {
	          Type = inputClass;
	        } else if (SUPPORT_POINTER_EVENTS) {
	          Type = PointerEventInput;
	        } else if (SUPPORT_ONLY_TOUCH) {
	          Type = TouchInput;
	        } else if (!SUPPORT_TOUCH) {
	          Type = MouseInput;
	        } else {
	          Type = TouchMouseInput;
	        }
	        return new Type(manager, inputHandler);
	      }

	      /**
	       * handle input events
	       * @param {Manager} manager
	       * @param {String} eventType
	       * @param {Object} input
	       */
	      function inputHandler(manager, eventType, input) {
	        var pointersLen = input.pointers.length;
	        var changedPointersLen = input.changedPointers.length;
	        var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
	        var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
	        input.isFirst = !!isFirst;
	        input.isFinal = !!isFinal;
	        if (isFirst) {
	          manager.session = {};
	        }

	        // source event is the normalized value of the domEvents
	        // like 'touchstart, mouseup, pointerdown'
	        input.eventType = eventType;

	        // compute scale, rotation etc
	        computeInputData(manager, input);

	        // emit secret event
	        manager.emit('hammer.input', input);
	        manager.recognize(input);
	        manager.session.prevInput = input;
	      }

	      /**
	       * extend the data with some usable properties like scale, rotate, velocity etc
	       * @param {Object} manager
	       * @param {Object} input
	       */
	      function computeInputData(manager, input) {
	        var session = manager.session;
	        var pointers = input.pointers;
	        var pointersLength = pointers.length;

	        // store the first input to calculate the distance and direction
	        if (!session.firstInput) {
	          session.firstInput = simpleCloneInputData(input);
	        }

	        // to compute scale and rotation we need to store the multiple touches
	        if (pointersLength > 1 && !session.firstMultiple) {
	          session.firstMultiple = simpleCloneInputData(input);
	        } else if (pointersLength === 1) {
	          session.firstMultiple = false;
	        }
	        var firstInput = session.firstInput;
	        var firstMultiple = session.firstMultiple;
	        var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
	        var center = input.center = getCenter(pointers);
	        input.timeStamp = now();
	        input.deltaTime = input.timeStamp - firstInput.timeStamp;
	        input.angle = getAngle(offsetCenter, center);
	        input.distance = getDistance(offsetCenter, center);
	        computeDeltaXY(session, input);
	        input.offsetDirection = getDirection(input.deltaX, input.deltaY);
	        var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
	        input.overallVelocityX = overallVelocity.x;
	        input.overallVelocityY = overallVelocity.y;
	        input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
	        input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
	        input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
	        input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
	        computeIntervalInputData(session, input);

	        // find the correct target
	        var target = manager.element;
	        if (hasParent(input.srcEvent.target, target)) {
	          target = input.srcEvent.target;
	        }
	        input.target = target;
	      }
	      function computeDeltaXY(session, input) {
	        var center = input.center;
	        var offset = session.offsetDelta || {};
	        var prevDelta = session.prevDelta || {};
	        var prevInput = session.prevInput || {};
	        if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
	          prevDelta = session.prevDelta = {
	            x: prevInput.deltaX || 0,
	            y: prevInput.deltaY || 0
	          };
	          offset = session.offsetDelta = {
	            x: center.x,
	            y: center.y
	          };
	        }
	        input.deltaX = prevDelta.x + (center.x - offset.x);
	        input.deltaY = prevDelta.y + (center.y - offset.y);
	      }

	      /**
	       * velocity is calculated every x ms
	       * @param {Object} session
	       * @param {Object} input
	       */
	      function computeIntervalInputData(session, input) {
	        var last = session.lastInterval || input,
	          deltaTime = input.timeStamp - last.timeStamp,
	          velocity,
	          velocityX,
	          velocityY,
	          direction;
	        if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined$1)) {
	          var deltaX = input.deltaX - last.deltaX;
	          var deltaY = input.deltaY - last.deltaY;
	          var v = getVelocity(deltaTime, deltaX, deltaY);
	          velocityX = v.x;
	          velocityY = v.y;
	          velocity = abs(v.x) > abs(v.y) ? v.x : v.y;
	          direction = getDirection(deltaX, deltaY);
	          session.lastInterval = input;
	        } else {
	          // use latest velocity info if it doesn't overtake a minimum period
	          velocity = last.velocity;
	          velocityX = last.velocityX;
	          velocityY = last.velocityY;
	          direction = last.direction;
	        }
	        input.velocity = velocity;
	        input.velocityX = velocityX;
	        input.velocityY = velocityY;
	        input.direction = direction;
	      }

	      /**
	       * create a simple clone from the input used for storage of firstInput and firstMultiple
	       * @param {Object} input
	       * @returns {Object} clonedInputData
	       */
	      function simpleCloneInputData(input) {
	        // make a simple copy of the pointers because we will get a reference if we don't
	        // we only need clientXY for the calculations
	        var pointers = [];
	        var i = 0;
	        while (i < input.pointers.length) {
	          pointers[i] = {
	            clientX: round(input.pointers[i].clientX),
	            clientY: round(input.pointers[i].clientY)
	          };
	          i++;
	        }
	        return {
	          timeStamp: now(),
	          pointers: pointers,
	          center: getCenter(pointers),
	          deltaX: input.deltaX,
	          deltaY: input.deltaY
	        };
	      }

	      /**
	       * get the center of all the pointers
	       * @param {Array} pointers
	       * @return {Object} center contains `x` and `y` properties
	       */
	      function getCenter(pointers) {
	        var pointersLength = pointers.length;

	        // no need to loop when only one touch
	        if (pointersLength === 1) {
	          return {
	            x: round(pointers[0].clientX),
	            y: round(pointers[0].clientY)
	          };
	        }
	        var x = 0,
	          y = 0,
	          i = 0;
	        while (i < pointersLength) {
	          x += pointers[i].clientX;
	          y += pointers[i].clientY;
	          i++;
	        }
	        return {
	          x: round(x / pointersLength),
	          y: round(y / pointersLength)
	        };
	      }

	      /**
	       * calculate the velocity between two points. unit is in px per ms.
	       * @param {Number} deltaTime
	       * @param {Number} x
	       * @param {Number} y
	       * @return {Object} velocity `x` and `y`
	       */
	      function getVelocity(deltaTime, x, y) {
	        return {
	          x: x / deltaTime || 0,
	          y: y / deltaTime || 0
	        };
	      }

	      /**
	       * get the direction between two points
	       * @param {Number} x
	       * @param {Number} y
	       * @return {Number} direction
	       */
	      function getDirection(x, y) {
	        if (x === y) {
	          return DIRECTION_NONE;
	        }
	        if (abs(x) >= abs(y)) {
	          return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
	        }
	        return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
	      }

	      /**
	       * calculate the absolute distance between two points
	       * @param {Object} p1 {x, y}
	       * @param {Object} p2 {x, y}
	       * @param {Array} [props] containing x and y keys
	       * @return {Number} distance
	       */
	      function getDistance(p1, p2, props) {
	        if (!props) {
	          props = PROPS_XY;
	        }
	        var x = p2[props[0]] - p1[props[0]],
	          y = p2[props[1]] - p1[props[1]];
	        return Math.sqrt(x * x + y * y);
	      }

	      /**
	       * calculate the angle between two coordinates
	       * @param {Object} p1
	       * @param {Object} p2
	       * @param {Array} [props] containing x and y keys
	       * @return {Number} angle
	       */
	      function getAngle(p1, p2, props) {
	        if (!props) {
	          props = PROPS_XY;
	        }
	        var x = p2[props[0]] - p1[props[0]],
	          y = p2[props[1]] - p1[props[1]];
	        return Math.atan2(y, x) * 180 / Math.PI;
	      }

	      /**
	       * calculate the rotation degrees between two pointersets
	       * @param {Array} start array of pointers
	       * @param {Array} end array of pointers
	       * @return {Number} rotation
	       */
	      function getRotation(start, end) {
	        return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
	      }

	      /**
	       * calculate the scale factor between two pointersets
	       * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
	       * @param {Array} start array of pointers
	       * @param {Array} end array of pointers
	       * @return {Number} scale
	       */
	      function getScale(start, end) {
	        return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
	      }
	      var MOUSE_INPUT_MAP = {
	        mousedown: INPUT_START,
	        mousemove: INPUT_MOVE,
	        mouseup: INPUT_END
	      };
	      var MOUSE_ELEMENT_EVENTS = 'mousedown';
	      var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';

	      /**
	       * Mouse events input
	       * @constructor
	       * @extends Input
	       */
	      function MouseInput() {
	        this.evEl = MOUSE_ELEMENT_EVENTS;
	        this.evWin = MOUSE_WINDOW_EVENTS;
	        this.pressed = false; // mousedown state

	        Input.apply(this, arguments);
	      }
	      inherit(MouseInput, Input, {
	        /**
	         * handle mouse events
	         * @param {Object} ev
	         */
	        handler: function MEhandler(ev) {
	          var eventType = MOUSE_INPUT_MAP[ev.type];

	          // on start we want to have the left mouse button down
	          if (eventType & INPUT_START && ev.button === 0) {
	            this.pressed = true;
	          }
	          if (eventType & INPUT_MOVE && ev.which !== 1) {
	            eventType = INPUT_END;
	          }

	          // mouse must be down
	          if (!this.pressed) {
	            return;
	          }
	          if (eventType & INPUT_END) {
	            this.pressed = false;
	          }
	          this.callback(this.manager, eventType, {
	            pointers: [ev],
	            changedPointers: [ev],
	            pointerType: INPUT_TYPE_MOUSE,
	            srcEvent: ev
	          });
	        }
	      });
	      var POINTER_INPUT_MAP = {
	        pointerdown: INPUT_START,
	        pointermove: INPUT_MOVE,
	        pointerup: INPUT_END,
	        pointercancel: INPUT_CANCEL,
	        pointerout: INPUT_CANCEL
	      };

	      // in IE10 the pointer types is defined as an enum
	      var IE10_POINTER_TYPE_ENUM = {
	        2: INPUT_TYPE_TOUCH,
	        3: INPUT_TYPE_PEN,
	        4: INPUT_TYPE_MOUSE,
	        5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
	      };
	      var POINTER_ELEMENT_EVENTS = 'pointerdown';
	      var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';

	      // IE10 has prefixed support, and case-sensitive
	      if (window.MSPointerEvent && !window.PointerEvent) {
	        POINTER_ELEMENT_EVENTS = 'MSPointerDown';
	        POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
	      }

	      /**
	       * Pointer events input
	       * @constructor
	       * @extends Input
	       */
	      function PointerEventInput() {
	        this.evEl = POINTER_ELEMENT_EVENTS;
	        this.evWin = POINTER_WINDOW_EVENTS;
	        Input.apply(this, arguments);
	        this.store = this.manager.session.pointerEvents = [];
	      }
	      inherit(PointerEventInput, Input, {
	        /**
	         * handle mouse events
	         * @param {Object} ev
	         */
	        handler: function PEhandler(ev) {
	          var store = this.store;
	          var removePointer = false;
	          var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
	          var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
	          var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
	          var isTouch = pointerType == INPUT_TYPE_TOUCH;

	          // get index of the event in the store
	          var storeIndex = inArray(store, ev.pointerId, 'pointerId');

	          // start and mouse must be down
	          if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
	            if (storeIndex < 0) {
	              store.push(ev);
	              storeIndex = store.length - 1;
	            }
	          } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
	            removePointer = true;
	          }

	          // it not found, so the pointer hasn't been down (so it's probably a hover)
	          if (storeIndex < 0) {
	            return;
	          }

	          // update the event in the store
	          store[storeIndex] = ev;
	          this.callback(this.manager, eventType, {
	            pointers: store,
	            changedPointers: [ev],
	            pointerType: pointerType,
	            srcEvent: ev
	          });
	          if (removePointer) {
	            // remove from the store
	            store.splice(storeIndex, 1);
	          }
	        }
	      });
	      var SINGLE_TOUCH_INPUT_MAP = {
	        touchstart: INPUT_START,
	        touchmove: INPUT_MOVE,
	        touchend: INPUT_END,
	        touchcancel: INPUT_CANCEL
	      };
	      var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
	      var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';

	      /**
	       * Touch events input
	       * @constructor
	       * @extends Input
	       */
	      function SingleTouchInput() {
	        this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
	        this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
	        this.started = false;
	        Input.apply(this, arguments);
	      }
	      inherit(SingleTouchInput, Input, {
	        handler: function TEhandler(ev) {
	          var type = SINGLE_TOUCH_INPUT_MAP[ev.type];

	          // should we handle the touch events?
	          if (type === INPUT_START) {
	            this.started = true;
	          }
	          if (!this.started) {
	            return;
	          }
	          var touches = normalizeSingleTouches.call(this, ev, type);

	          // when done, reset the started state
	          if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
	            this.started = false;
	          }
	          this.callback(this.manager, type, {
	            pointers: touches[0],
	            changedPointers: touches[1],
	            pointerType: INPUT_TYPE_TOUCH,
	            srcEvent: ev
	          });
	        }
	      });

	      /**
	       * @this {TouchInput}
	       * @param {Object} ev
	       * @param {Number} type flag
	       * @returns {undefined|Array} [all, changed]
	       */
	      function normalizeSingleTouches(ev, type) {
	        var all = toArray(ev.touches);
	        var changed = toArray(ev.changedTouches);
	        if (type & (INPUT_END | INPUT_CANCEL)) {
	          all = uniqueArray(all.concat(changed), 'identifier');
	        }
	        return [all, changed];
	      }
	      var TOUCH_INPUT_MAP = {
	        touchstart: INPUT_START,
	        touchmove: INPUT_MOVE,
	        touchend: INPUT_END,
	        touchcancel: INPUT_CANCEL
	      };
	      var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';

	      /**
	       * Multi-user touch events input
	       * @constructor
	       * @extends Input
	       */
	      function TouchInput() {
	        this.evTarget = TOUCH_TARGET_EVENTS;
	        this.targetIds = {};
	        Input.apply(this, arguments);
	      }
	      inherit(TouchInput, Input, {
	        handler: function MTEhandler(ev) {
	          var type = TOUCH_INPUT_MAP[ev.type];
	          var touches = getTouches.call(this, ev, type);
	          if (!touches) {
	            return;
	          }
	          this.callback(this.manager, type, {
	            pointers: touches[0],
	            changedPointers: touches[1],
	            pointerType: INPUT_TYPE_TOUCH,
	            srcEvent: ev
	          });
	        }
	      });

	      /**
	       * @this {TouchInput}
	       * @param {Object} ev
	       * @param {Number} type flag
	       * @returns {undefined|Array} [all, changed]
	       */
	      function getTouches(ev, type) {
	        var allTouches = toArray(ev.touches);
	        var targetIds = this.targetIds;

	        // when there is only one touch, the process can be simplified
	        if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
	          targetIds[allTouches[0].identifier] = true;
	          return [allTouches, allTouches];
	        }
	        var i,
	          targetTouches,
	          changedTouches = toArray(ev.changedTouches),
	          changedTargetTouches = [],
	          target = this.target;

	        // get target touches from touches
	        targetTouches = allTouches.filter(function (touch) {
	          return hasParent(touch.target, target);
	        });

	        // collect touches
	        if (type === INPUT_START) {
	          i = 0;
	          while (i < targetTouches.length) {
	            targetIds[targetTouches[i].identifier] = true;
	            i++;
	          }
	        }

	        // filter changed touches to only contain touches that exist in the collected target ids
	        i = 0;
	        while (i < changedTouches.length) {
	          if (targetIds[changedTouches[i].identifier]) {
	            changedTargetTouches.push(changedTouches[i]);
	          }

	          // cleanup removed touches
	          if (type & (INPUT_END | INPUT_CANCEL)) {
	            delete targetIds[changedTouches[i].identifier];
	          }
	          i++;
	        }
	        if (!changedTargetTouches.length) {
	          return;
	        }
	        return [
	        // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
	        uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier'), changedTargetTouches];
	      }

	      /**
	       * Combined touch and mouse input
	       *
	       * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
	       * This because touch devices also emit mouse events while doing a touch.
	       *
	       * @constructor
	       * @extends Input
	       */

	      var DEDUP_TIMEOUT = 2500;
	      var DEDUP_DISTANCE = 25;
	      function TouchMouseInput() {
	        Input.apply(this, arguments);
	        var handler = bindFn(this.handler, this);
	        this.touch = new TouchInput(this.manager, handler);
	        this.mouse = new MouseInput(this.manager, handler);
	        this.primaryTouch = null;
	        this.lastTouches = [];
	      }
	      inherit(TouchMouseInput, Input, {
	        /**
	         * handle mouse and touch events
	         * @param {Hammer} manager
	         * @param {String} inputEvent
	         * @param {Object} inputData
	         */
	        handler: function TMEhandler(manager, inputEvent, inputData) {
	          var isTouch = inputData.pointerType == INPUT_TYPE_TOUCH,
	            isMouse = inputData.pointerType == INPUT_TYPE_MOUSE;
	          if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
	            return;
	          }

	          // when we're in a touch event, record touches to  de-dupe synthetic mouse event
	          if (isTouch) {
	            recordTouches.call(this, inputEvent, inputData);
	          } else if (isMouse && isSyntheticEvent.call(this, inputData)) {
	            return;
	          }
	          this.callback(manager, inputEvent, inputData);
	        },
	        /**
	         * remove the event listeners
	         */
	        destroy: function destroy() {
	          this.touch.destroy();
	          this.mouse.destroy();
	        }
	      });
	      function recordTouches(eventType, eventData) {
	        if (eventType & INPUT_START) {
	          this.primaryTouch = eventData.changedPointers[0].identifier;
	          setLastTouch.call(this, eventData);
	        } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
	          setLastTouch.call(this, eventData);
	        }
	      }
	      function setLastTouch(eventData) {
	        var touch = eventData.changedPointers[0];
	        if (touch.identifier === this.primaryTouch) {
	          var lastTouch = {
	            x: touch.clientX,
	            y: touch.clientY
	          };
	          this.lastTouches.push(lastTouch);
	          var lts = this.lastTouches;
	          var removeLastTouch = function () {
	            var i = lts.indexOf(lastTouch);
	            if (i > -1) {
	              lts.splice(i, 1);
	            }
	          };
	          setTimeout(removeLastTouch, DEDUP_TIMEOUT);
	        }
	      }
	      function isSyntheticEvent(eventData) {
	        var x = eventData.srcEvent.clientX,
	          y = eventData.srcEvent.clientY;
	        for (var i = 0; i < this.lastTouches.length; i++) {
	          var t = this.lastTouches[i];
	          var dx = Math.abs(x - t.x),
	            dy = Math.abs(y - t.y);
	          if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
	            return true;
	          }
	        }
	        return false;
	      }
	      var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
	      var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined$1;

	      // magical touchAction value
	      var TOUCH_ACTION_COMPUTE = 'compute';
	      var TOUCH_ACTION_AUTO = 'auto';
	      var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
	      var TOUCH_ACTION_NONE = 'none';
	      var TOUCH_ACTION_PAN_X = 'pan-x';
	      var TOUCH_ACTION_PAN_Y = 'pan-y';
	      var TOUCH_ACTION_MAP = getTouchActionProps();

	      /**
	       * Touch Action
	       * sets the touchAction property or uses the js alternative
	       * @param {Manager} manager
	       * @param {String} value
	       * @constructor
	       */
	      function TouchAction(manager, value) {
	        this.manager = manager;
	        this.set(value);
	      }
	      TouchAction.prototype = {
	        /**
	         * set the touchAction value on the element or enable the polyfill
	         * @param {String} value
	         */
	        set: function (value) {
	          // find out the touch-action by the event handlers
	          if (value == TOUCH_ACTION_COMPUTE) {
	            value = this.compute();
	          }
	          if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
	            this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
	          }
	          this.actions = value.toLowerCase().trim();
	        },
	        /**
	         * just re-set the touchAction value
	         */
	        update: function () {
	          this.set(this.manager.options.touchAction);
	        },
	        /**
	         * compute the value for the touchAction property based on the recognizer's settings
	         * @returns {String} value
	         */
	        compute: function () {
	          var actions = [];
	          each(this.manager.recognizers, function (recognizer) {
	            if (boolOrFn(recognizer.options.enable, [recognizer])) {
	              actions = actions.concat(recognizer.getTouchAction());
	            }
	          });
	          return cleanTouchActions(actions.join(' '));
	        },
	        /**
	         * this method is called on each input cycle and provides the preventing of the browser behavior
	         * @param {Object} input
	         */
	        preventDefaults: function (input) {
	          var srcEvent = input.srcEvent;
	          var direction = input.offsetDirection;

	          // if the touch action did prevented once this session
	          if (this.manager.session.prevented) {
	            srcEvent.preventDefault();
	            return;
	          }
	          var actions = this.actions;
	          var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
	          var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
	          var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
	          if (hasNone) {
	            //do not prevent defaults if this is a tap gesture

	            var isTapPointer = input.pointers.length === 1;
	            var isTapMovement = input.distance < 2;
	            var isTapTouchTime = input.deltaTime < 250;
	            if (isTapPointer && isTapMovement && isTapTouchTime) {
	              return;
	            }
	          }
	          if (hasPanX && hasPanY) {
	            // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
	            return;
	          }
	          if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
	            return this.preventSrc(srcEvent);
	          }
	        },
	        /**
	         * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
	         * @param {Object} srcEvent
	         */
	        preventSrc: function (srcEvent) {
	          this.manager.session.prevented = true;
	          srcEvent.preventDefault();
	        }
	      };

	      /**
	       * when the touchActions are collected they are not a valid value, so we need to clean things up. *
	       * @param {String} actions
	       * @returns {*}
	       */
	      function cleanTouchActions(actions) {
	        // none
	        if (inStr(actions, TOUCH_ACTION_NONE)) {
	          return TOUCH_ACTION_NONE;
	        }
	        var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
	        var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);

	        // if both pan-x and pan-y are set (different recognizers
	        // for different directions, e.g. horizontal pan but vertical swipe?)
	        // we need none (as otherwise with pan-x pan-y combined none of these
	        // recognizers will work, since the browser would handle all panning
	        if (hasPanX && hasPanY) {
	          return TOUCH_ACTION_NONE;
	        }

	        // pan-x OR pan-y
	        if (hasPanX || hasPanY) {
	          return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
	        }

	        // manipulation
	        if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
	          return TOUCH_ACTION_MANIPULATION;
	        }
	        return TOUCH_ACTION_AUTO;
	      }
	      function getTouchActionProps() {
	        if (!NATIVE_TOUCH_ACTION) {
	          return false;
	        }
	        var touchMap = {};
	        var cssSupports = window.CSS && window.CSS.supports;
	        ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
	          // If css.supports is not supported but there is native touch-action assume it supports
	          // all values. This is the case for IE 10 and 11.
	          touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
	        });
	        return touchMap;
	      }

	      /**
	       * Recognizer flow explained; *
	       * All recognizers have the initial state of POSSIBLE when a input session starts.
	       * The definition of a input session is from the first input until the last input, with all it's movement in it. *
	       * Example session for mouse-input: mousedown -> mousemove -> mouseup
	       *
	       * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
	       * which determines with state it should be.
	       *
	       * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
	       * POSSIBLE to give it another change on the next cycle.
	       *
	       *               Possible
	       *                  |
	       *            +-----+---------------+
	       *            |                     |
	       *      +-----+-----+               |
	       *      |           |               |
	       *   Failed      Cancelled          |
	       *                          +-------+------+
	       *                          |              |
	       *                      Recognized       Began
	       *                                         |
	       *                                      Changed
	       *                                         |
	       *                                  Ended/Recognized
	       */
	      var STATE_POSSIBLE = 1;
	      var STATE_BEGAN = 2;
	      var STATE_CHANGED = 4;
	      var STATE_ENDED = 8;
	      var STATE_RECOGNIZED = STATE_ENDED;
	      var STATE_CANCELLED = 16;
	      var STATE_FAILED = 32;

	      /**
	       * Recognizer
	       * Every recognizer needs to extend from this class.
	       * @constructor
	       * @param {Object} options
	       */
	      function Recognizer(options) {
	        this.options = assign({}, this.defaults, options || {});
	        this.id = uniqueId();
	        this.manager = null;

	        // default is enable true
	        this.options.enable = ifUndefined(this.options.enable, true);
	        this.state = STATE_POSSIBLE;
	        this.simultaneous = {};
	        this.requireFail = [];
	      }
	      Recognizer.prototype = {
	        /**
	         * @virtual
	         * @type {Object}
	         */
	        defaults: {},
	        /**
	         * set options
	         * @param {Object} options
	         * @return {Recognizer}
	         */
	        set: function (options) {
	          assign(this.options, options);

	          // also update the touchAction, in case something changed about the directions/enabled state
	          this.manager && this.manager.touchAction.update();
	          return this;
	        },
	        /**
	         * recognize simultaneous with an other recognizer.
	         * @param {Recognizer} otherRecognizer
	         * @returns {Recognizer} this
	         */
	        recognizeWith: function (otherRecognizer) {
	          if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
	            return this;
	          }
	          var simultaneous = this.simultaneous;
	          otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
	          if (!simultaneous[otherRecognizer.id]) {
	            simultaneous[otherRecognizer.id] = otherRecognizer;
	            otherRecognizer.recognizeWith(this);
	          }
	          return this;
	        },
	        /**
	         * drop the simultaneous link. it doesnt remove the link on the other recognizer.
	         * @param {Recognizer} otherRecognizer
	         * @returns {Recognizer} this
	         */
	        dropRecognizeWith: function (otherRecognizer) {
	          if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
	            return this;
	          }
	          otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
	          delete this.simultaneous[otherRecognizer.id];
	          return this;
	        },
	        /**
	         * recognizer can only run when an other is failing
	         * @param {Recognizer} otherRecognizer
	         * @returns {Recognizer} this
	         */
	        requireFailure: function (otherRecognizer) {
	          if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
	            return this;
	          }
	          var requireFail = this.requireFail;
	          otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
	          if (inArray(requireFail, otherRecognizer) === -1) {
	            requireFail.push(otherRecognizer);
	            otherRecognizer.requireFailure(this);
	          }
	          return this;
	        },
	        /**
	         * drop the requireFailure link. it does not remove the link on the other recognizer.
	         * @param {Recognizer} otherRecognizer
	         * @returns {Recognizer} this
	         */
	        dropRequireFailure: function (otherRecognizer) {
	          if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
	            return this;
	          }
	          otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
	          var index = inArray(this.requireFail, otherRecognizer);
	          if (index > -1) {
	            this.requireFail.splice(index, 1);
	          }
	          return this;
	        },
	        /**
	         * has require failures boolean
	         * @returns {boolean}
	         */
	        hasRequireFailures: function () {
	          return this.requireFail.length > 0;
	        },
	        /**
	         * if the recognizer can recognize simultaneous with an other recognizer
	         * @param {Recognizer} otherRecognizer
	         * @returns {Boolean}
	         */
	        canRecognizeWith: function (otherRecognizer) {
	          return !!this.simultaneous[otherRecognizer.id];
	        },
	        /**
	         * You should use `tryEmit` instead of `emit` directly to check
	         * that all the needed recognizers has failed before emitting.
	         * @param {Object} input
	         */
	        emit: function (input) {
	          var self = this;
	          var state = this.state;
	          function emit(event) {
	            self.manager.emit(event, input);
	          }

	          // 'panstart' and 'panmove'
	          if (state < STATE_ENDED) {
	            emit(self.options.event + stateStr(state));
	          }
	          emit(self.options.event); // simple 'eventName' events

	          if (input.additionalEvent) {
	            // additional event(panleft, panright, pinchin, pinchout...)
	            emit(input.additionalEvent);
	          }

	          // panend and pancancel
	          if (state >= STATE_ENDED) {
	            emit(self.options.event + stateStr(state));
	          }
	        },
	        /**
	         * Check that all the require failure recognizers has failed,
	         * if true, it emits a gesture event,
	         * otherwise, setup the state to FAILED.
	         * @param {Object} input
	         */
	        tryEmit: function (input) {
	          if (this.canEmit()) {
	            return this.emit(input);
	          }
	          // it's failing anyway
	          this.state = STATE_FAILED;
	        },
	        /**
	         * can we emit?
	         * @returns {boolean}
	         */
	        canEmit: function () {
	          var i = 0;
	          while (i < this.requireFail.length) {
	            if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
	              return false;
	            }
	            i++;
	          }
	          return true;
	        },
	        /**
	         * update the recognizer
	         * @param {Object} inputData
	         */
	        recognize: function (inputData) {
	          // make a new copy of the inputData
	          // so we can change the inputData without messing up the other recognizers
	          var inputDataClone = assign({}, inputData);

	          // is is enabled and allow recognizing?
	          if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
	            this.reset();
	            this.state = STATE_FAILED;
	            return;
	          }

	          // reset when we've reached the end
	          if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
	            this.state = STATE_POSSIBLE;
	          }
	          this.state = this.process(inputDataClone);

	          // the recognizer has recognized a gesture
	          // so trigger an event
	          if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
	            this.tryEmit(inputDataClone);
	          }
	        },
	        /**
	         * return the state of the recognizer
	         * the actual recognizing happens in this method
	         * @virtual
	         * @param {Object} inputData
	         * @returns {Const} STATE
	         */
	        process: function (inputData) {},
	        // jshint ignore:line

	        /**
	         * return the preferred touch-action
	         * @virtual
	         * @returns {Array}
	         */
	        getTouchAction: function () {},
	        /**
	         * called when the gesture isn't allowed to recognize
	         * like when another is being recognized or it is disabled
	         * @virtual
	         */
	        reset: function () {}
	      };

	      /**
	       * get a usable string, used as event postfix
	       * @param {Const} state
	       * @returns {String} state
	       */
	      function stateStr(state) {
	        if (state & STATE_CANCELLED) {
	          return 'cancel';
	        } else if (state & STATE_ENDED) {
	          return 'end';
	        } else if (state & STATE_CHANGED) {
	          return 'move';
	        } else if (state & STATE_BEGAN) {
	          return 'start';
	        }
	        return '';
	      }

	      /**
	       * direction cons to string
	       * @param {Const} direction
	       * @returns {String}
	       */
	      function directionStr(direction) {
	        if (direction == DIRECTION_DOWN) {
	          return 'down';
	        } else if (direction == DIRECTION_UP) {
	          return 'up';
	        } else if (direction == DIRECTION_LEFT) {
	          return 'left';
	        } else if (direction == DIRECTION_RIGHT) {
	          return 'right';
	        }
	        return '';
	      }

	      /**
	       * get a recognizer by name if it is bound to a manager
	       * @param {Recognizer|String} otherRecognizer
	       * @param {Recognizer} recognizer
	       * @returns {Recognizer}
	       */
	      function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
	        var manager = recognizer.manager;
	        if (manager) {
	          return manager.get(otherRecognizer);
	        }
	        return otherRecognizer;
	      }

	      /**
	       * This recognizer is just used as a base for the simple attribute recognizers.
	       * @constructor
	       * @extends Recognizer
	       */
	      function AttrRecognizer() {
	        Recognizer.apply(this, arguments);
	      }
	      inherit(AttrRecognizer, Recognizer, {
	        /**
	         * @namespace
	         * @memberof AttrRecognizer
	         */
	        defaults: {
	          /**
	           * @type {Number}
	           * @default 1
	           */
	          pointers: 1
	        },
	        /**
	         * Used to check if it the recognizer receives valid input, like input.distance > 10.
	         * @memberof AttrRecognizer
	         * @param {Object} input
	         * @returns {Boolean} recognized
	         */
	        attrTest: function (input) {
	          var optionPointers = this.options.pointers;
	          return optionPointers === 0 || input.pointers.length === optionPointers;
	        },
	        /**
	         * Process the input and return the state for the recognizer
	         * @memberof AttrRecognizer
	         * @param {Object} input
	         * @returns {*} State
	         */
	        process: function (input) {
	          var state = this.state;
	          var eventType = input.eventType;
	          var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
	          var isValid = this.attrTest(input);

	          // on cancel input and we've recognized before, return STATE_CANCELLED
	          if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
	            return state | STATE_CANCELLED;
	          } else if (isRecognized || isValid) {
	            if (eventType & INPUT_END) {
	              return state | STATE_ENDED;
	            } else if (!(state & STATE_BEGAN)) {
	              return STATE_BEGAN;
	            }
	            return state | STATE_CHANGED;
	          }
	          return STATE_FAILED;
	        }
	      });

	      /**
	       * Pan
	       * Recognized when the pointer is down and moved in the allowed direction.
	       * @constructor
	       * @extends AttrRecognizer
	       */
	      function PanRecognizer() {
	        AttrRecognizer.apply(this, arguments);
	        this.pX = null;
	        this.pY = null;
	      }
	      inherit(PanRecognizer, AttrRecognizer, {
	        /**
	         * @namespace
	         * @memberof PanRecognizer
	         */
	        defaults: {
	          event: 'pan',
	          threshold: 10,
	          pointers: 1,
	          direction: DIRECTION_ALL
	        },
	        getTouchAction: function () {
	          var direction = this.options.direction;
	          var actions = [];
	          if (direction & DIRECTION_HORIZONTAL) {
	            actions.push(TOUCH_ACTION_PAN_Y);
	          }
	          if (direction & DIRECTION_VERTICAL) {
	            actions.push(TOUCH_ACTION_PAN_X);
	          }
	          return actions;
	        },
	        directionTest: function (input) {
	          var options = this.options;
	          var hasMoved = true;
	          var distance = input.distance;
	          var direction = input.direction;
	          var x = input.deltaX;
	          var y = input.deltaY;

	          // lock to axis?
	          if (!(direction & options.direction)) {
	            if (options.direction & DIRECTION_HORIZONTAL) {
	              direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
	              hasMoved = x != this.pX;
	              distance = Math.abs(input.deltaX);
	            } else {
	              direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
	              hasMoved = y != this.pY;
	              distance = Math.abs(input.deltaY);
	            }
	          }
	          input.direction = direction;
	          return hasMoved && distance > options.threshold && direction & options.direction;
	        },
	        attrTest: function (input) {
	          return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
	        },
	        emit: function (input) {
	          this.pX = input.deltaX;
	          this.pY = input.deltaY;
	          var direction = directionStr(input.direction);
	          if (direction) {
	            input.additionalEvent = this.options.event + direction;
	          }
	          this._super.emit.call(this, input);
	        }
	      });

	      /**
	       * Pinch
	       * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
	       * @constructor
	       * @extends AttrRecognizer
	       */
	      function PinchRecognizer() {
	        AttrRecognizer.apply(this, arguments);
	      }
	      inherit(PinchRecognizer, AttrRecognizer, {
	        /**
	         * @namespace
	         * @memberof PinchRecognizer
	         */
	        defaults: {
	          event: 'pinch',
	          threshold: 0,
	          pointers: 2
	        },
	        getTouchAction: function () {
	          return [TOUCH_ACTION_NONE];
	        },
	        attrTest: function (input) {
	          return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
	        },
	        emit: function (input) {
	          if (input.scale !== 1) {
	            var inOut = input.scale < 1 ? 'in' : 'out';
	            input.additionalEvent = this.options.event + inOut;
	          }
	          this._super.emit.call(this, input);
	        }
	      });

	      /**
	       * Press
	       * Recognized when the pointer is down for x ms without any movement.
	       * @constructor
	       * @extends Recognizer
	       */
	      function PressRecognizer() {
	        Recognizer.apply(this, arguments);
	        this._timer = null;
	        this._input = null;
	      }
	      inherit(PressRecognizer, Recognizer, {
	        /**
	         * @namespace
	         * @memberof PressRecognizer
	         */
	        defaults: {
	          event: 'press',
	          pointers: 1,
	          time: 251,
	          // minimal time of the pointer to be pressed
	          threshold: 9 // a minimal movement is ok, but keep it low
	        },
	        getTouchAction: function () {
	          return [TOUCH_ACTION_AUTO];
	        },
	        process: function (input) {
	          var options = this.options;
	          var validPointers = input.pointers.length === options.pointers;
	          var validMovement = input.distance < options.threshold;
	          var validTime = input.deltaTime > options.time;
	          this._input = input;

	          // we only allow little movement
	          // and we've reached an end event, so a tap is possible
	          if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
	            this.reset();
	          } else if (input.eventType & INPUT_START) {
	            this.reset();
	            this._timer = setTimeoutContext(function () {
	              this.state = STATE_RECOGNIZED;
	              this.tryEmit();
	            }, options.time, this);
	          } else if (input.eventType & INPUT_END) {
	            return STATE_RECOGNIZED;
	          }
	          return STATE_FAILED;
	        },
	        reset: function () {
	          clearTimeout(this._timer);
	        },
	        emit: function (input) {
	          if (this.state !== STATE_RECOGNIZED) {
	            return;
	          }
	          if (input && input.eventType & INPUT_END) {
	            this.manager.emit(this.options.event + 'up', input);
	          } else {
	            this._input.timeStamp = now();
	            this.manager.emit(this.options.event, this._input);
	          }
	        }
	      });

	      /**
	       * Rotate
	       * Recognized when two or more pointer are moving in a circular motion.
	       * @constructor
	       * @extends AttrRecognizer
	       */
	      function RotateRecognizer() {
	        AttrRecognizer.apply(this, arguments);
	      }
	      inherit(RotateRecognizer, AttrRecognizer, {
	        /**
	         * @namespace
	         * @memberof RotateRecognizer
	         */
	        defaults: {
	          event: 'rotate',
	          threshold: 0,
	          pointers: 2
	        },
	        getTouchAction: function () {
	          return [TOUCH_ACTION_NONE];
	        },
	        attrTest: function (input) {
	          return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
	        }
	      });

	      /**
	       * Swipe
	       * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
	       * @constructor
	       * @extends AttrRecognizer
	       */
	      function SwipeRecognizer() {
	        AttrRecognizer.apply(this, arguments);
	      }
	      inherit(SwipeRecognizer, AttrRecognizer, {
	        /**
	         * @namespace
	         * @memberof SwipeRecognizer
	         */
	        defaults: {
	          event: 'swipe',
	          threshold: 10,
	          velocity: 0.3,
	          direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
	          pointers: 1
	        },
	        getTouchAction: function () {
	          return PanRecognizer.prototype.getTouchAction.call(this);
	        },
	        attrTest: function (input) {
	          var direction = this.options.direction;
	          var velocity;
	          if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
	            velocity = input.overallVelocity;
	          } else if (direction & DIRECTION_HORIZONTAL) {
	            velocity = input.overallVelocityX;
	          } else if (direction & DIRECTION_VERTICAL) {
	            velocity = input.overallVelocityY;
	          }
	          return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
	        },
	        emit: function (input) {
	          var direction = directionStr(input.offsetDirection);
	          if (direction) {
	            this.manager.emit(this.options.event + direction, input);
	          }
	          this.manager.emit(this.options.event, input);
	        }
	      });

	      /**
	       * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
	       * between the given interval and position. The delay option can be used to recognize multi-taps without firing
	       * a single tap.
	       *
	       * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
	       * multi-taps being recognized.
	       * @constructor
	       * @extends Recognizer
	       */
	      function TapRecognizer() {
	        Recognizer.apply(this, arguments);

	        // previous time and center,
	        // used for tap counting
	        this.pTime = false;
	        this.pCenter = false;
	        this._timer = null;
	        this._input = null;
	        this.count = 0;
	      }
	      inherit(TapRecognizer, Recognizer, {
	        /**
	         * @namespace
	         * @memberof PinchRecognizer
	         */
	        defaults: {
	          event: 'tap',
	          pointers: 1,
	          taps: 1,
	          interval: 300,
	          // max time between the multi-tap taps
	          time: 250,
	          // max time of the pointer to be down (like finger on the screen)
	          threshold: 9,
	          // a minimal movement is ok, but keep it low
	          posThreshold: 10 // a multi-tap can be a bit off the initial position
	        },
	        getTouchAction: function () {
	          return [TOUCH_ACTION_MANIPULATION];
	        },
	        process: function (input) {
	          var options = this.options;
	          var validPointers = input.pointers.length === options.pointers;
	          var validMovement = input.distance < options.threshold;
	          var validTouchTime = input.deltaTime < options.time;
	          this.reset();
	          if (input.eventType & INPUT_START && this.count === 0) {
	            return this.failTimeout();
	          }

	          // we only allow little movement
	          // and we've reached an end event, so a tap is possible
	          if (validMovement && validTouchTime && validPointers) {
	            if (input.eventType != INPUT_END) {
	              return this.failTimeout();
	            }
	            var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
	            var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
	            this.pTime = input.timeStamp;
	            this.pCenter = input.center;
	            if (!validMultiTap || !validInterval) {
	              this.count = 1;
	            } else {
	              this.count += 1;
	            }
	            this._input = input;

	            // if tap count matches we have recognized it,
	            // else it has began recognizing...
	            var tapCount = this.count % options.taps;
	            if (tapCount === 0) {
	              // no failing requirements, immediately trigger the tap event
	              // or wait as long as the multitap interval to trigger
	              if (!this.hasRequireFailures()) {
	                return STATE_RECOGNIZED;
	              } else {
	                this._timer = setTimeoutContext(function () {
	                  this.state = STATE_RECOGNIZED;
	                  this.tryEmit();
	                }, options.interval, this);
	                return STATE_BEGAN;
	              }
	            }
	          }
	          return STATE_FAILED;
	        },
	        failTimeout: function () {
	          this._timer = setTimeoutContext(function () {
	            this.state = STATE_FAILED;
	          }, this.options.interval, this);
	          return STATE_FAILED;
	        },
	        reset: function () {
	          clearTimeout(this._timer);
	        },
	        emit: function () {
	          if (this.state == STATE_RECOGNIZED) {
	            this._input.tapCount = this.count;
	            this.manager.emit(this.options.event, this._input);
	          }
	        }
	      });

	      /**
	       * Simple way to create a manager with a default set of recognizers.
	       * @param {HTMLElement} element
	       * @param {Object} [options]
	       * @constructor
	       */
	      function Hammer(element, options) {
	        options = options || {};
	        options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
	        return new Manager(element, options);
	      }

	      /**
	       * @const {string}
	       */
	      Hammer.VERSION = '2.0.7';

	      /**
	       * default settings
	       * @namespace
	       */
	      Hammer.defaults = {
	        /**
	         * set if DOM events are being triggered.
	         * But this is slower and unused by simple implementations, so disabled by default.
	         * @type {Boolean}
	         * @default false
	         */
	        domEvents: false,
	        /**
	         * The value for the touchAction property/fallback.
	         * When set to `compute` it will magically set the correct value based on the added recognizers.
	         * @type {String}
	         * @default compute
	         */
	        touchAction: TOUCH_ACTION_COMPUTE,
	        /**
	         * @type {Boolean}
	         * @default true
	         */
	        enable: true,
	        /**
	         * EXPERIMENTAL FEATURE -- can be removed/changed
	         * Change the parent input target element.
	         * If Null, then it is being set the to main element.
	         * @type {Null|EventTarget}
	         * @default null
	         */
	        inputTarget: null,
	        /**
	         * force an input class
	         * @type {Null|Function}
	         * @default null
	         */
	        inputClass: null,
	        /**
	         * Default recognizer setup when calling `Hammer()`
	         * When creating a new Manager these will be skipped.
	         * @type {Array}
	         */
	        preset: [
	        // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
	        [RotateRecognizer, {
	          enable: false
	        }], [PinchRecognizer, {
	          enable: false
	        }, ['rotate']], [SwipeRecognizer, {
	          direction: DIRECTION_HORIZONTAL
	        }], [PanRecognizer, {
	          direction: DIRECTION_HORIZONTAL
	        }, ['swipe']], [TapRecognizer], [TapRecognizer, {
	          event: 'doubletap',
	          taps: 2
	        }, ['tap']], [PressRecognizer]],
	        /**
	         * Some CSS properties can be used to improve the working of Hammer.
	         * Add them to this method and they will be set when creating a new Manager.
	         * @namespace
	         */
	        cssProps: {
	          /**
	           * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
	           * @type {String}
	           * @default 'none'
	           */
	          userSelect: 'none',
	          /**
	           * Disable the Windows Phone grippers when pressing an element.
	           * @type {String}
	           * @default 'none'
	           */
	          touchSelect: 'none',
	          /**
	           * Disables the default callout shown when you touch and hold a touch target.
	           * On iOS, when you touch and hold a touch target such as a link, Safari displays
	           * a callout containing information about the link. This property allows you to disable that callout.
	           * @type {String}
	           * @default 'none'
	           */
	          touchCallout: 'none',
	          /**
	           * Specifies whether zooming is enabled. Used by IE10>
	           * @type {String}
	           * @default 'none'
	           */
	          contentZooming: 'none',
	          /**
	           * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
	           * @type {String}
	           * @default 'none'
	           */
	          userDrag: 'none',
	          /**
	           * Overrides the highlight color shown when the user taps a link or a JavaScript
	           * clickable element in iOS. This property obeys the alpha value, if specified.
	           * @type {String}
	           * @default 'rgba(0,0,0,0)'
	           */
	          tapHighlightColor: 'rgba(0,0,0,0)'
	        }
	      };
	      var STOP = 1;
	      var FORCED_STOP = 2;

	      /**
	       * Manager
	       * @param {HTMLElement} element
	       * @param {Object} [options]
	       * @constructor
	       */
	      function Manager(element, options) {
	        this.options = assign({}, Hammer.defaults, options || {});
	        this.options.inputTarget = this.options.inputTarget || element;
	        this.handlers = {};
	        this.session = {};
	        this.recognizers = [];
	        this.oldCssProps = {};
	        this.element = element;
	        this.input = createInputInstance(this);
	        this.touchAction = new TouchAction(this, this.options.touchAction);
	        toggleCssProps(this, true);
	        each(this.options.recognizers, function (item) {
	          var recognizer = this.add(new item[0](item[1]));
	          item[2] && recognizer.recognizeWith(item[2]);
	          item[3] && recognizer.requireFailure(item[3]);
	        }, this);
	      }
	      Manager.prototype = {
	        /**
	         * set options
	         * @param {Object} options
	         * @returns {Manager}
	         */
	        set: function (options) {
	          assign(this.options, options);

	          // Options that need a little more setup
	          if (options.touchAction) {
	            this.touchAction.update();
	          }
	          if (options.inputTarget) {
	            // Clean up existing event listeners and reinitialize
	            this.input.destroy();
	            this.input.target = options.inputTarget;
	            this.input.init();
	          }
	          return this;
	        },
	        /**
	         * stop recognizing for this session.
	         * This session will be discarded, when a new [input]start event is fired.
	         * When forced, the recognizer cycle is stopped immediately.
	         * @param {Boolean} [force]
	         */
	        stop: function (force) {
	          this.session.stopped = force ? FORCED_STOP : STOP;
	        },
	        /**
	         * run the recognizers!
	         * called by the inputHandler function on every movement of the pointers (touches)
	         * it walks through all the recognizers and tries to detect the gesture that is being made
	         * @param {Object} inputData
	         */
	        recognize: function (inputData) {
	          var session = this.session;
	          if (session.stopped) {
	            return;
	          }

	          // run the touch-action polyfill
	          this.touchAction.preventDefaults(inputData);
	          var recognizer;
	          var recognizers = this.recognizers;

	          // this holds the recognizer that is being recognized.
	          // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
	          // if no recognizer is detecting a thing, it is set to `null`
	          var curRecognizer = session.curRecognizer;

	          // reset when the last recognizer is recognized
	          // or when we're in a new session
	          if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
	            curRecognizer = session.curRecognizer = null;
	          }
	          var i = 0;
	          while (i < recognizers.length) {
	            recognizer = recognizers[i];

	            // find out if we are allowed try to recognize the input for this one.
	            // 1.   allow if the session is NOT forced stopped (see the .stop() method)
	            // 2.   allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
	            //      that is being recognized.
	            // 3.   allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
	            //      this can be setup with the `recognizeWith()` method on the recognizer.
	            if (session.stopped !== FORCED_STOP && (
	            // 1
	            !curRecognizer || recognizer == curRecognizer ||
	            // 2
	            recognizer.canRecognizeWith(curRecognizer))) {
	              // 3
	              recognizer.recognize(inputData);
	            } else {
	              recognizer.reset();
	            }

	            // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
	            // current active recognizer. but only if we don't already have an active recognizer
	            if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
	              curRecognizer = session.curRecognizer = recognizer;
	            }
	            i++;
	          }
	        },
	        /**
	         * get a recognizer by its event name.
	         * @param {Recognizer|String} recognizer
	         * @returns {Recognizer|Null}
	         */
	        get: function (recognizer) {
	          if (recognizer instanceof Recognizer) {
	            return recognizer;
	          }
	          var recognizers = this.recognizers;
	          for (var i = 0; i < recognizers.length; i++) {
	            if (recognizers[i].options.event == recognizer) {
	              return recognizers[i];
	            }
	          }
	          return null;
	        },
	        /**
	         * add a recognizer to the manager
	         * existing recognizers with the same event name will be removed
	         * @param {Recognizer} recognizer
	         * @returns {Recognizer|Manager}
	         */
	        add: function (recognizer) {
	          if (invokeArrayArg(recognizer, 'add', this)) {
	            return this;
	          }

	          // remove existing
	          var existing = this.get(recognizer.options.event);
	          if (existing) {
	            this.remove(existing);
	          }
	          this.recognizers.push(recognizer);
	          recognizer.manager = this;
	          this.touchAction.update();
	          return recognizer;
	        },
	        /**
	         * remove a recognizer by name or instance
	         * @param {Recognizer|String} recognizer
	         * @returns {Manager}
	         */
	        remove: function (recognizer) {
	          if (invokeArrayArg(recognizer, 'remove', this)) {
	            return this;
	          }
	          recognizer = this.get(recognizer);

	          // let's make sure this recognizer exists
	          if (recognizer) {
	            var recognizers = this.recognizers;
	            var index = inArray(recognizers, recognizer);
	            if (index !== -1) {
	              recognizers.splice(index, 1);
	              this.touchAction.update();
	            }
	          }
	          return this;
	        },
	        /**
	         * bind event
	         * @param {String} events
	         * @param {Function} handler
	         * @returns {EventEmitter} this
	         */
	        on: function (events, handler) {
	          if (events === undefined$1) {
	            return;
	          }
	          if (handler === undefined$1) {
	            return;
	          }
	          var handlers = this.handlers;
	          each(splitStr(events), function (event) {
	            handlers[event] = handlers[event] || [];
	            handlers[event].push(handler);
	          });
	          return this;
	        },
	        /**
	         * unbind event, leave emit blank to remove all handlers
	         * @param {String} events
	         * @param {Function} [handler]
	         * @returns {EventEmitter} this
	         */
	        off: function (events, handler) {
	          if (events === undefined$1) {
	            return;
	          }
	          var handlers = this.handlers;
	          each(splitStr(events), function (event) {
	            if (!handler) {
	              delete handlers[event];
	            } else {
	              handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
	            }
	          });
	          return this;
	        },
	        /**
	         * emit event to the listeners
	         * @param {String} event
	         * @param {Object} data
	         */
	        emit: function (event, data) {
	          // we also want to trigger dom events
	          if (this.options.domEvents) {
	            triggerDomEvent(event, data);
	          }

	          // no handlers, so skip it all
	          var handlers = this.handlers[event] && this.handlers[event].slice();
	          if (!handlers || !handlers.length) {
	            return;
	          }
	          data.type = event;
	          data.preventDefault = function () {
	            data.srcEvent.preventDefault();
	          };
	          var i = 0;
	          while (i < handlers.length) {
	            handlers[i](data);
	            i++;
	          }
	        },
	        /**
	         * destroy the manager and unbinds all events
	         * it doesn't unbind dom events, that is the user own responsibility
	         */
	        destroy: function () {
	          this.element && toggleCssProps(this, false);
	          this.handlers = {};
	          this.session = {};
	          this.input.destroy();
	          this.element = null;
	        }
	      };

	      /**
	       * add/remove the css properties as defined in manager.options.cssProps
	       * @param {Manager} manager
	       * @param {Boolean} add
	       */
	      function toggleCssProps(manager, add) {
	        var element = manager.element;
	        if (!element.style) {
	          return;
	        }
	        var prop;
	        each(manager.options.cssProps, function (value, name) {
	          prop = prefixed(element.style, name);
	          if (add) {
	            manager.oldCssProps[prop] = element.style[prop];
	            element.style[prop] = value;
	          } else {
	            element.style[prop] = manager.oldCssProps[prop] || '';
	          }
	        });
	        if (!add) {
	          manager.oldCssProps = {};
	        }
	      }

	      /**
	       * trigger dom event
	       * @param {String} event
	       * @param {Object} data
	       */
	      function triggerDomEvent(event, data) {
	        var gestureEvent = document.createEvent('Event');
	        gestureEvent.initEvent(event, true, true);
	        gestureEvent.gesture = data;
	        data.target.dispatchEvent(gestureEvent);
	      }
	      assign(Hammer, {
	        INPUT_START: INPUT_START,
	        INPUT_MOVE: INPUT_MOVE,
	        INPUT_END: INPUT_END,
	        INPUT_CANCEL: INPUT_CANCEL,
	        STATE_POSSIBLE: STATE_POSSIBLE,
	        STATE_BEGAN: STATE_BEGAN,
	        STATE_CHANGED: STATE_CHANGED,
	        STATE_ENDED: STATE_ENDED,
	        STATE_RECOGNIZED: STATE_RECOGNIZED,
	        STATE_CANCELLED: STATE_CANCELLED,
	        STATE_FAILED: STATE_FAILED,
	        DIRECTION_NONE: DIRECTION_NONE,
	        DIRECTION_LEFT: DIRECTION_LEFT,
	        DIRECTION_RIGHT: DIRECTION_RIGHT,
	        DIRECTION_UP: DIRECTION_UP,
	        DIRECTION_DOWN: DIRECTION_DOWN,
	        DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
	        DIRECTION_VERTICAL: DIRECTION_VERTICAL,
	        DIRECTION_ALL: DIRECTION_ALL,
	        Manager: Manager,
	        Input: Input,
	        TouchAction: TouchAction,
	        TouchInput: TouchInput,
	        MouseInput: MouseInput,
	        PointerEventInput: PointerEventInput,
	        TouchMouseInput: TouchMouseInput,
	        SingleTouchInput: SingleTouchInput,
	        Recognizer: Recognizer,
	        AttrRecognizer: AttrRecognizer,
	        Tap: TapRecognizer,
	        Pan: PanRecognizer,
	        Swipe: SwipeRecognizer,
	        Pinch: PinchRecognizer,
	        Rotate: RotateRecognizer,
	        Press: PressRecognizer,
	        on: addEventListeners,
	        off: removeEventListeners,
	        each: each,
	        merge: merge,
	        extend: extend,
	        assign: assign,
	        inherit: inherit,
	        bindFn: bindFn,
	        prefixed: prefixed
	      });

	      // this prevents errors when Hammer is loaded in the presence of an AMD
	      //  style loader but by script tag, not by the loader.
	      var freeGlobal = typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}; // jshint ignore:line
	      freeGlobal.Hammer = Hammer;
	      if (module.exports) {
	        module.exports = Hammer;
	      } else {
	        window[exportName] = Hammer;
	      }
	    })(window, document, 'Hammer');
	  })(hammer);
	  return hammer.exports;
	}

	var hammerExports = requireHammer();
	var Hammer$1 = /*@__PURE__*/getDefaultExportFromCjs(hammerExports);

	function init$1(Picasso) {
	  // Transparent component, placed on top of the data area and used to register event on
	  Picasso.component('event-area', {
	    mounted(element) {
	      element.classList.add('event-area');
	      element.style.pointerEvents = 'auto';
	      element.style.zIndex = 1;
	    },
	    render() {
	      const nodes = [];
	      return nodes;
	    }
	  });
	}

	/** @jsxRuntime classic */
	/** @jsx h */

	function getStyle(dock, rect) {
	  const style = {
	    pointerEvents: 'auto',
	    display: 'flex',
	    justifyContent: 'center',
	    alignItems: 'center',
	    color: '#7b7a78',
	    fontStyle: 'italic',
	    fontSize: '13px'
	  };
	  switch (dock) {
	    case 'left':
	      style.width = `${rect.height}px`;
	      style.transform = `rotate(-90deg) translate(-${rect.height}px, 0)`;
	      style.transformOrigin = 'top left';
	      break;
	    case 'right':
	      style.width = `${rect.height}px`;
	      style.transform = `rotate(90deg) translate(0, -${rect.width}px)`;
	      style.transformOrigin = 'top left';
	      break;
	    case 'center':
	      style.width = `${rect.width}px`;
	      style.height = `${rect.height}px`;
	      style.color = '#595959';
	      style.fontStyle = 'normal';
	      style.fontSize = '1.2em';
	      style.textAlign = 'center';
	      break;

	    // eslint-disable-next-line default-case-last
	    default:
	    case 'top':
	    case 'bottom':
	      style.justifyContent = 'flex-start';
	      style.alignItems = 'flex-start';
	      break;
	  }
	  return style;
	}
	var disclaimer = {
	  renderer: 'dom',
	  disableTriggers: true,
	  preferredSize: function preferredSize() {
	    return 22;
	  },
	  // eslint-disable-next-line no-unused-vars
	  render(h) {
	    const {
	      settings: {
	        label,
	        rtl
	      },
	      layout: {
	        dock
	      }
	    } = this.settings;
	    const dir = (dock === 'top' || dock === 'bottom') && rtl ? 'rtl' : 'ltr';
	    const style = getStyle(dock, this.rect);
	    const modifiedLabel = dock === 'center' ? label : `* ${label}`;
	    const spanStyle = dock !== 'center' ? {
	      overflow: 'hidden',
	      whiteSpace: 'nowrap',
	      textOverflow: 'ellipsis'
	    } : {};
	    return h("div", {
	      style: style,
	      dir: dir
	    }, h("span", {
	      ref: this.alignToRef,
	      style: spanStyle,
	      title: modifiedLabel
	    }, modifiedLabel));
	  }
	};

	function setup(renderer) {
	  const picasso = p();
	  // default to use canvas renderer
	  picasso.renderer.prio([renderer || 'canvas']);

	  // TODO: investigate picasso warnings
	  // if (DebugFlags.DEVELOPER) {
	  // picasso.logger.level(picassojs.logger.LOG_LEVEL.WARN);
	  // }

	  picasso.use(initialize$1);
	  picasso.use(initialize(Hammer$1));
	  picasso.use(init$1);
	  picasso.component('disclaimer', disclaimer);
	  return picasso;
	}

	const lassoIcon = {
	  shapes: [{
	    type: 'path',
	    attrs: {
	      d: 'M15.9488039,5.20769129 C16.0487326,6.70662306 15.3492311,8.30548361 14.050157,9.30477145 C12.651154,10.5039169 10.8524359,10.8037032 8.85386017,10.4039881 L7.3549284,10.0042729 L5.75606786,9.70448659 C5.75606786,9.90434416 5.65613907,10.0042729 5.4562815,10.2041305 C5.05656637,10.6038456 4.55692244,10.8037032 4.05727852,10.8037032 C3.75749217,10.8037032 3.45770582,10.7037744 3.15791946,10.6038456 C3.05799068,10.903632 3.15791946,11.2034184 3.45770582,11.7030623 C5.05656637,14.0014243 3.85742095,15.9000712 3.75749217,16 L2.2585604,15.3004985 C2.2585604,15.2005697 2.95806189,14.0014243 1.95877405,12.6024213 C1.6589877,12.0028486 1.15934378,11.0035608 1.55905891,10.0042729 C1.6589877,9.80441537 1.75891648,9.6045578 1.95877405,9.40470024 C1.6589877,8.90505631 1.55905891,8.30548361 1.85884527,7.7059109 C1.55905891,7.40612455 1.25927256,7.1063382 1.15934378,6.70662306 C0.859557424,5.90719279 0.959486209,4.5081898 1.6589877,3.30904439 C1.95877405,2.6095429 2.55834676,2.0099702 3.15791946,1.51032628 C3.95734974,0.91075357 4.95663758,0.610967217 6.15578299,0.311180864 C9.05371774,-0.388320626 11.9516525,0.111323295 13.9502282,1.61025506 C15.1493736,2.50961412 15.8488751,3.80868831 15.9488039,5.20769129 Z M13.0508691,8.10562604 C13.8502994,7.40612455 14.3499433,6.40683671 14.3499433,5.30762008 C14.2500145,4.20840345 13.550513,3.40897318 12.9509403,2.90932926 C12.1515101,2.40968533 11.252151,2.0099702 10.1529344,1.81011263 C8.95378895,1.61025506 7.75464354,1.71018384 6.45556935,1.91004141 C4.75678001,2.30975655 3.65756338,3.00925804 3.05799068,4.10847467 C2.55834676,5.00783373 2.65827554,5.90719279 2.75820433,6.20697914 C2.75820433,6.30690792 2.85813311,6.40683671 3.05799068,6.40683671 C3.15791946,6.40683671 3.25784825,6.40683671 3.35777703,6.40683671 C3.45770582,6.40683671 3.45770582,6.40683671 3.45770582,6.40683671 L3.5576346,6.40683671 L3.65756338,6.40683671 C4.65685123,6.40683671 5.4562815,6.90648063 5.85599664,7.80583969 L5.85599664,8.00569726 C6.35564056,8.10562604 7.05514205,8.30548361 7.75464354,8.50534118 L9.25357531,8.90505631 C10.0530056,9.0049851 10.7525071,9.0049851 11.4520086,8.80512753 C12.0515813,8.70519875 12.5512252,8.40541239 13.0508691,8.10562604 Z'
	    }
	  }]
	};

	function useSelect() {
	  const constraints = stardust.useConstraints();
	  const [enabled, setEnabled] = stardust.useState(false);
	  const [active, setActive] = stardust.useState(false);
	  const isInSelections = !!stardust.useLayout().qSelectionInfo.qInSelections;
	  const [lasso] = stardust.useState(() => ({
	    toggle() {
	      setActive(a => !a);
	    }
	  }));
	  stardust.useEffect(() => {
	    if (!constraints) {
	      return;
	    }
	    setEnabled(!constraints.select && !constraints.active);
	  }, [constraints]);
	  stardust.useAction(() => ({
	    key: 'lasso',
	    label: 'Lasso',
	    icon: lassoIcon,
	    hidden: !enabled || !isInSelections,
	    active,
	    action() {
	      setActive(a => !a);
	    }
	  }), [isInSelections, active, enabled]);
	  lasso.enabled = () => enabled;
	  lasso.active = () => active;
	  return lasso;
	}

	function useResize(chartInstance) {
	  const rect = stardust.useRect();
	  const options = stardust.useOptions();
	  const constraints = stardust.useConstraints();
	  const [, error] = stardust.usePromise(async () => {
	    if (!chartInstance) {
	      return;
	    }
	    chartInstance.updateConstraints(constraints);
	    chartInstance.options = options;
	    await chartInstance.resize();
	  }, [rect.width, rect.height]);
	  if (error) {
	    throw error;
	  }
	}

	function useEnvironment() {
	  const app = stardust.useApp();
	  const appLayout = stardust.useAppLayout();
	  const deviceType = stardust.useDeviceType();
	  const options = stardust.useOptions();
	  const theme = stardust.useTheme();
	  const translator = stardust.useTranslator();
	  const environment = stardust.useMemo(() => ({
	    app,
	    appLayout,
	    deviceType,
	    options,
	    theme,
	    translator
	  }),
	  // eslint-disable-next-line react-hooks/exhaustive-deps
	  [app, appLayout, options.direction, options.freeResize, translator.language(), theme.name(), deviceType]);
	  return environment;
	}

	const setupSnapshot = chartInstance => {
	  stardust.onTakeSnapshot(layout => {
	    if (!chartInstance) {
	      return undefined;
	    }
	    return chartInstance.setSnapshotData(layout);
	  });

	  // eslint-disable-next-line react-hooks/rules-of-hooks
	  stardust.useImperativeHandle(() => ({
	    getViewState() {
	      if (!chartInstance) {
	        return undefined;
	      }
	      return chartInstance.getViewState();
	    }
	  }), [chartInstance]);
	};

	var conversion$1 = {exports: {}};

	var hasRequiredConversion;
	function requireConversion() {
	  if (hasRequiredConversion) return conversion$1.exports;
	  hasRequiredConversion = 1;
	  (function (module, exports$1) {
	    !function (e, r) {
	      module.exports = r();
	    }(self, () => (() => {
	      var e = {
	          909: e => {

	            var r = Object.prototype.hasOwnProperty,
	              n = Object.prototype.toString,
	              t = Object.defineProperty,
	              i = Object.getOwnPropertyDescriptor,
	              o = function (e) {
	                return "function" == typeof Array.isArray ? Array.isArray(e) : "[object Array]" === n.call(e);
	              },
	              a = function (e) {
	                if (!e || "[object Object]" !== n.call(e)) return false;
	                var t,
	                  i = r.call(e, "constructor"),
	                  o = e.constructor && e.constructor.prototype && r.call(e.constructor.prototype, "isPrototypeOf");
	                if (e.constructor && !i && !o) return false;
	                for (t in e);
	                return void 0 === t || r.call(e, t);
	              },
	              s = function (e, r) {
	                t && "__proto__" === r.name ? t(e, r.name, {
	                  enumerable: true,
	                  configurable: true,
	                  value: r.newValue,
	                  writable: true
	                }) : e[r.name] = r.newValue;
	              },
	              u = function (e, n) {
	                if ("__proto__" === n) {
	                  if (!r.call(e, n)) return;
	                  if (i) return i(e, n).value;
	                }
	                return e[n];
	              };
	            e.exports = function e() {
	              var r,
	                n,
	                t,
	                i,
	                l,
	                c,
	                p = arguments[0],
	                f = 1,
	                m = arguments.length,
	                d = false;
	              for ("boolean" == typeof p && (d = p, p = arguments[1] || {}, f = 2), (null == p || "object" != typeof p && "function" != typeof p) && (p = {}); f < m; ++f) if (null != (r = arguments[f])) for (n in r) t = u(p, n), p !== (i = u(r, n)) && (d && i && (a(i) || (l = o(i))) ? (l ? (l = false, c = t && o(t) ? t : []) : c = t && a(t) ? t : {}, s(p, {
	                name: n,
	                newValue: e(d, c, i)
	              })) : void 0 !== i && s(p, {
	                name: n,
	                newValue: i
	              }));
	              return p;
	            };
	          },
	          8: (e, r) => {
	            (() => {

	              var e = {
	                  229: e => {
	                    var r = Object.prototype.hasOwnProperty,
	                      n = Object.prototype.toString,
	                      t = Object.defineProperty,
	                      i = Object.getOwnPropertyDescriptor,
	                      o = function (e) {
	                        return "function" == typeof Array.isArray ? Array.isArray(e) : "[object Array]" === n.call(e);
	                      },
	                      a = function (e) {
	                        if (!e || "[object Object]" !== n.call(e)) return false;
	                        var t,
	                          i = r.call(e, "constructor"),
	                          o = e.constructor && e.constructor.prototype && r.call(e.constructor.prototype, "isPrototypeOf");
	                        if (e.constructor && !i && !o) return false;
	                        for (t in e);
	                        return void 0 === t || r.call(e, t);
	                      },
	                      s = function (e, r) {
	                        t && "__proto__" === r.name ? t(e, r.name, {
	                          enumerable: true,
	                          configurable: true,
	                          value: r.newValue,
	                          writable: true
	                        }) : e[r.name] = r.newValue;
	                      },
	                      u = function (e, n) {
	                        if ("__proto__" === n) {
	                          if (!r.call(e, n)) return;
	                          if (i) return i(e, n).value;
	                        }
	                        return e[n];
	                      };
	                    e.exports = function e() {
	                      var r,
	                        n,
	                        t,
	                        i,
	                        l,
	                        c,
	                        p = arguments[0],
	                        f = 1,
	                        m = arguments.length,
	                        d = false;
	                      for ("boolean" == typeof p && (d = p, p = arguments[1] || {}, f = 2), (null == p || "object" != typeof p && "function" != typeof p) && (p = {}); f < m; ++f) if (null != (r = arguments[f])) for (n in r) t = u(p, n), p !== (i = u(r, n)) && (d && i && (a(i) || (l = o(i))) ? (l ? (l = false, c = t && o(t) ? t : []) : c = t && a(t) ? t : {}, s(p, {
	                        name: n,
	                        newValue: e(d, c, i)
	                      })) : void 0 !== i && s(p, {
	                        name: n,
	                        newValue: i
	                      }));
	                      return p;
	                    };
	                  }
	                },
	                n = {};
	              function t(r) {
	                var i = n[r];
	                if (void 0 !== i) return i.exports;
	                var o = n[r] = {
	                  exports: {}
	                };
	                return e[r](o, o.exports, t), o.exports;
	              }
	              t.n = e => {
	                var r = e && e.__esModule ? () => e.default : () => e;
	                return t.d(r, {
	                  a: r
	                }), r;
	              }, t.d = (e, r) => {
	                for (var n in r) t.o(r, n) && !t.o(e, n) && Object.defineProperty(e, n, {
	                  enumerable: true,
	                  get: r[n]
	                });
	              }, t.o = (e, r) => Object.prototype.hasOwnProperty.call(e, r), t.r = e => {
	                "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
	                  value: "Module"
	                }), Object.defineProperty(e, "__esModule", {
	                  value: true
	                });
	              };
	              var i = {};
	              (() => {
	                t.r(i), t.d(i, {
	                  default: () => Fe
	                });
	                var e = t(229),
	                  r = t.n(e);
	                const n = function (e, r, n) {
	                    if (!r) return false;
	                    var t,
	                      i = r.split("."),
	                      o = i[i.length - 1],
	                      a = e;
	                    for (t = 0; t < i.length - 1; ++t) void 0 === a[i[t]] && (a[i[t]] = Number.isNaN(+i[t + 1]) ? {} : []), a = a[i[t]];
	                    if (void 0 !== n) {
	                      var s = a[o];
	                      return a[o] = n, {
	                        updated: n,
	                        previous: s
	                      };
	                    }
	                    return delete a[o], false;
	                  },
	                  o = function (e, r, n) {
	                    var t,
	                      i = r.split("."),
	                      o = e;
	                    if (void 0 === o) return n;
	                    for (t = 0; t < i.length; ++t) {
	                      if (void 0 === o[i[t]]) return n;
	                      o = o[i[t]];
	                    }
	                    return o;
	                  },
	                  a = {
	                    EXPRESSIONS: {
	                      observed: "",
	                      trend: "STL_Trend",
	                      seasonal: "STL_Seasonal",
	                      residual: "STL_Residual"
	                    },
	                    OPTIONS: [{
	                      value: "observed",
	                      translation: "cao.trendDecomposition.parameters.decomposition.observed"
	                    }, {
	                      value: "trend",
	                      translation: "cao.trendDecomposition.parameters.decomposition.trend"
	                    }, {
	                      value: "seasonal",
	                      translation: "cao.trendDecomposition.parameters.decomposition.seasonal"
	                    }, {
	                      value: "residual",
	                      translation: "cao.trendDecomposition.parameters.decomposition.residual"
	                    }]
	                  };
	                var s = "".concat(" ", "(").concat("　"),
	                  u = "".concat("　", ")").concat(" ");
	                function l(e) {
	                  return s + e + u;
	                }
	                function c(e) {
	                  var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
	                  if (e.qLibraryId) {
	                    var n = function (e, r) {
	                      if (!r) return null;
	                      var n, t;
	                      for (n = 0; n < r.length; n++) if ((t = r[n]).qInfo.qId === e) return t;
	                      return null;
	                    }(e.qLibraryId, r.dimensionList);
	                    return n && n.qData.info[0].qTags.indexOf("$numeric") > -1;
	                  }
	                  var t = function (e, r) {
	                    if (!r) return null;
	                    var n,
	                      t,
	                      i = function (e) {
	                        var r = e.trim();
	                        "=" === r.charAt(0) && (r = (r = r.substring(1)).trim());
	                        var n = r.length - 1;
	                        return "[" === r.charAt(0) && "]" === r.charAt(n) && (r = (r = r.substring(1, n)).trim()), r;
	                      }(e);
	                    for (n = 0; n < r.length; n++) {
	                      if ((t = r[n]).qName === i) return t;
	                      if (t.qDerivedFieldData) for (var o = 0; o < t.qDerivedFieldData.qDerivedFieldLists.length; ++o) for (var a = t.qDerivedFieldData.qDerivedFieldLists[o], s = 0; s < a.qFieldDefs.length; ++s) {
	                        var u = a.qFieldDefs[s];
	                        if (u.qName === i) return u;
	                      }
	                    }
	                    return null;
	                  }(e.qDef.qFieldDefs[0], r.fieldList);
	                  return t && t.qTags.indexOf("$numeric") > -1;
	                }
	                function p(e) {
	                  return !(!e.fullAccumulation && !e.fullRange);
	                }
	                function f(e, r) {
	                  var n = e.crossAllDimensions;
	                  return 2 === r && n ? "RowNo(Total)" : "RowNo()";
	                }
	                function m(e) {
	                  var r = function (e) {
	                      return e ? (e = function (e) {
	                        return e.replace(/\/\*[^]*?\*\//g, "");
	                      }(e = function (e) {
	                        return e.replace(/\/\/(.*)$/gm, "");
	                      }(e))).trim() : "";
	                    }(e),
	                    n = r.trim();
	                  return "=" === n.substring(0, 1) ? n.substring(1).trim() : n;
	                }
	                function d() {
	                  return "[$(=Replace(GetObjectField(".concat(arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 0, "),']',']]'))]");
	                }
	                function y(e, r) {
	                  var n = e.crossAllDimensions;
	                  return 2 === r && n ? "Above(Total " : "Above(";
	                }
	                function q(e) {
	                  return void 0 === e ? ")" : ", 0, ".concat(e, ")");
	                }
	                function b(e) {
	                  return "Replace(Replace(".concat(e, ",'''',''''''),'$','$''&''')");
	                }
	                function v(e, r) {
	                  return e ? "".concat(r, '={">=$(=Min(').concat(r, "))<=$(=Max(").concat(r, '))"}') : "".concat(r, '={"=Only({1}').concat(r, ")>='$(=").concat(b("MinString(".concat(r, ")")), ")' and Only({1}").concat(r, ")<='$(=").concat(b("MaxString(".concat(r, ")")), ")'\"}");
	                }
	                function D(e) {
	                  var r = e.modifier,
	                    n = void 0 === r ? {} : r,
	                    t = e.dimensions,
	                    i = e.dimensionAndFieldList,
	                    o = e.funcComp,
	                    a = void 0 === o ? "Sum" : o,
	                    s = e.valueComp,
	                    u = void 0 === s ? "0" : s;
	                  if (!n.showExcludedValues) return "";
	                  if (t && 1 === t.length) {
	                    var l = v(c(t[0], i), d(0));
	                    return "".concat(a, "({1<").concat(l, ">}").concat(u, ")");
	                  }
	                  if (t && 2 === t.length) {
	                    var p = c(t[0], i),
	                      f = c(t[1], i),
	                      m = d(0),
	                      y = d(1),
	                      q = v(p, m),
	                      b = v(f, y);
	                    return "".concat(a, "({1<").concat(q, ",").concat(b, ">}").concat(u, ")");
	                  }
	                  return "".concat(a, "({1}").concat(u, ")");
	                }
	                function g(e) {
	                  return "".concat(e, "(");
	                }
	                function h(e) {
	                  var r = e.properties,
	                    n = e.layout;
	                  return o(r, "qHyperCubeDef.qDimensions", o(n, "qHyperCube.qDimensionInfo", [])).length;
	                }
	                const x = {
	                  isFullRange: p,
	                  getNumDimensions: h,
	                  getExpressionWithExcludedComp: function (e) {
	                    var r = e.expression,
	                      n = e.modifier,
	                      t = e.dimensions,
	                      i = e.dimensionAndFieldList,
	                      o = e.treatMissingAsNull,
	                      a = l(m(r));
	                    if (!n.showExcludedValues) return a;
	                    var s = D({
	                        modifier: n,
	                        dimensions: t,
	                        dimensionAndFieldList: i
	                      }),
	                      u = o ? "" : ", 0";
	                    if (t && 1 === t.length) {
	                      var c = d(0);
	                      return "If(Count(".concat(c, ") > 0, ").concat(a, " + ").concat(s).concat(u, ")");
	                    }
	                    if (t && 2 === t.length) {
	                      var p = d(0),
	                        f = d(1);
	                      return "If(Count(".concat(p, ") * Count(").concat(f, ") > 0, ").concat(a, " + ").concat(s).concat(u, ")");
	                    }
	                    return a;
	                  },
	                  getRowNoComp: f,
	                  getNumStepComp: function (e, r) {
	                    if (!p(e)) {
	                      var n = e.steps;
	                      return "number" != typeof n || Number.isNaN(n) ? 6 : n;
	                    }
	                    return f(e, r);
	                  },
	                  getAboveCompPrefix: y,
	                  getAboveCompSuffix: q,
	                  getAboveComp: function (e, r, n, t) {
	                    return y(e, r) + n + q(t);
	                  },
	                  getFunctionPrefix: g,
	                  getFunctionSuffix: function () {
	                    return ")";
	                  },
	                  getRangeComp: function (e, r) {
	                    return g(e) + r + ")";
	                  },
	                  getAggrComp: function (e, r, n) {
	                    return "Aggr(".concat(e, ", ").concat(r, ", ").concat(n, ")");
	                  },
	                  getExcludedComp: D,
	                  needDimension: function (e) {
	                    var r = e.modifier,
	                      n = e.properties,
	                      t = e.layout,
	                      i = function (e) {
	                        return void 0 === e.primaryDimension ? e.accumulationDimension : e.primaryDimension;
	                      }(r);
	                    return 0 === i && 2 === h({
	                      properties: n,
	                      layout: t
	                    });
	                  },
	                  getDimComp: function (e, r) {
	                    var n = function (e) {
	                        return e[arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0].qDef.qSortCriterias[0];
	                      }(e, r),
	                      t = d(r);
	                    if (!n.qSortByExpression && !n.qSortByNumeric && !n.qSortByAscii) return t;
	                    var i = ["Descending", "Ascending"],
	                      o = n.qSortByNumeric ? "(Numeric, ".concat(i[(n.qSortByNumeric + 1) / 2], ")") : "",
	                      a = n.qSortByAscii ? "(Text, ".concat(i[(n.qSortByAscii + 1) / 2], ")") : "";
	                    return n.qSortByNumeric && n.qSortByAscii ? "(".concat(t, ", ").concat(o, ", ").concat(a, ")") : n.qSortByNumeric ? "(".concat(t, ", ").concat(o, ")") : n.qSortByAscii ? "(".concat(t, ", ").concat(a, ")") : t;
	                  },
	                  simplifyExpression: m,
	                  extractInputExpression: function (e) {
	                    var r = e.outputExpression;
	                    if (e.modifier) {
	                      var n = r.indexOf(s);
	                      if (-1 !== n) {
	                        var t = r.indexOf(u);
	                        if (-1 !== t) return r.substring(n + s.length, t);
	                      }
	                    }
	                  },
	                  initModifier: function (e, r) {
	                    Object.keys(r).forEach(function (n) {
	                      void 0 === e[n] && (e[n] = r[n]);
	                    });
	                  },
	                  isNumeric: c,
	                  isApplicable: function (e) {
	                    var r = e.properties,
	                      n = e.layout,
	                      t = e.minDimensions,
	                      i = void 0 === t ? 1 : t,
	                      o = e.maxDimensions,
	                      a = void 0 === o ? 2 : o;
	                    if (!r && !n) return true;
	                    var s = h({
	                      properties: r,
	                      layout: n
	                    });
	                    return s >= i && s <= a;
	                  },
	                  getExpressionWithMarkers: l,
	                  canExtract: function (e) {
	                    var r = e.indexOf(s),
	                      n = e.indexOf(u);
	                    return r > -1 && n > -1 && r < n;
	                  },
	                  getDimDefWithWrapper: d,
	                  getFieldWithWrapper: function (e) {
	                    var r = e ? e.replace(/]/g, "]]") : e;
	                    return "[".concat(r, "]");
	                  },
	                  generateTSDExpression: function (e, r, n) {
	                    var t = r || e.outputExpression;
	                    if (e.base && e.base.qDef && (t = r !== e.base.qDef ? r : e.base.qDef), "observed" !== e.decomposition) {
	                      var i = n.qHyperCubeDef.qMeasures.find(function (r) {
	                        return r.qDef.base && r.qDef.base.qLibraryId && e.base && e.base.qLibraryId ? r.qDef.base.qLibraryId === e.base.qLibraryId : null;
	                      });
	                      i && r !== i.qDef.qLabel && (t = i.qLibraryId || i.qDef.base.qLibraryId ? "[".concat(i.qDef.qLabel, "]") : i.qDef.base.qDef);
	                      var o = function (e) {
	                        var r = a.OPTIONS.find(function (r) {
	                          return r.value === e.decomposition;
	                        });
	                        return r ? a.EXPRESSIONS[r.value] : "";
	                      }(e);
	                      t = t.startsWith("=") ? t.substr(1) : t, t = "".concat(o, "(").concat(t, ", ").concat(e.steps, ")");
	                    }
	                    return t;
	                  },
	                  getDecomposition: function (e) {
	                    var r = "observed";
	                    return Object.values(a.EXPRESSIONS).find(function (n) {
	                      var t = e.qDef.base.qDef.toLowerCase() || e.qDef.qDef.toLowerCase();
	                      return a.EXPRESSIONS[n] && t.includes(a.EXPRESSIONS[n].toLowerCase()) && (r = n), n;
	                    }), r;
	                  }
	                };
	                function A(e, r) {
	                  (null == r || r > e.length) && (r = e.length);
	                  for (var n = 0, t = new Array(r); n < r; n++) t[n] = e[n];
	                  return t;
	                }
	                function E(e) {
	                  return E = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) {
	                    return typeof e;
	                  } : function (e) {
	                    return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
	                  }, E(e);
	                }
	                var C = r().bind(null, true),
	                  I = {},
	                  S = Array.isArray;
	                function M(e) {
	                  return null != e && !Array.isArray(e) && "object" === E(e);
	                }
	                function L(e) {
	                  return void 0 === e;
	                }
	                function O(e, r) {
	                  return "function" == typeof e[r] || "$$" === r.substring(0, 2) || "_" === r.substring(0, 1);
	                }
	                function F(e, r) {
	                  var n,
	                    t = r.substring(1).split("/").slice(0, -1);
	                  return t.forEach(function (r, i) {
	                    if (i !== t.length) {
	                      n = +r;
	                      var o = Number.isNaN(n) ? {} : [];
	                      e[n || r] = L(e[n || r]) ? o : e[r], e = e[n || r];
	                    }
	                  }), e;
	                }
	                function P(e, r) {
	                  var n = true;
	                  if (M(e) && M(r)) return Object.keys(e).length === Object.keys(r).length && (Object.keys(e).forEach(function (t) {
	                    P(e[t], r[t]) || (n = false);
	                  }), n);
	                  if (S(e) && S(r)) {
	                    if (e.length !== r.length) return false;
	                    for (var t = 0, i = e.length; t < i; t += 1) if (!P(e[t], r[t])) return false;
	                    return true;
	                  }
	                  return e === r;
	                }
	                I.generate = function (e, r, n) {
	                  n = n || "";
	                  var t = [];
	                  return Object.keys(r).forEach(function (i) {
	                    var o = function (e) {
	                        return e ? C({}, {
	                          val: e
	                        }).val : e;
	                      }(r[i]),
	                      a = e[i],
	                      s = "".concat(n, "/").concat(i);
	                    P(o, a) || O(r, i) || (L(a) ? t.push({
	                      op: "add",
	                      path: s,
	                      value: o
	                    }) : M(o) && M(a) ? t = t.concat(I.generate(a, o, s)) : S(o) && S(a) ? t = t.concat(function (e, r, n) {
	                      var t = [],
	                        i = e.slice(),
	                        o = -1;
	                      function a(e, r, n) {
	                        if (e[n] && L(e[n].qInfo)) return null;
	                        if (e[n] && e[n].qInfo.qId === r) return n;
	                        for (var t = 0, i = e.length; t < i; t += 1) if (e[t] && e[t].qInfo.qId === r) return t;
	                        return -1;
	                      }
	                      if (P(r, i)) return t;
	                      if (!L(r[0]) && L(r[0].qInfo)) return t.push({
	                        op: "replace",
	                        path: n,
	                        value: r
	                      }), t;
	                      for (var s = i.length - 1; s >= 0; s -= 1) -1 === (o = a(r, i[s].qInfo && i[s].qInfo.qId, s)) ? (t.push({
	                        op: "remove",
	                        path: "".concat(n, "/").concat(s)
	                      }), i.splice(s, 1)) : t = t.concat(I.generate(i[s], r[o], "".concat(n, "/").concat(s)));
	                      for (var u = 0, l = r.length; u < l; u += 1) -1 === (o = a(i, r[u].qInfo && r[u].qInfo.qId)) ? (t.push({
	                        op: "add",
	                        path: "".concat(n, "/").concat(u),
	                        value: r[u]
	                      }), i.splice(u, 0, r[u])) : o !== u && (t.push({
	                        op: "move",
	                        path: "".concat(n, "/").concat(u),
	                        from: "".concat(n, "/").concat(o)
	                      }), i.splice(u, 0, i.splice(o, 1)[0]));
	                      return t;
	                    }(a, o, s)) : t.push({
	                      op: "replace",
	                      path: "".concat(n, "/").concat(i),
	                      value: o
	                    }));
	                  }), Object.keys(e).forEach(function (i) {
	                    L(r[i]) && !O(e, i) && t.push({
	                      op: "remove",
	                      path: "".concat(n, "/").concat(i)
	                    });
	                  }), t;
	                }, I.apply = function (e, r) {
	                  r.forEach(function (r) {
	                    var n,
	                      t,
	                      i = F(e, r.path),
	                      o = r.path.split("/").splice(-1)[0],
	                      a = o && Number.isNaN(+o) ? i[o] : i[+o] || i,
	                      s = r.from ? r.from.split("/").splice(-1)[0] : null;
	                    if ("/" === r.path && (i = null, a = e), "add" === r.op || "replace" === r.op) {
	                      if (S(i)) "-" === o && (o = i.length), i.splice(+o, "add" === r.op ? 0 : 1, r.value);else if (S(a) && S(r.value)) {
	                        var u,
	                          l = r.value.slice();
	                        a.length = 0, (u = a).push.apply(u, function (e) {
	                          if (Array.isArray(e)) return A(e);
	                        }(t = l) || function (e) {
	                          if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e);
	                        }(t) || function (e, r) {
	                          if (e) {
	                            if ("string" == typeof e) return A(e, r);
	                            var n = Object.prototype.toString.call(e).slice(8, -1);
	                            return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? A(e, r) : void 0;
	                          }
	                        }(t) || function () {
	                          throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	                        }());
	                      } else if (M(a) && M(r.value)) n = a, Object.keys(n).forEach(function (e) {
	                        Object.getOwnPropertyDescriptor(n, e).configurable && !O(n, e) && delete n[e];
	                      }), C(a, r.value);else {
	                        if (!i) throw new Error("Patchee is not an object we can patch");
	                        i[o] = r.value;
	                      }
	                    } else if ("move" === r.op) {
	                      var c = F(e, r.from);
	                      S(i) ? i.splice(+o, 0, c.splice(+s, 1)[0]) : (i[o] = c[s], delete c[s]);
	                    } else "remove" === r.op && (S(i) ? i.splice(+o, 1) : delete i[o]);
	                  });
	                }, I.clone = function (e) {
	                  return C({}, e);
	                }, I.createPatch = function (e, r, n) {
	                  var t = {
	                    op: e.toLowerCase(),
	                    path: n
	                  };
	                  return "move" === t.op ? t.from = r : void 0 !== r && (t.value = r), t;
	                }, I.updateObject = function (e, r) {
	                  Object.keys(e).length ? I.apply(e, I.generate(e, r)) : C(e, r);
	                };
	                const V = I,
	                  N = function (e, n, t) {
	                    if (!e) return Promise.resolve();
	                    var i = V.generate(n, t);
	                    return r()(true, n, t), i && i.length ? (i = i.map(function (e) {
	                      return {
	                        qOp: e.op,
	                        qValue: JSON.stringify(e.value),
	                        qPath: e.path
	                      };
	                    }), e.applyPatches(i, true)) : Promise.resolve();
	                  };
	                var w = "accumulation";
	                function H(e, r) {
	                  var n = o(e, r);
	                  if (n) for (var t = 0; t < n.length; t++) if (n[t].type === w) return n[t];
	                }
	                function T(e, r) {
	                  var n = function (e, r) {
	                    var n = o(e, r);
	                    if (!n) return -1;
	                    for (var t = 0; t < n.length; t++) if (n[t].type === w) return t;
	                    return -1;
	                  }(e, r);
	                  return n > -1 ? "".concat(r, ".").concat(n) : r;
	                }
	                var j = {
	                  type: "accumulation",
	                  disabled: false,
	                  accumulationDimension: 0,
	                  crossAllDimensions: false,
	                  showExcludedValues: true,
	                  fullAccumulation: false,
	                  steps: 6,
	                  outputExpression: ""
	                };
	                const R = {
	                  translationKey: "properties.modifier.accumulation",
	                  needDimension: x.needDimension,
	                  isApplicable: function (e) {
	                    var r = e.properties,
	                      n = e.layout;
	                    return x.isApplicable({
	                      properties: r,
	                      layout: n,
	                      minDimensions: 1,
	                      maxDimensions: 2
	                    });
	                  },
	                  generateExpression: function (e) {
	                    var r = e.expression,
	                      n = e.modifier,
	                      t = e.properties,
	                      i = e.layout,
	                      a = e.numDimensions,
	                      s = e.dimensionAndFieldList;
	                    if (!n) return r;
	                    var u = a;
	                    void 0 === u && (u = x.getNumDimensions({
	                      properties: t,
	                      layout: i
	                    }));
	                    var l = o(t, "qHyperCubeDef.qDimensions", []),
	                      c = x.getExpressionWithExcludedComp({
	                        expression: r,
	                        modifier: n,
	                        dimensions: l,
	                        dimensionAndFieldList: s
	                      }),
	                      p = x.getNumStepComp(n, u),
	                      f = x.getAboveComp(n, u, c, p),
	                      m = x.getRangeComp("RangeSum", f);
	                    if (x.needDimension({
	                      modifier: n,
	                      properties: t,
	                      layout: i
	                    })) {
	                      var d = x.getDimComp(l, 1),
	                        y = x.getDimComp(l, 0),
	                        q = x.getAggrComp(m, d, y);
	                      m = n.showExcludedValues ? x.getExcludedComp({
	                        modifier: n,
	                        dimensions: l,
	                        dimensionAndFieldList: s,
	                        valueComp: q
	                      }) : q;
	                    }
	                    return m;
	                  },
	                  extractInputExpression: x.extractInputExpression,
	                  initModifier: function (e) {
	                    x.initModifier(e, j);
	                  },
	                  enableTotalsFunction: function () {
	                    return false;
	                  },
	                  propertyPanelDef: function (e) {
	                    var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
	                      n = {
	                        type: "items",
	                        items: {
	                          disclaimer: {
	                            component: "text",
	                            translation: r.disclaimer || "properties.modifier.accumulation.disclaimer",
	                            show: function (e, r) {
	                              return !x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          },
	                          settings: {
	                            type: "items",
	                            items: {
	                              primaryDimension: {
	                                refFn: function (r) {
	                                  return "".concat(T(r, e), ".accumulationDimension");
	                                },
	                                type: "integer",
	                                translation: r.primaryDimension || "properties.modifier.primaryDimension",
	                                title: {
	                                  translation: r.primaryDimensionTooltip || "properties.modifier.accumulation.primaryDimension.tooltip"
	                                },
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: 1,
	                                options: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.map(function (e, r) {
	                                    return {
	                                      value: r,
	                                      label: e.qGroupFallbackTitles[0]
	                                    };
	                                  });
	                                },
	                                show: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              },
	                              crossAllDimensions: {
	                                refFn: function (r) {
	                                  return "".concat(T(r, e), ".crossAllDimensions");
	                                },
	                                type: "boolean",
	                                translation: r.crossAllDimensions || "properties.modifier.crossAllDimensions",
	                                title: {
	                                  translation: r.crossAllDimensionsTooltip || "properties.modifier.accumulation.crossAllDimensions.tooltip"
	                                },
	                                schemaIgnore: true,
	                                defaultValue: false,
	                                show: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              },
	                              fullRange: {
	                                refFn: function (r) {
	                                  return "".concat(T(r, e), ".fullAccumulation");
	                                },
	                                type: "boolean",
	                                translation: r.range || "properties.modifier.range",
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: false,
	                                options: [{
	                                  value: true,
	                                  translation: r.rangeFull || "properties.modifier.range.full"
	                                }, {
	                                  value: false,
	                                  translation: r.rangeCustom || "properties.modifier.range.custom"
	                                }]
	                              },
	                              steps: {
	                                refFn: function (r) {
	                                  return "".concat(T(r, e), ".steps");
	                                },
	                                type: "integer",
	                                translation: r.rangeSteps || "properties.modifier.range.steps",
	                                schemaIgnore: true,
	                                defaultValue: 6,
	                                change: function (r) {
	                                  var n = H(r, e);
	                                  if (n) {
	                                    var t = n.steps;
	                                    n.steps = "number" != typeof t || Number.isNaN(t) ? 6 : Math.abs(t);
	                                  }
	                                },
	                                show: function (r) {
	                                  var n = H(r, e);
	                                  return n && !n.fullAccumulation;
	                                }
	                              },
	                              showExcludedValues: {
	                                refFn: function (r) {
	                                  return "".concat(T(r, e), ".showExcludedValues");
	                                },
	                                type: "boolean",
	                                translation: r.showExcludedValues || "properties.modifier.showExcludedValues",
	                                schemaIgnore: true,
	                                defaultValue: true
	                              }
	                            },
	                            show: function (e, r) {
	                              return x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          }
	                        },
	                        show: function (r, n, t) {
	                          var i = t.ext.support.modifiers;
	                          if (!Array.isArray(i) || -1 === i.indexOf(w)) return false;
	                          var o = H(r, e);
	                          return o && !o.disabled;
	                        }
	                      };
	                    return n;
	                  }
	                };
	                var _ = "movingAverage";
	                function B(e, r) {
	                  var n = o(e, r);
	                  if (n) for (var t = 0; t < n.length; t++) if (n[t].type === _) return n[t];
	                }
	                function k(e, r) {
	                  var n = function (e, r) {
	                    var n = o(e, r);
	                    if (!n) return -1;
	                    for (var t = 0; t < n.length; t++) if (n[t].type === _) return t;
	                    return -1;
	                  }(e, r);
	                  return n > -1 ? "".concat(r, ".").concat(n) : r;
	                }
	                var W = {
	                  type: "movingAverage",
	                  disabled: false,
	                  primaryDimension: 0,
	                  crossAllDimensions: false,
	                  showExcludedValues: true,
	                  fullRange: false,
	                  steps: 6,
	                  outputExpression: "",
	                  nullSuppression: false
	                };
	                const $ = {
	                  translationKey: "properties.modifier.movingAverage",
	                  needDimension: x.needDimension,
	                  isApplicable: function (e) {
	                    var r = e.properties,
	                      n = e.layout;
	                    return x.isApplicable({
	                      properties: r,
	                      layout: n,
	                      minDimensions: 1,
	                      maxDimensions: 2
	                    });
	                  },
	                  generateExpression: function (e) {
	                    var r,
	                      n = e.expression,
	                      t = e.modifier,
	                      i = e.properties,
	                      a = e.layout,
	                      s = e.numDimensions,
	                      u = e.dimensionAndFieldList;
	                    if (!t) return n;
	                    var l = s;
	                    void 0 === l && (l = x.getNumDimensions({
	                      properties: i,
	                      layout: a
	                    }));
	                    var c = o(i, "qHyperCubeDef.qDimensions", []),
	                      p = t.showExcludedValues && t.nullSuppression,
	                      f = x.getExpressionWithExcludedComp({
	                        expression: n,
	                        modifier: t,
	                        dimensions: c,
	                        dimensionAndFieldList: u,
	                        treatMissingAsNull: p
	                      }),
	                      m = x.getNumStepComp(t, l),
	                      d = x.getAboveComp(t, l, f, m);
	                    if (t.nullSuppression) r = x.getRangeComp("RangeAvg", d);else {
	                      var y = x.getRangeComp("RangeSum", d),
	                        q = function (e, r) {
	                          var n = x.getRowNoComp(e, r);
	                          if (!x.isFullRange(e)) {
	                            var t = e.steps,
	                              i = "number" != typeof t || Number.isNaN(t) ? 6 : t;
	                            return "RangeMin(".concat(i, ", ").concat(n, ")");
	                          }
	                          return n;
	                        }(t, l);
	                      r = "".concat(y, " / ").concat(q);
	                    }
	                    var b = r;
	                    if (x.needDimension({
	                      modifier: t,
	                      properties: i,
	                      layout: a
	                    })) {
	                      var v = x.getDimComp(c, 1),
	                        D = x.getDimComp(c, 0),
	                        g = x.getAggrComp(b, v, D);
	                      b = t.showExcludedValues ? x.getExcludedComp({
	                        modifier: t,
	                        dimensions: c,
	                        dimensionAndFieldList: u,
	                        funcComp: "Only",
	                        valueComp: g
	                      }) : g;
	                    }
	                    return b;
	                  },
	                  extractInputExpression: x.extractInputExpression,
	                  initModifier: function (e) {
	                    x.initModifier(e, W);
	                  },
	                  enableTotalsFunction: function () {
	                    return false;
	                  },
	                  propertyPanelDef: function (e) {
	                    var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
	                      n = {
	                        type: "items",
	                        items: {
	                          disclaimer: {
	                            component: "text",
	                            translation: r.disclaimer || "properties.modifier.movingAverage.disclaimer",
	                            show: function (e, r) {
	                              return !x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          },
	                          settings: {
	                            type: "items",
	                            items: {
	                              primaryDimension: {
	                                refFn: function (r) {
	                                  return "".concat(k(r, e), ".primaryDimension");
	                                },
	                                type: "integer",
	                                translation: r.primaryDimension || "properties.modifier.primaryDimension",
	                                title: {
	                                  translation: r.primaryDimensionTooltip || "properties.modifier.movingAverage.primaryDimension.tooltip"
	                                },
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: 1,
	                                options: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.map(function (e, r) {
	                                    return {
	                                      value: r,
	                                      label: e.qGroupFallbackTitles[0]
	                                    };
	                                  });
	                                },
	                                show: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              },
	                              crossAllDimensions: {
	                                refFn: function (r) {
	                                  return "".concat(k(r, e), ".crossAllDimensions");
	                                },
	                                type: "boolean",
	                                translation: r.crossAllDimensions || "properties.modifier.crossAllDimensions",
	                                title: {
	                                  translation: r.crossAllDimensionsTooltip || "properties.modifier.movingAverage.crossAllDimensions.tooltip"
	                                },
	                                schemaIgnore: true,
	                                defaultValue: false,
	                                show: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              },
	                              fullRange: {
	                                refFn: function (r) {
	                                  return "".concat(k(r, e), ".fullRange");
	                                },
	                                type: "boolean",
	                                translation: r.range || "properties.modifier.range",
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: false,
	                                options: [{
	                                  value: true,
	                                  translation: r.rangeFull || "properties.modifier.range.full"
	                                }, {
	                                  value: false,
	                                  translation: r.rangeCustom || "properties.modifier.range.custom"
	                                }]
	                              },
	                              steps: {
	                                refFn: function (r) {
	                                  return "".concat(k(r, e), ".steps");
	                                },
	                                type: "integer",
	                                translation: r.rangeSteps || "properties.modifier.range.steps",
	                                schemaIgnore: true,
	                                defaultValue: 6,
	                                change: function (r) {
	                                  var n = B(r, e);
	                                  if (n) {
	                                    var t = n.steps;
	                                    n.steps = "number" != typeof t || Number.isNaN(t) ? 6 : Math.abs(t);
	                                  }
	                                },
	                                show: function (r) {
	                                  var n = B(r, e);
	                                  return n && !n.fullRange;
	                                }
	                              },
	                              showExcludedValues: {
	                                refFn: function (r) {
	                                  return "".concat(k(r, e), ".showExcludedValues");
	                                },
	                                type: "boolean",
	                                translation: r.showExcludedValues || "properties.modifier.showExcludedValues",
	                                schemaIgnore: true,
	                                defaultValue: true
	                              },
	                              nullSuppression: {
	                                refFn: function (r) {
	                                  return "".concat(k(r, e), ".nullSuppression");
	                                },
	                                type: "boolean",
	                                translation: r.showNull || "properties.dimensions.showNull",
	                                schemaIgnore: true,
	                                defaultValue: false,
	                                inverted: true
	                              }
	                            },
	                            show: function (e, r) {
	                              return x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          }
	                        },
	                        show: function (r, n, t) {
	                          var i = t.ext.support.modifiers;
	                          if (!Array.isArray(i) || -1 === i.indexOf(_)) return false;
	                          var o = B(r, e);
	                          return o && !o.disabled;
	                        }
	                      };
	                    return n;
	                  }
	                };
	                var U = "timeSeriesDecomposition";
	                function G(e, r) {
	                  var n = o(e, r);
	                  if (n) for (var t = 0; t < n.length; t++) if (n[t].type === U) return n[t];
	                }
	                function z(e, r) {
	                  var n = function (e, r) {
	                    var n = o(e, r);
	                    if (!n) return -1;
	                    for (var t = 0; t < n.length; t++) if (n[t].type === U) return t;
	                    return -1;
	                  }(e, r);
	                  return n > -1 ? "".concat(r, ".").concat(n) : r;
	                }
	                var Y = {
	                  type: "timeSeriesDecomposition",
	                  disabled: false,
	                  decomposition: "",
	                  steps: 2,
	                  outputExpression: ""
	                };
	                const J = {
	                  translationKey: "properties.modifier.timeSeriesDecomposition",
	                  needDimension: x.needDimension,
	                  isApplicable: function (e) {
	                    var r = e.properties,
	                      n = e.layout;
	                    return x.isApplicable({
	                      properties: r,
	                      layout: n,
	                      minDimensions: 1,
	                      maxDimensions: 2
	                    });
	                  },
	                  generateExpression: function (e) {
	                    var r = e.expression,
	                      n = e.modifier,
	                      t = e.properties;
	                    return n ? x.generateTSDExpression(n, r, t) : r;
	                  },
	                  extractInputExpression: x.extractInputExpression,
	                  initModifier: function (e, r) {
	                    x.initModifier(e, Y), "" === e.decomposition && r && (e.decomposition = x.getDecomposition(r));
	                  },
	                  propertyPanelDef: function (e) {
	                    var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
	                      n = {
	                        type: "items",
	                        items: {
	                          disclaimer: {
	                            component: "text",
	                            translation: r.timeSeriesDecomposition || "properties.modifier.timeSeriesDecomposition",
	                            show: function (e, r) {
	                              return !x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          },
	                          settings: {
	                            type: "items",
	                            items: {
	                              decomposition: {
	                                refFn: function (r) {
	                                  return "".concat(z(r, e), ".decomposition");
	                                },
	                                type: "string",
	                                translation: r.modifierTrendDecompositionDecomposition || "properties.modifier.trendDecomposition.decomposition",
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: r.trendDecompositionParametersDecompositionObserved || "cao.trendDecomposition.parameters.decomposition.observed",
	                                options: a.OPTIONS
	                              },
	                              steps: {
	                                refFn: function (r) {
	                                  return "".concat(z(r, e), ".steps");
	                                },
	                                type: "integer",
	                                translation: r.modifierTimeSeriesDecompositionPeriods || "properties.modifier.timeSeriesDecomposition.periods",
	                                schemaIgnore: true,
	                                defaultValue: 2,
	                                change: function (r, n) {
	                                  var t = G(r, e);
	                                  if (t) {
	                                    var i = t.steps;
	                                    t.steps = "number" != typeof i || Number.isNaN(i) ? 2 : Math.abs(i), n.properties.qHyperCubeDef.qMeasures = n.properties.qHyperCubeDef.qMeasures.map(function (e) {
	                                      return e.qDef.modifiers.map(function (e) {
	                                        return "timeSeriesDecomposition" === e.type ? e.steps = i : e.steps = e.steps, e;
	                                      }), e;
	                                    });
	                                  }
	                                },
	                                show: function (r) {
	                                  var n = G(r, e);
	                                  return n && !n.fullRange;
	                                }
	                              }
	                            },
	                            show: function (e, r) {
	                              return x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          }
	                        },
	                        show: function (r, n, t) {
	                          var i = t.ext.support.modifiers;
	                          if (!Array.isArray(i) || -1 === i.indexOf(U)) return false;
	                          var o = G(r, e);
	                          return o && !o.disabled;
	                        }
	                      };
	                    return n;
	                  }
	                };
	                var K = "difference";
	                function X(e, r) {
	                  var n = o(e, r);
	                  if (n) for (var t = 0; t < n.length; t++) if (n[t].type === K) return n[t];
	                }
	                function Q(e, r) {
	                  var n = function (e, r) {
	                    var n = o(e, r);
	                    if (!n) return -1;
	                    for (var t = 0; t < n.length; t++) if (n[t].type === K) return t;
	                    return -1;
	                  }(e, r);
	                  return n > -1 ? "".concat(r, ".").concat(n) : r;
	                }
	                var Z = {
	                  type: "difference",
	                  disabled: false,
	                  primaryDimension: 0,
	                  crossAllDimensions: false,
	                  showExcludedValues: true,
	                  outputExpression: ""
	                };
	                const ee = {
	                  translationKey: "properties.modifier.difference",
	                  needDimension: x.needDimension,
	                  isApplicable: function (e) {
	                    var r = e.properties,
	                      n = e.layout;
	                    return x.isApplicable({
	                      properties: r,
	                      layout: n,
	                      minDimensions: 1,
	                      maxDimensions: 2
	                    });
	                  },
	                  extractInputExpression: x.extractInputExpression,
	                  generateExpression: function (e) {
	                    var r = e.expression,
	                      n = e.modifier,
	                      t = e.properties,
	                      i = e.layout,
	                      a = e.numDimensions,
	                      s = e.dimensionAndFieldList;
	                    if (!n) return r;
	                    var u = a;
	                    void 0 === u && (u = x.getNumDimensions({
	                      properties: t,
	                      layout: i
	                    }));
	                    var l = o(t, "qHyperCubeDef.qDimensions", []),
	                      c = x.getExpressionWithExcludedComp({
	                        expression: r,
	                        modifier: n,
	                        dimensions: l,
	                        dimensionAndFieldList: s
	                      }),
	                      p = x.getAboveComp(n, u, c),
	                      f = "".concat(c, " - ").concat(p);
	                    if (x.needDimension({
	                      modifier: n,
	                      properties: t,
	                      layout: i
	                    })) {
	                      var m = x.getDimComp(l, 1),
	                        d = x.getDimComp(l, 0),
	                        y = x.getAggrComp(f, m, d);
	                      f = n.showExcludedValues ? x.getExcludedComp({
	                        modifier: n,
	                        dimensions: l,
	                        dimensionAndFieldList: s,
	                        funcComp: "Only",
	                        valueComp: y
	                      }) : y;
	                    }
	                    return f;
	                  },
	                  initModifier: function (e) {
	                    Object.keys(Z).forEach(function (r) {
	                      void 0 === e[r] && (e[r] = Z[r]);
	                    });
	                  },
	                  enableTotalsFunction: function () {
	                    return false;
	                  },
	                  propertyPanelDef: function (e) {
	                    var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
	                      n = {
	                        type: "items",
	                        items: {
	                          disclaimer: {
	                            component: "text",
	                            translation: r.disclaimer || "properties.modifier.difference.disclaimer",
	                            show: function (e, r) {
	                              return !x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          },
	                          settings: {
	                            type: "items",
	                            items: {
	                              primaryDimension: {
	                                refFn: function (r) {
	                                  return "".concat(Q(r, e), ".primaryDimension");
	                                },
	                                type: "integer",
	                                translation: r.primaryDimension || "properties.modifier.primaryDimension",
	                                title: {
	                                  translation: r.primaryDimensionTooltip || "properties.modifier.difference.primaryDimension.tooltip"
	                                },
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: 1,
	                                options: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.map(function (e, r) {
	                                    return {
	                                      value: r,
	                                      label: e.qGroupFallbackTitles[0]
	                                    };
	                                  });
	                                },
	                                show: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              },
	                              crossAllDimensions: {
	                                refFn: function (r) {
	                                  return "".concat(Q(r, e), ".crossAllDimensions");
	                                },
	                                type: "boolean",
	                                translation: r.crossAllDimensions || "properties.modifier.crossAllDimensions",
	                                title: {
	                                  translation: r.crossAllDimensionsTooltip || "properties.modifier.difference.crossAllDimensions.tooltip"
	                                },
	                                schemaIgnore: true,
	                                defaultValue: false,
	                                show: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              },
	                              showExcludedValues: {
	                                refFn: function (r) {
	                                  return "".concat(Q(r, e), ".showExcludedValues");
	                                },
	                                type: "boolean",
	                                translation: r.showExcludedValues || "properties.modifier.showExcludedValues",
	                                schemaIgnore: true,
	                                defaultValue: true
	                              }
	                            },
	                            show: function (e, r) {
	                              return x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          }
	                        },
	                        show: function (r, n, t) {
	                          var i = t.ext.support.modifiers;
	                          if (!Array.isArray(i) || -1 === i.indexOf(K)) return false;
	                          var o = X(r, e);
	                          return o && !o.disabled;
	                        }
	                      };
	                    return n;
	                  }
	                };
	                var re = "normalization";
	                function ne(e, r) {
	                  var n = o(e, r);
	                  if (n) for (var t = 0; t < n.length; t++) if (n[t].type === re) return n[t];
	                }
	                function te(e, r) {
	                  var n = function (e, r) {
	                    var n = o(e, r);
	                    if (!n) return -1;
	                    for (var t = 0; t < n.length; t++) if (n[t].type === re) return t;
	                    return -1;
	                  }(e, r);
	                  return n > -1 ? "".concat(r, ".").concat(n) : r;
	                }
	                function ie(e, r) {
	                  for (var n = 0; n < e.length; n++) if (e[n].value === r) return n;
	                  return -1;
	                }
	                var oe = {
	                  type: "normalization",
	                  disabled: false,
	                  primaryDimension: 0,
	                  outputExpression: "",
	                  dimensionalScope: 2,
	                  selectionScope: 2
	                };
	                function ae(e) {
	                  return 2 === e ? "{1}" : "";
	                }
	                function se(e, r, n) {
	                  return 1 === e ? "{$<".concat(x.getFieldWithWrapper(r), "={'").concat(n, "'}>}") : "";
	                }
	                function ue(e, r) {
	                  return 0 === e && r > 1 || 2 === e ? "Total" : "";
	                }
	                function le(e, r, n) {
	                  return 0 === e && r > 1 ? "<".concat(x.getDimDefWithWrapper(n), ">") : "";
	                }
	                const ce = {
	                  translationKey: "properties.modifier.normalization",
	                  needDimension: function () {
	                    return true;
	                  },
	                  isApplicable: function (e) {
	                    var r = e.properties,
	                      n = e.layout;
	                    return x.isApplicable({
	                      properties: r,
	                      layout: n,
	                      minDimensions: 1,
	                      maxDimensions: 2
	                    });
	                  },
	                  extractInputExpression: x.extractInputExpression,
	                  generateExpression: function (e) {
	                    var r = e.expression,
	                      n = e.modifier,
	                      t = e.properties,
	                      i = e.layout,
	                      a = e.numDimensions,
	                      s = e.dimensionAndFieldList;
	                    if (!n) return r;
	                    var u = a;
	                    void 0 === u && (u = x.getNumDimensions({
	                      properties: t,
	                      layout: i
	                    }));
	                    var l = o(t, "qHyperCubeDef.qDimensions", []),
	                      c = x.getExpressionWithExcludedComp({
	                        expression: r,
	                        modifier: n,
	                        dimensions: l,
	                        dimensionAndFieldList: s
	                      }),
	                      p = n.selectionScope,
	                      f = n.dimensionalScope;
	                    return function (e, r, n, t, i, o, a) {
	                      var s = ae(r),
	                        u = se(r, n, t),
	                        l = "" === s && "" === u ? "" : s || u,
	                        c = ue(i, o),
	                        p = le(i, o, a),
	                        f = function (e) {
	                          for (var r = [], n = 0; n < e; n++) r[n] = x.getDimDefWithWrapper(n);
	                          return r.join(", ");
	                        }(o);
	                      return "".concat(e, "/ Sum(").concat(l, " ").concat(c).concat(p, " Aggr(").concat(l, " ").concat(e, ", ").concat(f, "))");
	                    }(c, p, n.field, n.value, f, u, n.primaryDimension);
	                  },
	                  initModifier: function (e) {
	                    Object.keys(oe).forEach(function (r) {
	                      void 0 === e[r] && (e[r] = oe[r]);
	                    });
	                  },
	                  updateModifier: function (e, r) {
	                    1 === (r.qDimensions ? r.qDimensions.length : 0) && 0 === e.dimensionalScope && (e.dimensionalScope = 2);
	                  },
	                  enableTotalsFunction: function () {
	                    return true;
	                  },
	                  propertyPanelDef: function (e) {
	                    var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
	                      n = {
	                        type: "items",
	                        items: {
	                          disclaimer: {
	                            component: "text",
	                            translation: r.disclaimer || "properties.modifier.normalization.disclaimer",
	                            show: function (e, r) {
	                              return !x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          },
	                          settings: {
	                            type: "items",
	                            items: {
	                              selectionScope: {
	                                refFn: function (r) {
	                                  return "".concat(te(r, e), ".selectionScope");
	                                },
	                                type: "string",
	                                translation: r.modifierSelectionScope || "properties.modifier.selectionScope",
	                                title: {
	                                  translation: r.modifierSelectionScopeTooltip || "properties.modifier.selectionScope.tooltip"
	                                },
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: 2,
	                                options: function (n) {
	                                  return function (e, r, n) {
	                                    var t = [{
	                                      value: 0,
	                                      translation: r.selectionScopeCurrentSelection || "properties.modifier.selectionScope.currentSelection"
	                                    }, {
	                                      value: 1,
	                                      translation: r.selectionScopeSpecificValue || "properties.modifier.selectionScope.selectAField"
	                                    }, {
	                                      value: 2,
	                                      translation: r.selectionScopeTotal || "properties.modifier.selectionScope.total"
	                                    }];
	                                    return t = function (e, r) {
	                                      if (1 === e) {
	                                        var n = ie(r, 0);
	                                        r.splice(n, 1);
	                                      }
	                                      return r;
	                                    }(ne(e, n).dimensionalScope, t), t;
	                                  }(n, r, e);
	                                }
	                              },
	                              field: {
	                                refFn: function (r) {
	                                  return "".concat(te(r, e), ".field");
	                                },
	                                type: "string",
	                                component: "expression-with-dropdown",
	                                translation: "Common.Field",
	                                defaultValue: "",
	                                dropdownOnly: true,
	                                options: function (e, r, n) {
	                                  return n.app.getFieldList().then(function (e) {
	                                    return e.map(function (e) {
	                                      return {
	                                        label: e.qName,
	                                        value: e.qName
	                                      };
	                                    });
	                                  });
	                                },
	                                show: function (r) {
	                                  return 1 === ne(r, e).selectionScope;
	                                }
	                              },
	                              value: {
	                                refFn: function (r) {
	                                  return "".concat(te(r, e), ".value");
	                                },
	                                type: "string",
	                                ref: "value",
	                                component: "string",
	                                translation: "properties.value",
	                                expression: "optional",
	                                show: function (r) {
	                                  return 1 === ne(r, e).selectionScope;
	                                }
	                              },
	                              dimensionalScope: {
	                                refFn: function (r) {
	                                  return "".concat(te(r, e), ".dimensionalScope");
	                                },
	                                type: "string",
	                                translation: r.modifierDimensionalScope || "properties.modifier.dimensionalScope",
	                                title: {
	                                  translation: r.modifierDimensionalScopeTooltip || "properties.modifier.dimensionalScope.tooltip"
	                                },
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: 2,
	                                supportTooltip: true,
	                                options: function (n, t) {
	                                  return function (e, r, n, t) {
	                                    var i = r.layout.qHyperCube.qDimensionInfo.length,
	                                      o = [{
	                                        value: 0,
	                                        translation: n.dimensionalScopeOneDimension || "properties.modifier.dimensionalScope.respectOneDimension",
	                                        tooltipTranslation: n.dimensionalScopeOneDimensionTooltip || "properties.modifier.dimensionalScope.respectOneDimension.tooltip"
	                                      }, {
	                                        value: 1,
	                                        translation: n.dimensionalScopeAllDimensions || "properties.modifier.dimensionalScope.".concat(2 === i ? "respectAllDimensions" : "respectDimension"),
	                                        tooltipTranslation: n.dimensionalScopeAllDimensionsTooltip || "properties.modifier.dimensionalScope.".concat(2 === i ? "respectAllDimensions" : "respectDimension", ".tooltip")
	                                      }, {
	                                        value: 2,
	                                        translation: n.dimensionalScopeDisregardAllDimensions || "properties.modifier.dimensionalScope.".concat(2 === i ? "disregardAllDimensions" : "disregardDimension"),
	                                        tooltipTranslation: n.dimensionalScopeDisregardAllDimensionsTooltip || "properties.modifier.dimensionalScope.".concat(2 === i ? "disregardAllDimensions" : "disregardDimension", ".tooltip")
	                                      }];
	                                    return o = function (e, r) {
	                                      if (e < 2) {
	                                        var n = ie(r, 0);
	                                        r.splice(n, 1);
	                                      }
	                                      return r;
	                                    }(i, o), o = function (e, r) {
	                                      if (0 === e) {
	                                        var n = ie(r, 1);
	                                        r.splice(n, 1);
	                                      }
	                                      return r;
	                                    }(ne(e, t).selectionScope, o), o;
	                                  }(n, t, r, e);
	                                }
	                              },
	                              primaryDimension: {
	                                refFn: function (r) {
	                                  return "".concat(te(r, e), ".primaryDimension");
	                                },
	                                type: "integer",
	                                translation: r.primaryDimension || "properties.modifier.primaryDimension",
	                                title: {
	                                  translation: r.primaryDimensionTooltip || "properties.modifier.normalization.primaryDimension.tooltip"
	                                },
	                                component: "dropdown",
	                                schemaIgnore: true,
	                                defaultValue: 1,
	                                options: function (e, r) {
	                                  return r.layout.qHyperCube.qDimensionInfo.map(function (e, r) {
	                                    return {
	                                      value: r,
	                                      label: e.qGroupFallbackTitles[0]
	                                    };
	                                  });
	                                },
	                                show: function (r, n) {
	                                  return 0 === (ne(r, e).dimensionalScope || 0) && n.layout.qHyperCube.qDimensionInfo.length > 1;
	                                }
	                              }
	                            },
	                            show: function (e, r) {
	                              return x.isApplicable({
	                                properties: r.properties
	                              });
	                            }
	                          }
	                        },
	                        show: function (r, n, t) {
	                          var i = t.ext.support.modifiers;
	                          if (!Array.isArray(i) || -1 === i.indexOf(re)) return false;
	                          var o = ne(r, e);
	                          return o && !o.disabled;
	                        }
	                      };
	                    return n;
	                  },
	                  getDisregardSelectionComp: ae,
	                  getFieldSelectionComp: se,
	                  getTotalComp: ue,
	                  getSelectedDimComp: le
	                };
	                var pe = "qDef.base",
	                  fe = "qDef.qDef",
	                  me = "qDef.base.qDef",
	                  de = "qLibraryId",
	                  ye = "qDef.base.qLibraryId";
	                const qe = {
	                  getExpression: function (e) {
	                    var r = o(e, me);
	                    return void 0 !== r ? r : o(e, fe);
	                  },
	                  getExpressionRef: function (e) {
	                    return void 0 !== o(e, me) ? me : fe;
	                  },
	                  getLibraryIdRef: function (e) {
	                    return o(e, ye) ? ye : de;
	                  },
	                  getLibraryId: function (e) {
	                    return o(e, ye) || o(e, de);
	                  },
	                  getLabelRef: function (e) {
	                    return o(e, pe) ? "qDef.base.qLabel" : "qDef.qLabel";
	                  },
	                  getLabelExpressionRef: function (e) {
	                    return o(e, pe) ? "qDef.base.qLabelExpression" : "qDef.qLabelExpression";
	                  }
	                };
	                var be = "qDef.qDef",
	                  ve = "qDef.base.qDef",
	                  De = "qLibraryId",
	                  ge = "qDef.base.qLibraryId",
	                  he = "qDef.qLabel",
	                  xe = "qDef.qLabelExpression",
	                  Ae = "qDef.base.qLabel",
	                  Ee = "qDef.base.qLabelExpression",
	                  Ce = "qDef.qAggrFunc",
	                  Ie = "qDef.base.qAggrFunc",
	                  Se = {
	                    initBase: function (e, r) {
	                      (r || Se.isValid(e)) && (n(e, ve, o(e, be)), n(e, ge, o(e, De)), n(e, Ae, o(e, he)), n(e, Ee, o(e, xe)));
	                    },
	                    restoreBase: function (e) {
	                      Se.isValid(e) && (n(e, be, o(e, ve)), n(e, De, o(e, ge)), n(e, he, o(e, Ae)), n(e, xe, o(e, Ee)), o(e, Ce) && o(e, Ie) && n(e, Ce, o(e, Ie)), delete e.qDef.base);
	                    },
	                    isValid: function (e) {
	                      var r = o(e, ve),
	                        n = o(e, ge);
	                      return void 0 !== r || void 0 !== n;
	                    }
	                  };
	                const Me = Se;
	                function Le(e) {
	                  return Le = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) {
	                    return typeof e;
	                  } : function (e) {
	                    return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
	                  }, Le(e);
	                }
	                var Oe = {
	                  accumulation: R,
	                  movingAverage: $,
	                  difference: ee,
	                  normalization: ce,
	                  timeSeriesDecomposition: J
	                };
	                const Fe = {
	                  modifiers: Oe,
	                  apply: Ve,
	                  applyModifiers: Ne,
	                  cleanUpMeasure: we,
	                  destroy: function (e) {
	                    e && Pe[e.id] && Pe[e.id].masterItemSubscriber && (Pe[e.id].masterItemSubscriber && Pe[e.id].masterItemSubscriber.unsubscribe(), delete Pe[e.id]);
	                  },
	                  hasActiveModifiers: He,
	                  getActiveModifier: Te,
	                  initBase: Me.initBase,
	                  isSupportedModifiers: function (e) {
	                    return Array.isArray(e) && e.some(function (e) {
	                      return Oe[e];
	                    });
	                  },
	                  isApplicableSupportedModifiers: function (e) {
	                    var r = e.modifierTypes,
	                      n = e.properties,
	                      t = e.layout;
	                    return Array.isArray(r) && r.some(function (e) {
	                      return Oe[e] && Oe[e].isApplicable({
	                        properties: n,
	                        layout: t
	                      });
	                    });
	                  },
	                  measureBase: qe,
	                  limitedSorting: function (e) {
	                    var r = e.measures,
	                      n = e.properties,
	                      t = e.layout,
	                      i = false,
	                      o = false;
	                    return r.forEach(function (e) {
	                      var r = _e(e);
	                      ze({
	                        modifiers: r,
	                        properties: n,
	                        layout: t
	                      }) && (i = true, o = o || Qe({
	                        modifiers: r,
	                        properties: n,
	                        layout: t
	                      }));
	                    }), i && !o;
	                  },
	                  ifEnableTotalsFunction: je
	                };
	                var Pe = {};
	                function Ve() {
	                  var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
	                    n = e.model,
	                    t = e.properties,
	                    i = e.isSnapshot,
	                    a = void 0 !== i && i,
	                    s = e.masterItem,
	                    u = false;
	                  Pe[n.id] = Pe[n.id] || {
	                    isFirstTime: true
	                  };
	                  var l = Pe[n.id].isFirstTime;
	                  if (Pe[n.id].isFirstTime = false, t && "object" === Le(t)) return Ne({
	                    model: n,
	                    properties: t
	                  });
	                  var c = n ? n.layout : void 0,
	                    p = o(c, "qSelectionInfo.qInSelections");
	                  if (a || p) return Promise.resolve(u);
	                  var f = o(c, "qHyperCube.qMeasureInfo"),
	                    m = Pe[n.id].lastReloadTime;
	                  if (Pe[n.id].lastReloadTime = o(n, "app.layout.qLastReloadTime"), He({
	                    measures: f,
	                    layout: c
	                  })) {
	                    var d = function (e) {
	                      var r = e.measures,
	                        n = e.layout,
	                        t = e.lastReloadTime;
	                      return o(e.model, "app.layout.qLastReloadTime") !== t && function (e) {
	                        var r = e.measures,
	                          n = e.properties,
	                          t = e.layout;
	                        return !!Array.isArray(r) && r.some(function (e) {
	                          return Ge({
	                            measure: e,
	                            properties: n,
	                            layout: t
	                          });
	                        });
	                      }({
	                        measures: r,
	                        layout: n
	                      });
	                    }({
	                      measures: f,
	                      layout: c,
	                      model: n,
	                      lastReloadTime: m
	                    });
	                    return d || function (e) {
	                      var r = e.measures,
	                        n = e.layout,
	                        t = e.masterItem,
	                        i = e.isFirstTime;
	                      return !!Array.isArray(r) && (i || t || r.some(function (e) {
	                        return function (e) {
	                          var r = e.measure,
	                            n = e.layout;
	                          return ze({
	                            modifiers: _e(r),
	                            layout: n
	                          }) ? !r.base : !!r.base;
	                        }({
	                          measure: e,
	                          layout: n
	                        });
	                      }));
	                    }({
	                      measures: f,
	                      layout: c,
	                      masterItem: s,
	                      isFirstTime: l
	                    }) ? n.getEffectiveProperties().then(function (e) {
	                      var t = r()(true, {}, e);
	                      ke(t);
	                      var i = Ze(t);
	                      return Ye({
	                        model: n
	                      }).then(function (r) {
	                        return Je({
	                          libraryIds: i,
	                          model: n
	                        }).then(function (i) {
	                          return d && function (e) {
	                            var r = e.properties;
	                            Re(r).forEach(function (e) {
	                              return function (e) {
	                                var r = e.measure;
	                                if (Ge({
	                                  measure: r,
	                                  properties: e.properties
	                                })) {
	                                  var n = 0,
	                                    t = r.qDef.modifiers;
	                                  Array.isArray(t) && t.forEach(function (e) {
	                                    if ("object" === Le(e) && !e.disabled) {
	                                      if (n++, "object" !== Le(Oe[e.type])) throw new Error('Modifier "'.concat(e.type, '" is not available'));
	                                      if (n > 1) throw new Error("More than 1 modifier on a measure! (not yet supported)");
	                                      var t = Oe[e.type].extractInputExpression({
	                                        outputExpression: r.qDef.qDef,
	                                        modifier: e
	                                      });
	                                      void 0 !== t && $e(r) && x.simplifyExpression(r.qDef.base.qDef) !== x.simplifyExpression(t) && (r.qDef.base.qDef = t);
	                                    }
	                                  });
	                                }
	                              }({
	                                measure: e,
	                                properties: r
	                              });
	                            });
	                          }({
	                            properties: t
	                          }), Ne({
	                            model: n,
	                            oldProperties: e,
	                            properties: t,
	                            runUpdateIfChange: true,
	                            masterItem: s,
	                            libraryItemsProps: i,
	                            dimensionAndFieldList: r
	                          });
	                        });
	                      });
	                    }) : Promise.resolve(u);
	                  }
	                  return function (e) {
	                    return !!Array.isArray(e) && e.some(function (e) {
	                      return "object" === Le(e.base);
	                    });
	                  }(f) ? n.getEffectiveProperties().then(function (e) {
	                    return function (e) {
	                      var n = e.model,
	                        t = e.properties,
	                        i = Ze(t);
	                      return er({
	                        model: n,
	                        libraryIds: i
	                      }).then(function () {
	                        var e = r()(true, {}, t);
	                        return Re(t).forEach(function (e) {
	                          return we(e);
	                        }), Xe({
	                          oldProperties: e,
	                          newProperties: t,
	                          model: n
	                        });
	                      });
	                    }({
	                      model: n,
	                      properties: e
	                    });
	                  }) : Promise.resolve(u);
	                }
	                function Ne(e) {
	                  var n = e.model,
	                    t = e.oldProperties,
	                    i = e.properties,
	                    a = e.measures,
	                    s = e.runUpdateIfChange,
	                    u = void 0 !== s && s,
	                    l = e.masterItem,
	                    c = e.libraryItemsProps,
	                    p = e.dimensionAndFieldList;
	                  void 0 === t && (t = u ? r()(true, {}, i) : i), ke(i);
	                  var f = Ze(i);
	                  return er({
	                    model: n,
	                    libraryIds: f,
	                    masterItem: l
	                  }).then(function () {
	                    return function (e) {
	                      var n = e.measures,
	                        t = e.properties,
	                        i = e.model,
	                        a = e.libraryItemsProps,
	                        s = e.dimensionAndFieldList;
	                      if (n || (n = Re(t)), !n.length) return Promise.resolve();
	                      if (!He({
	                        measures: n,
	                        properties: t
	                      })) return n.forEach(function (e) {
	                        return we(e);
	                      }), Promise.resolve();
	                      var u = a ? void 0 : Ze(t);
	                      return Ye({
	                        model: i,
	                        dimensionAndFieldList: s
	                      }).then(function (e) {
	                        return Je({
	                          libraryIds: u,
	                          model: i,
	                          libraryItemsProps: a
	                        }).then(function (i) {
	                          n.forEach(function (n) {
	                            ze({
	                              modifiers: n.qDef.modifiers,
	                              properties: t
	                            }) ? (function (e) {
	                              var n = e.measure,
	                                t = e.properties,
	                                i = e.libraryItemsProps,
	                                a = e.dimensionAndFieldList,
	                                s = 0;
	                              Me.isValid(n) || Me.initBase(n, true);
	                              var u = n.qDef,
	                                l = u.modifiers,
	                                c = u.base;
	                              Array.isArray(l) && l.forEach(function (e) {
	                                if ("object" === Le(e) && !e.disabled) {
	                                  if (s++, "object" !== Le(Oe[e.type])) throw new Error('Modifier "'.concat(e.type, '" is not available'));
	                                  if (s > 1) throw new Error("More than 1 modifier on a measure! (not yet supported)");
	                                  Oe[e.type].initModifier(e, n);
	                                  var u = n.qLibraryId || c && c.qLibraryId;
	                                  u ? function (e) {
	                                    var n = e.measure,
	                                      t = e.modifier,
	                                      i = e.properties,
	                                      o = e.dimensionAndFieldList,
	                                      a = e.libraryItemsProps[e.libraryId],
	                                      s = a.qMeasure.qDef,
	                                      u = "" === s ? s : Oe[t.type].generateExpression({
	                                        expression: s,
	                                        modifier: t,
	                                        properties: i,
	                                        dimensionAndFieldList: o
	                                      });
	                                    t.outputExpression = u, n.qDef.qDef = t.outputExpression, (n.qDef.qLabel || a.qMeasure.qLabel) && (n.qDef.qLabel = a.qMeasure.qLabel), (n.qDef.qLabelExpression || a.qMeasure.qLabelExpression) && (n.qDef.qLabelExpression = a.qMeasure.qLabelExpression), n.qDef.quarantine && n.qDef.quarantine.qNumFormat && a.qMeasure.qNumFormat && (n.qDef.qNumFormat = a.qMeasure.qNumFormat, n.qDef.isCustomFormatted = a.qMeasure.isCustomFormatted), delete n.qLibraryId, n.qDef.coloring = a.qMeasure.coloring, t.base = r()(true, {}, n.qDef.base);
	                                  }({
	                                    measure: n,
	                                    modifier: e,
	                                    libraryId: u,
	                                    properties: t,
	                                    libraryItemsProps: i,
	                                    dimensionAndFieldList: a
	                                  }) : function (e) {
	                                    var n = e.measure,
	                                      t = e.modifier,
	                                      i = e.properties,
	                                      o = e.dimensionAndFieldList;
	                                    "function" == typeof Oe[t.type].updateModifier && Oe[t.type].updateModifier(t, i.qHyperCubeDef);
	                                    var a = qe.getExpression(n),
	                                      s = "" === a ? a : Oe[t.type].generateExpression({
	                                        expression: a,
	                                        modifier: t,
	                                        properties: i,
	                                        dimensionAndFieldList: o
	                                      });
	                                    t.outputExpression = s, n.qDef.qDef = t.outputExpression, n.qDef.base.qLabelExpression ? n.qDef.qLabelExpression = n.qDef.base.qLabelExpression : n.qDef.qLabel = n.qDef.base.qLabel || a, t.base = r()(true, {}, n.qDef.base);
	                                  }({
	                                    measure: n,
	                                    modifier: e,
	                                    properties: t,
	                                    dimensionAndFieldList: a
	                                  }), function (e) {
	                                    var r = o(e, "qDef.qAggrFunc");
	                                    "Expr" !== r || je(e) ? "None" !== r ? delete e.qDef.base.qAggrFunc : "None" === r && je(e) && "Expr" === e.qDef.base.qAggrFunc && (e.qDef.qAggrFunc = "Expr", delete e.qDef.base.qAggrFunc) : (e.qDef.qAggrFunc = "None", e.qDef.base.qAggrFunc = "Expr");
	                                  }(n);
	                                }
	                              });
	                            }({
	                              measure: n,
	                              properties: t,
	                              libraryItemsProps: i,
	                              dimensionAndFieldList: e
	                            }), We(n)) : we(n);
	                          });
	                        });
	                      });
	                    }({
	                      measures: a,
	                      properties: i,
	                      model: n,
	                      libraryItemsProps: c,
	                      dimensionAndFieldList: p
	                    }).then(function () {
	                      return u ? Xe({
	                        oldProperties: t,
	                        newProperties: i,
	                        model: n
	                      }) : Promise.resolve(false);
	                    });
	                  });
	                }
	                function we(e) {
	                  !function (e) {
	                    var r = _e(e);
	                    return Array.isArray(r) && r.some(function (e) {
	                      return "object" === Le(e) && !e.disabled && !Oe[e.type];
	                    });
	                  }(e) ? Me.restoreBase(e) : delete e.qDef.base, e.qDef.coloring && delete e.qDef.coloring, We(e);
	                }
	                function He(e) {
	                  var r = e.measures,
	                    n = e.properties,
	                    t = e.layout;
	                  return !!Array.isArray(r) && r.some(function (e) {
	                    return ze({
	                      modifiers: _e(e),
	                      properties: n,
	                      layout: t
	                    });
	                  });
	                }
	                function Te(e) {
	                  var r = _e(e);
	                  if (Array.isArray(r)) for (var n = 0; n < r.length; n++) {
	                    var t = r[n];
	                    if (Oe[t.type] && !t.disabled) return t;
	                  }
	                }
	                function je(e) {
	                  var r = Te(e);
	                  return !r || Oe[r.type].enableTotalsFunction(e);
	                }
	                function Re(e) {
	                  return o(e, "qHyperCubeDef.qMeasures", []).concat(o(e, "qHyperCubeDef.qLayoutExclude.qHyperCubeDef.qMeasures", []));
	                }
	                function _e(e) {
	                  return e.modifiers || e.qDef && e.qDef.modifiers;
	                }
	                function Be(e) {
	                  return o(e, "outputExpression.qValueExpression.qExpr") || o(e, "outputExpression");
	                }
	                function ke(e) {
	                  Re(e).forEach(function (e) {
	                    return function (e) {
	                      var n = Te(e);
	                      n && (void 0 !== n.outputExpression && Be(n) !== e.qDef.qDef ? delete e.qDef.base : !Me.isValid(e) && n.base && (e.qDef.base = r()(true, {}, n.base)));
	                    }(e);
	                  });
	                }
	                function We(e) {
	                  var r = _e(e);
	                  Array.isArray(r) && r.forEach(function (r) {
	                    "object" === Le(r) && (r.disabled || !Oe[r.type] && Be(r) !== e.qDef.qDef) && (r.disabled = true, delete r.base);
	                  });
	                }
	                function $e(e) {
	                  return e.base || e.qDef && e.qDef.base;
	                }
	                function Ue(e) {
	                  var r = $e(e);
	                  return e.qLibraryId || r && r.qLibraryId;
	                }
	                function Ge(e) {
	                  var r = e.measure,
	                    n = e.properties,
	                    t = e.layout;
	                  return !Ue(r) && ze({
	                    modifiers: _e(r),
	                    properties: n,
	                    layout: t
	                  });
	                }
	                function ze(e) {
	                  var r = e.modifiers,
	                    n = e.properties,
	                    t = e.layout,
	                    i = {};
	                  return Array.isArray(r) && r.some(function (e) {
	                    return !("object" !== Le(e) || e.disabled || !Oe[e.type]) && (void 0 === i[e.type] && (i[e.type] = Oe[e.type].isApplicable({
	                      properties: n,
	                      layout: t
	                    })), i[e.type]);
	                  });
	                }
	                function Ye(e) {
	                  var r = e.model,
	                    n = e.dimensionAndFieldList;
	                  if (n) return Promise.resolve(n);
	                  var t = [],
	                    i = {},
	                    o = r.app.getDimensionList().then(function (e) {
	                      i.dimensionList = e;
	                    });
	                  t.push(o);
	                  var a = r.app.getFieldList().then(function (e) {
	                    i.fieldList = e;
	                  });
	                  return t.push(a), Promise.all(t).then(function () {
	                    return i;
	                  });
	                }
	                function Je(e) {
	                  var r = e.libraryIds,
	                    n = e.model,
	                    t = e.libraryItemsProps;
	                  if (t) return Promise.resolve(t);
	                  var i = r.measureLibraryIds,
	                    o = r.dimensionLibraryIds,
	                    a = {},
	                    s = [];
	                  return i.forEach(function (e) {
	                    var r = n.app.getMeasure(e).then(function (r) {
	                      return r.getProperties().then(function (r) {
	                        a[e] = r;
	                      });
	                    });
	                    s.push(r);
	                  }), o.forEach(function (e) {
	                    var r = n.app.getDimension(e).then(function (r) {
	                      return r.getProperties().then(function (r) {
	                        a[e] = r;
	                      });
	                    });
	                    s.push(r);
	                  }), Promise.all(s).then(function () {
	                    return a;
	                  });
	                }
	                function Ke(e, r) {
	                  if ("" !== r || -1 === ["qFmt", "qDec", "qThou"].indexOf(e)) return r;
	                }
	                function Xe(e) {
	                  var r = e.oldProperties,
	                    n = e.newProperties,
	                    t = e.model,
	                    i = JSON.stringify(o(r, "qHyperCubeDef.qMeasures"), Ke) !== JSON.stringify(o(n, "qHyperCubeDef.qMeasures"), Ke) || JSON.stringify(o(r, "qHyperCubeDef.qLayoutExclude.qHyperCubeDef.qMeasures"), Ke) !== JSON.stringify(o(n, "qHyperCubeDef.qLayoutExclude.qHyperCubeDef.qMeasures"), Ke);
	                  return i ? function (e) {
	                    var r = e.model,
	                      n = e.oldProperties,
	                      t = e.newProperties,
	                      i = r.layout;
	                    return i && !i.qHasSoftPatches && !i.qExtendsId && o(i, "qMeta.privileges", []).indexOf("update") > -1 ? r.setProperties(t) : N(r, n, t);
	                  }({
	                    model: t,
	                    oldProperties: r,
	                    newProperties: n
	                  }).then(function () {
	                    return i;
	                  }) : Promise.resolve(i);
	                }
	                function Qe(e) {
	                  var r = e.modifiers,
	                    n = e.properties,
	                    t = e.layout;
	                  return Array.isArray(r) && r.some(function (e) {
	                    return "object" === Le(e) && !e.disabled && Oe[e.type] && Oe[e.type].needDimension({
	                      modifier: e,
	                      properties: n,
	                      layout: t
	                    });
	                  });
	                }
	                function Ze(e) {
	                  var r = Re(e),
	                    n = [],
	                    t = [],
	                    i = false;
	                  return r.forEach(function (r) {
	                    var t = _e(r);
	                    if (ze({
	                      modifiers: t,
	                      properties: e
	                    })) {
	                      var o = Ue(r);
	                      o && n.push(o), i = i || Qe({
	                        modifiers: t,
	                        properties: e
	                      });
	                    }
	                  }), o(e, "qHyperCubeDef.qDimensions", []).forEach(function (e) {
	                    var r = e.qLibraryId;
	                    r && t.push(r);
	                  }), {
	                    measureLibraryIds: n,
	                    dimensionLibraryIds: t
	                  };
	                }
	                function er(e) {
	                  var r = e.model,
	                    n = e.libraryIds;
	                  return !e.masterItem && n && (n.measureLibraryIds.length || n.dimensionLibraryIds.length) ? (Pe[r.id].masterItemSubscriber = Pe[r.id].masterItemSubscriber || function (e) {
	                    var r = e.model,
	                      n = e.callback,
	                      t = {},
	                      i = {},
	                      a = {},
	                      s = {
	                        dimension: ["qDim.qFieldDefs"],
	                        measure: ["qMeasure.qDef", "qMeasure.qLabel", "qMeasure.qLabelExpression", "qMeasure.coloring", "qMeasure.qNumFormat", "qMeasure.isCustomFormatted"]
	                      };
	                    function u(e) {
	                      var r = {},
	                        n = o(e, "qInfo.qType");
	                      return n && s[n] && s[n].forEach(function (n) {
	                        r[n] = o(e, n);
	                      }), JSON.stringify(r);
	                    }
	                    function l(e) {
	                      var r = e.qInfo.qId;
	                      if (t[r]) {
	                        var i = u(e);
	                        t[r].properties !== i && (t[r].properties = i, "function" == typeof n && t[r].enabled && n(e)), t[r].enabled = true;
	                      }
	                    }
	                    function c(e, n) {
	                      return r.app[n](e).then(function (r) {
	                        t[e] = {
	                          listener: r.layoutSubscribe(l),
	                          enabled: false,
	                          properties: u(r.layout)
	                        };
	                      });
	                    }
	                    return {
	                      subscribe: function (e) {
	                        var n = e.measureLibraryIds,
	                          o = e.dimensionLibraryIds,
	                          s = [];
	                        return function (e) {
	                          var r = e.dimensionLibraryIds;
	                          i = {}, e.measureLibraryIds.forEach(function (e) {
	                            i[e] = true;
	                          }), a = {}, r.forEach(function (e) {
	                            a[e] = true;
	                          });
	                        }({
	                          measureLibraryIds: n,
	                          dimensionLibraryIds: o
	                        }), Object.keys(t).forEach(function (e) {
	                          i[e] || a[e] || (t[e].listener.dispose(), delete t[e]);
	                        }), r.app && (Object.keys(i).forEach(function (e) {
	                          i[e] && !t[e] && s.push(c(e, "getMeasure"));
	                        }), Object.keys(a).forEach(function (e) {
	                          a[e] && !t[e] && s.push(c(e, "getDimension"));
	                        })), Promise.all(s);
	                      },
	                      unsubscribe: function () {
	                        Object.keys(t).forEach(function (e) {
	                          t[e].listener.dispose();
	                        }), t = {};
	                      }
	                    };
	                  }({
	                    model: r,
	                    callback: function (e) {
	                      return Ve({
	                        model: r,
	                        masterItem: e
	                      }).then(function () {
	                        return r.app.clearUndoBuffer();
	                      });
	                    }
	                  }), Pe[r.id].masterItemSubscriber.subscribe(n)) : Promise.resolve();
	                }
	              })(), r.default = i.default, Object.defineProperty(r, "__esModule", {
	                value: true
	              });
	            })();
	          }
	        },
	        r = {};
	      function n(t) {
	        var i = r[t];
	        if (void 0 !== i) return i.exports;
	        var o = r[t] = {
	          exports: {}
	        };
	        return e[t](o, o.exports, n), o.exports;
	      }
	      n.n = e => {
	        var r = e && e.__esModule ? () => e.default : () => e;
	        return n.d(r, {
	          a: r
	        }), r;
	      }, n.d = (e, r) => {
	        for (var t in r) n.o(r, t) && !n.o(e, t) && Object.defineProperty(e, t, {
	          enumerable: true,
	          get: r[t]
	        });
	      }, n.o = (e, r) => Object.prototype.hasOwnProperty.call(e, r);
	      var t = {};
	      return (() => {

	        function e(r) {
	          var n,
	            t = r;
	          return t > 9 ? (n = 65 + t - 10) > 90 && (n += 6) : t = "".concat(t).charCodeAt(0), [48, 111, 79, 105, 73, 108].indexOf(n) > -1 ? e(t + 1) : String.fromCharCode(n);
	        }
	        function r(n) {
	          var t = e(n % 62),
	            i = Math.floor(n / 62);
	          return i > 0 ? r(i) + t : t;
	        }
	        function i(e) {
	          return i = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) {
	            return typeof e;
	          } : function (e) {
	            return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
	          }, i(e);
	        }
	        n.d(t, {
	          default: () => ke
	        });
	        const o = {
	          getValue: function (e, r, n) {
	            if (null == e || null == r) return n;
	            for (var t = r.split("."), i = e, o = 0; o < t.length; ++o) {
	              var a = t[o];
	              if ("" !== a) {
	                if (void 0 === i[a] || null === i[a]) return n;
	                i = i[a];
	              }
	            }
	            return i;
	          },
	          setValue: function (e, r, n) {
	            if (null != e && null != r) {
	              for (var t = r.split("."), i = t[t.length - 1], o = e, a = 0; a < t.length - 1; ++a) {
	                var s = t[a];
	                void 0 !== o[s] && null !== o[s] || (o[s] = Number.isNaN(+t[a + 1]) ? {} : []), o = o[s];
	              }
	              void 0 !== n ? o[i] = n : delete o[i];
	            }
	          },
	          isEmpty: function (e) {
	            return 0 === Object.keys(e).length && e.constructor === Object;
	          },
	          isAtomicValue: function (e) {
	            return /boolean|number|string/.test(i(e));
	          },
	          generateId: function () {
	            return r(Math.round(99e11 * Math.random() + 1e11)).replace(/\W/g, "");
	          }
	        };
	        function a(e) {
	          return function (e) {
	            if (Array.isArray(e)) return s(e);
	          }(e) || function (e) {
	            if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e);
	          }(e) || function (e, r) {
	            if (e) {
	              if ("string" == typeof e) return s(e, r);
	              var n = Object.prototype.toString.call(e).slice(8, -1);
	              return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? s(e, r) : void 0;
	            }
	          }(e) || function () {
	            throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	          }();
	        }
	        function s(e, r) {
	          (null == r || r > e.length) && (r = e.length);
	          for (var n = 0, t = new Array(r); n < r; n++) t[n] = e[n];
	          return t;
	        }
	        function u(e) {
	          return function (e) {
	            if (Array.isArray(e)) return l(e);
	          }(e) || function (e) {
	            if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e);
	          }(e) || function (e, r) {
	            if (e) {
	              if ("string" == typeof e) return l(e, r);
	              var n = Object.prototype.toString.call(e).slice(8, -1);
	              return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? l(e, r) : void 0;
	            }
	          }(e) || function () {
	            throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	          }();
	        }
	        function l(e, r) {
	          (null == r || r > e.length) && (r = e.length);
	          for (var n = 0, t = new Array(r); n < r; n++) t[n] = e[n];
	          return t;
	        }
	        function c(e, r, n) {
	          if (e) {
	            for (var t = 0; t < e.length; t++) if (e[t][r] === n) return t;
	            return -1;
	          }
	          return -1;
	        }
	        const p = {
	          isOrderedSubset: function (e, r) {
	            if (!(e && r && e.length && r.length)) return false;
	            var n = e.indexOf(r[0]);
	            if (-1 !== n) {
	              for (var t = 0; t < r.length; t++) {
	                var i = e.indexOf(r[t]);
	                if (n > i) return false;
	                n = i;
	              }
	              return true;
	            }
	            return false;
	          },
	          indexAdded: function (e, r) {
	            var n;
	            for (n = 0; n < e.length; ++n) e[n] >= 0 && e[n] >= r && ++e[n];
	            e.push(r);
	          },
	          indexRemoved: function (e, r) {
	            var n,
	              t = 0;
	            for (n = 0; n < e.length; ++n) e[n] > r ? --e[n] : e[n] === r && (t = n);
	            return e.splice(t, 1), t;
	          },
	          findItemByPropertyValue: function (e, r, n) {
	            if (e) {
	              for (var t = 0; t < e.length; t++) if (e[t][r] === n) return e[t];
	              return null;
	            }
	            return null;
	          },
	          findIndexByPropertyValue: c
	        };
	        var f = n(8),
	          m = n.n(f);
	        const d = function (e) {
	            var r,
	              n = e.exportFormat,
	              t = e.qHyperCubeDef,
	              i = n.data[0];
	            (r = i.dimensions).push.apply(r, a(t.qDimensions));
	            var s,
	              u = o.getValue(t, "qLayoutExclude.qHyperCubeDef.qDimensions");
	            u && (s = i.excludedDimensions).push.apply(s, a(u));
	          },
	          y = function (e) {
	            var r,
	              n = e.exportFormat,
	              t = e.qHyperCubeDef,
	              i = n.data[0];
	            (r = i.measures).push.apply(r, u(t.qMeasures));
	            var a,
	              s = o.getValue(t, "qLayoutExclude.qHyperCubeDef.qMeasures");
	            s && (a = i.excludedMeasures).push.apply(a, u(s));
	          },
	          q = function (e) {
	            var r = e.exportFormat,
	              n = e.qHyperCubeDef,
	              t = r.data[0];
	            n.qInterColumnSortOrder || (n.qInterColumnSortOrder = []), t.interColumnSortOrder = n.qInterColumnSortOrder.concat();
	            var i = o.getValue(n, "qLayoutExclude.qHyperCubeDef.qInterColumnSortOrder");
	            i && p.isOrderedSubset(i, t.interColumnSortOrder) && (t.interColumnSortOrder = i.concat());
	          },
	          b = function (e) {
	            var r = e.exportFormat,
	              n = e.properties;
	            Object.keys(n).forEach(function (e) {
	              r.properties[e] = n[e];
	            });
	          },
	          v = function (e) {
	            var r = e.exportFormat,
	              n = e.properties;
	            n.qLayoutExclude || (n.qLayoutExclude = {}), n.qLayoutExclude.disabled && (Object.keys(n.qLayoutExclude.disabled).forEach(function (e) {
	              r.properties.hasOwnProperty(e) || (r.properties[e] = n.qLayoutExclude.disabled[e]);
	            }), delete n.qLayoutExclude.disabled), n.qLayoutExclude.changed && (function (e) {
	              Object.keys(e.qLayoutExclude.changed).forEach(function (r) {
	                e.qLayoutExclude.changed[r].to === o.getValue(e, r) && o.setValue(e, r, e.qLayoutExclude.changed[r].from);
	              });
	            }(n), delete n.qLayoutExclude.changed), n.qLayoutExclude.quarantine && !o.isEmpty(n.qLayoutExclude.quarantine) || delete n.qLayoutExclude;
	          },
	          D = function (e) {
	            e.forEach(function (e) {
	              m().cleanUpMeasure(e), e.qDef.modifiers && (e.store = {
	                modifiers: e.qDef.modifiers
	              }, delete e.qDef.modifiers);
	            });
	          };
	        function g(e, r, n) {
	          var t,
	            i,
	            a = arguments.length > 3 && void 0 !== arguments[3] && arguments[3],
	            s = o.getValue(e, r);
	          if (!o.isAtomicValue(s)) try {
	            if ((i = (i = (t = JSON.stringify(s)).match(/:\{/g)) ? i.length : 0) > 2 && !a) return;
	            s = JSON.parse(t);
	          } catch (e) {
	            return;
	          }
	          o.getValue(e, "qLayoutExclude.quarantine") || o.setValue(e, "qLayoutExclude.quarantine", {});
	          var u = o.getValue(e, "qLayoutExclude.quarantine");
	          u[n] || (u[n] = {}), u[n][r] = s;
	        }
	        var h = n(909),
	          x = n.n(h);
	        function A(e, r) {
	          var n = x()(true, {}, r, e);
	          return o.getValue(n, "qOtherTotalSpec.qOtherCounted") || o.setValue(n, "qOtherTotalSpec.qOtherCounted", {
	            qv: "10"
	          }), o.getValue(n, "qOtherTotalSpec.qOtherLimit") || o.setValue(n, "qOtherTotalSpec.qOtherLimit", {
	            qv: "0"
	          }), n.hasOwnProperty("othersLabel") || (n.othersLabel = "Others"), n;
	        }
	        function E(e, r) {
	          return x()(true, {}, r, e);
	        }
	        function C(e, r, n) {
	          return "function" == typeof e ? e(r) : Number.isNaN(+e) ? n : e;
	        }
	        var I = Math.pow(2, 53) - 1;
	        function S(e, r) {
	          (null == r || r > e.length) && (r = e.length);
	          for (var n = 0, t = new Array(r); n < r; n++) t[n] = e[n];
	          return t;
	        }
	        function M(e, r) {
	          (null == r || r > e.length) && (r = e.length);
	          for (var n = 0, t = new Array(r); n < r; n++) t[n] = e[n];
	          return t;
	        }
	        const L = function (e, r, n) {
	            var t = "masterobject" === o.getValue(r, "properties.qInfo.qType") ? "masterobject" : o.getValue(n, "qInfo.qType");
	            o.setValue(e, "qInfo.qType", t), e.visualization = n.visualization;
	          },
	          O = function (e, r, n) {
	            r.hasOwnProperty(e) && (n[e] = r[e]);
	          },
	          F = function (e, r, n, t) {
	            r.hasOwnProperty(e) ? n[e] = r[e] : n[e] = t;
	          },
	          P = function () {
	            return {
	              qDef: {
	                autoSort: true,
	                cId: "",
	                othersLabel: "Others"
	              },
	              qLibraryId: "",
	              qNullSuppression: false,
	              qOtherLabel: "Others",
	              qOtherTotalSpec: {
	                qOtherLimitMode: "OTHER_GE_LIMIT",
	                qOtherMode: "OTHER_OFF",
	                qOtherSortMode: "OTHER_SORT_DESCENDING",
	                qSuppressOther: false
	              }
	            };
	          },
	          V = function () {
	            return {
	              qDef: {
	                autoSort: true,
	                cId: "",
	                numFormatFromTemplate: true
	              },
	              qLibraryId: "",
	              qTrendLines: []
	            };
	          },
	          N = function (e) {
	            var r,
	              n = e.exportFormat,
	              t = e.maxDimensions,
	              i = e.minDimensions,
	              o = e.newHyperCubeDef,
	              a = e.defaultDimension,
	              s = n.data[0];
	            for (r = 0; r < s.dimensions.length; ++r) {
	              var u = A(s.dimensions[r], a);
	              o.qDimensions.length < t ? o.qDimensions.push(u) : o.qLayoutExclude.qHyperCubeDef.qDimensions.push(u);
	            }
	            for (r = 0; r < s.excludedDimensions.length; ++r) {
	              var l = A(s.excludedDimensions[r], a);
	              o.qDimensions.length < i ? o.qDimensions.push(l) : o.qLayoutExclude.qHyperCubeDef.qDimensions.push(l);
	            }
	          },
	          w = function (e) {
	            var r,
	              n = e.exportFormat,
	              t = e.maxMeasures,
	              i = e.minMeasures,
	              o = e.newHyperCubeDef,
	              a = e.defaultMeasure,
	              s = n.data[0];
	            for (r = 0; r < s.measures.length; ++r) {
	              var u = E(s.measures[r], a);
	              o.qMeasures.length < t ? o.qMeasures.push(u) : o.qLayoutExclude.qHyperCubeDef.qMeasures.push(u);
	            }
	            for (r = 0; r < s.excludedMeasures.length; ++r) {
	              var l = E(s.excludedMeasures[r], a);
	              o.qMeasures.length < i ? o.qMeasures.push(l) : o.qLayoutExclude.qHyperCubeDef.qMeasures.push(l);
	            }
	          },
	          H = function (e) {
	            var r = e.exportFormat,
	              n = e.dataDefinition,
	              t = void 0 === n ? {} : n,
	              i = r.data[0],
	              o = t.dimensions || {
	                max: 0
	              },
	              a = t.measures || {
	                max: 0
	              },
	              s = C(a.max, i.dimensions.length, I),
	              u = C(a.min, i.dimensions.length, 0);
	            return {
	              maxDimensions: C(o.max, s, I),
	              minDimensions: C(o.min, u, 0),
	              maxMeasures: s,
	              minMeasures: u
	            };
	          },
	          T = function (e) {
	            var r = e.exportFormat,
	              n = e.newHyperCubeDef,
	              t = r.data[0],
	              i = n.qDimensions.length + n.qMeasures.length;
	            n.qInterColumnSortOrder = t.interColumnSortOrder.concat();
	            var o = n.qInterColumnSortOrder.length;
	            if (o !== i) for (n.qLayoutExclude && (n.qLayoutExclude.qHyperCubeDef.qInterColumnSortOrder = t.interColumnSortOrder.concat()); o !== i;) o < i ? (p.indexAdded(n.qInterColumnSortOrder, o), ++o) : (--o, p.indexRemoved(n.qInterColumnSortOrder, o));
	          },
	          j = function (e) {
	            var r = e.exportFormat,
	              n = e.initialProperties,
	              t = e.hypercubePath,
	              i = {
	                qLayoutExclude: {
	                  disabled: {},
	                  quarantine: {}
	                }
	              };
	            return Object.keys(r.properties).forEach(function (e) {
	              "qLayoutExclude" === e ? r.properties[e].quarantine && (i.qLayoutExclude.quarantine = x()(true, {}, r.properties[e].quarantine)) : "qHyperCubeDef" === e && t ? o.setValue(i, "".concat(t, ".qHyperCubeDef"), r.properties.qHyperCubeDef) : n.hasOwnProperty(e) || -1 !== ["qMetaDef", "descriptionExpression", "labelExpression"].indexOf(e) || function (e, r) {
	                return "components" === r && Array.isArray(e[r]) && e[r].some(function (e) {
	                  return "general" === e.key;
	                });
	              }(r.properties, e) ? i[e] = r.properties[e] : i.qLayoutExclude.disabled[e] = r.properties[e];
	            }), null === (i = x()(true, {}, n, i)).components && (i.components = []), i;
	          },
	          R = function (e) {
	            var r = e.exportFormat,
	              n = e.maxDimensions,
	              t = e.minDimensions,
	              i = e.maxMeasures,
	              o = e.minMeasures,
	              a = r.data[0];
	            return a.dimensions.length > n && n > 0 || a.measures.length > i && i > 0 || a.excludedDimensions.length > 0 && a.dimensions.length + a.excludedDimensions.length > t || a.excludedMeasures.length > 0 && a.measures.length + a.excludedMeasures.length > o || !i && a.measures.length > 0 || !n && a.dimensions.length > 0;
	          },
	          _ = function (e) {
	            var r = e.exportFormat,
	              n = e.maxDimensions,
	              t = e.minDimensions,
	              i = e.maxMeasures,
	              o = e.minMeasures,
	              a = e.newHyperCubeDef,
	              s = r.data[0];
	            a.qLayoutExclude || (a.qLayoutExclude = {}), a.qLayoutExclude.qHyperCubeDef || (a.qLayoutExclude.qHyperCubeDef = {}), (s.dimensions.length > n && n > 0 || s.excludedDimensions && s.excludedDimensions.length && s.dimensions.length + s.excludedDimensions.length > t) && (a.qLayoutExclude.qHyperCubeDef.qDimensions || (a.qLayoutExclude.qHyperCubeDef.qDimensions = [])), (s.measures.length > i && i > 0 || s.excludedMeasures && s.excludedMeasures.length && s.measures.length + s.excludedMeasures.length > o) && (a.qLayoutExclude.qHyperCubeDef.qMeasures || (a.qLayoutExclude.qHyperCubeDef.qMeasures = [])), !i && s.measures.length && (a.qLayoutExclude.qHyperCubeDef.qMeasures || (a.qLayoutExclude.qHyperCubeDef.qMeasures = [])), !n && s.dimensions.length && (a.qLayoutExclude.qHyperCubeDef.qDimensions || (a.qLayoutExclude.qHyperCubeDef.qDimensions = []));
	          },
	          B = function (e) {
	            var r,
	              n = e.newProperties,
	              t = e.dataDefinition,
	              i = e.hypercubePath;
	            if (t.dimensions && "function" == typeof t.dimensions.added) {
	              var a = o.getValue(n, i || "").qHyperCubeDef,
	                s = function (e) {
	                  if (Array.isArray(e)) return S(e);
	                }(r = a.qDimensions) || function (e) {
	                  if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e);
	                }(r) || function (e, r) {
	                  if (e) {
	                    if ("string" == typeof e) return S(e, r);
	                    var n = Object.prototype.toString.call(e).slice(8, -1);
	                    return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? S(e, r) : void 0;
	                  }
	                }(r) || function () {
	                  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	                }();
	              a.qDimensions = [], s.forEach(function (e) {
	                a.qDimensions.push(e), t.dimensions.added(e, n);
	              });
	            }
	          },
	          k = function (e) {
	            var r,
	              n = e.newProperties,
	              t = e.dataDefinition,
	              i = e.hypercubePath;
	            if (t.measures && "function" == typeof t.measures.added) {
	              var a = o.getValue(n, i || "").qHyperCubeDef,
	                s = function (e) {
	                  if (Array.isArray(e)) return M(e);
	                }(r = a.qMeasures) || function (e) {
	                  if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e);
	                }(r) || function (e, r) {
	                  if (e) {
	                    if ("string" == typeof e) return M(e, r);
	                    var n = Object.prototype.toString.call(e).slice(8, -1);
	                    return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? M(e, r) : void 0;
	                  }
	                }(r) || function () {
	                  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	                }();
	              a.qMeasures = [], s.forEach(function (e) {
	                a.qMeasures.push(e), t.measures.added(e, n);
	              });
	            }
	          },
	          W = function (e) {
	            var r = e.measures,
	              n = e.modifierTypes;
	            r && n && m().isSupportedModifiers(n) && r.forEach(function (e) {
	              e.store && e.store.modifiers && (e.qDef.modifiers = e.store.modifiers), delete e.store;
	            });
	          };
	        function $(e, r) {
	          var n = o.getValue(e, "qLayoutExclude.quarantine", {})[r];
	          return !!n && (Object.keys(n).forEach(function (r) {
	            o.setValue(e, r, n[r]);
	          }), delete e.qLayoutExclude.quarantine[r], true);
	        }
	        const U = {
	          exportProperties: function (e) {
	            var r = e.propertyTree,
	              n = e.hypercubePath,
	              t = e.viewDataMode,
	              i = function () {
	                for (var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 1, r = {
	                    data: [],
	                    properties: {}
	                  }, n = 0; n < e; ++n) r.data.push({
	                  dimensions: [],
	                  measures: [],
	                  excludedDimensions: [],
	                  excludedMeasures: [],
	                  interColumnSortOrder: []
	                });
	                return r;
	              }(),
	              a = r.qProperty,
	              s = o.getValue(a, n || ""),
	              u = s.qHyperCubeDef;
	            return u.qInterColumnSortOrder || (u.qInterColumnSortOrder = []), d({
	              exportFormat: i,
	              qHyperCubeDef: u
	            }), y({
	              exportFormat: i,
	              qHyperCubeDef: u
	            }), q({
	              exportFormat: i,
	              qHyperCubeDef: u
	            }), delete u.qLayoutExclude, b({
	              exportFormat: i,
	              properties: a
	            }), n && (i.properties.qHyperCubeDef = u, delete s.qHyperCubeDef), v({
	              exportFormat: i,
	              properties: a
	            }), t || D(i.properties.qHyperCubeDef.qMeasures), Array.isArray(i.properties.filters) && (g(i.properties, "filters", "storedFilters", true), delete i.properties.filters), i.properties.qHyperCubeDef.qContextSetExpression && (g(i.properties, "qHyperCubeDef.qContextSetExpression", "storedFilters"), i.properties.qHyperCubeDef.qContextSetExpression = ""), i.properties.qHyperCubeDef.qDynamicScript && i.properties.qHyperCubeDef.qDynamicScript.length && (g(i.properties, "qHyperCubeDef.qDynamicScript", "dynamicScript"), i.properties.qHyperCubeDef.qDynamicScript = []), i;
	          },
	          importProperties: function (e) {
	            var r = e.exportFormat,
	              n = e.initialProperties,
	              t = void 0 === n ? {} : n,
	              i = e.dataDefinition,
	              a = void 0 === i ? {} : i,
	              s = e.defaultPropertyValues,
	              u = void 0 === s ? {} : s,
	              l = e.hypercubePath,
	              c = e.extension,
	              p = e.supportedFilters,
	              f = void 0 === p || p,
	              m = e.isHCModifierSupported,
	              d = void 0 === m || m,
	              y = {
	                qChildren: []
	              },
	              q = j({
	                exportFormat: r,
	                initialProperties: t,
	                hypercubePath: l
	              }),
	              b = o.getValue(t, l || "").qHyperCubeDef,
	              v = o.getValue(q, l || "").qHyperCubeDef,
	              D = H({
	                exportFormat: r,
	                dataDefinition: a
	              }),
	              g = D.maxDimensions,
	              h = D.minDimensions,
	              x = D.maxMeasures,
	              A = D.minMeasures,
	              E = u.defaultDimension,
	              C = void 0 === E ? P() : E,
	              I = u.defaultMeasure,
	              S = void 0 === I ? V() : I;
	            v.qDimensions.length = 0, v.qMeasures.length = 0, R({
	              exportFormat: r,
	              maxDimensions: g,
	              minDimensions: h,
	              maxMeasures: x,
	              minMeasures: A
	            }) && _({
	              exportFormat: r,
	              maxDimensions: g,
	              minDimensions: h,
	              maxMeasures: x,
	              minMeasures: A,
	              newHyperCubeDef: v
	            }), N({
	              exportFormat: r,
	              maxDimensions: g,
	              minDimensions: h,
	              newHyperCubeDef: v,
	              defaultDimension: C
	            }), w({
	              exportFormat: r,
	              maxMeasures: x,
	              minMeasures: A,
	              newHyperCubeDef: v,
	              defaultMeasure: S
	            }), B({
	              newProperties: q,
	              dataDefinition: a,
	              hypercubePath: l
	            }), k({
	              newProperties: q,
	              dataDefinition: a,
	              hypercubePath: l
	            }), T({
	              exportFormat: r,
	              newHyperCubeDef: v
	            }), O("qMaxStackedCells", b, v), O("qNoOfLeftDims", b, v), F("qInitialDataFetch", b, v, [{
	              qTop: 0,
	              qLeft: 0,
	              qWidth: 0,
	              qHeight: 0
	            }]), F("qMode", b, v, "S"), F("qReductionMode", b, v, "N"), F("qSortbyYValue", b, v), F("qIndentMode", b, v), F("qShowTotalsAbove", b, v), L(q, r, t), y.qProperty = q;
	            var M = o.getValue(c || {}, "support.modifiers");
	            return W({
	              measures: v.qMeasures,
	              modifierTypes: M
	            }), f && $(y.qProperty, "storedFilters"), "S" === v.qMode && d && $(y.qProperty, "dynamicScript"), y;
	          }
	        };
	        var G = {
	          cellBackgroundColor: true,
	          cellForegroundColor: true,
	          colorByAlternative: true,
	          colorByExpression: true,
	          tooltip: true,
	          urlLabel: true,
	          url: true
	        };
	        function z(e, r, n, t) {
	          r = r || [];
	          var i = c(e, t, n),
	            o = c(r, t, n);
	          if (-1 !== i && -1 === o) {
	            var a = e.splice(i, 1);
	            r.push(a[0]);
	          }
	          return r;
	        }
	        function Y(e, r) {
	          return e.length !== r;
	        }
	        const J = {
	            create: function (e, r) {
	              if (!e || !G[e]) throw new Error("Attribute Expressions Util: ID required");
	              var n = {};
	              return r && Object.keys(r).forEach(function (e) {
	                n[e] = r[e];
	              }), n.id = e, n.qAttribute = true, n;
	            },
	            moveByIdFromGroup: function (e, r, n, t, i) {
	              n = n || "qAttributeExpressions", i = i || "id";
	              for (var o = 0; o < e.length; o++) {
	                var a = e[o][n],
	                  s = r.length;
	                if (z(a, r, t, i), Y(r, s)) return r;
	              }
	              return r;
	            },
	            IDMAP: {
	              CELL_BACKGROUND_COLOR: "cellBackgroundColor",
	              CELL_FOREGROUND_COLOR: "cellForegroundColor",
	              COLOR_BY_ALTERNATIVE: "colorByAlternative",
	              COLOR_BY_EXPRESSION: "colorByExpression",
	              TOOLTIP: "tooltip",
	              CELL_LINK_LABEL: "urlLabel",
	              CELL_LINK_URL: "url"
	            }
	          },
	          K = {
	            getNumDimensions: function (e) {
	              return o.getValue(e, "qHyperCubeDef.qDimensions.length", 0);
	            },
	            getNumMeasures: function (e) {
	              return o.getValue(e, "qHyperCubeDef.qMeasures.length", 0);
	            },
	            wrapFieldName: function (e) {
	              return e.split(" ").length > 1 && "=" !== e[0] && "[" !== e[0] ? "[".concat(e, "]") : e;
	            },
	            getItemLabel: function (e) {
	              return e.label || e.name;
	            }
	          },
	          X = {
	            colorModeOptions: {
	              primary: function () {
	                return true;
	              },
	              dimension: function (e) {
	                return K.getNumDimensions(e) > 0 && K.getNumMeasures(e) <= 1;
	              },
	              multiColor: function (e) {
	                return K.getNumMeasures(e) > 1;
	              },
	              measure: function (e) {
	                return K.getNumDimensions(e) > 0;
	              },
	              expression: function (e) {
	                return K.getNumMeasures(e) >= 1;
	              }
	            }
	          },
	          Q = {
	            colorModeOptions: {
	              primary: function () {
	                return true;
	              },
	              dimension: function () {
	                return true;
	              },
	              multiColor: function () {
	                return false;
	              },
	              measure: function () {
	                return true;
	              },
	              expression: function (e) {
	                return K.getNumMeasures(e) >= 1;
	              }
	            }
	          };
	        var Z = {
	          scatterplot: Q,
	          "sn-scatter-plot": Q,
	          piechart: {
	            colorModeOptions: {
	              primary: function () {
	                return true;
	              },
	              dimension: function () {
	                return true;
	              },
	              multiColor: function () {
	                return false;
	              },
	              measure: function () {
	                return true;
	              },
	              expression: function (e) {
	                return K.getNumMeasures(e) >= 1;
	              }
	            }
	          },
	          linechart: {
	            colorModeOptions: {
	              primary: function () {
	                return true;
	              },
	              dimension: function (e) {
	                return K.getNumDimensions(e) > 1;
	              },
	              multiColor: function (e) {
	                return K.getNumMeasures(e) > 1;
	              },
	              measure: function (e) {
	                return K.getNumDimensions(e) <= 1;
	              },
	              expression: function (e) {
	                return K.getNumMeasures(e) >= 1;
	              }
	            }
	          },
	          map: {
	            colorModeOptions: {
	              primary: function () {
	                return true;
	              },
	              dimension: function (e) {
	                return K.getNumDimensions(e) >= 1;
	              },
	              multiColor: function (e) {
	                return K.getNumMeasures(e) > 1;
	              },
	              measure: function (e) {
	                return K.getNumDimensions(e) >= 1;
	              },
	              expression: function (e) {
	                return K.getNumDimensions(e) >= 1;
	              }
	            }
	          },
	          distributionplot: {
	            colorModeOptions: {
	              primary: function () {
	                return true;
	              },
	              dimension: function () {
	                return true;
	              },
	              multiColor: function () {
	                return false;
	              },
	              measure: function () {
	                return true;
	              },
	              expression: function (e) {
	                return K.getNumDimensions(e) >= 1;
	              }
	            }
	          }
	        };
	        function ee(e, r, n) {
	          if (Array.isArray(e[r])) {
	            var t = p.findIndexByPropertyValue(e[r], "id", n);
	            t >= 0 && e[r].splice(t, 1);
	          } else e[r] = [];
	        }
	        function re(e, r) {
	          var n = J.IDMAP.COLOR_BY_ALTERNATIVE;
	          e.forEach(function (e) {
	            ee(e, "qAttributeDimensions", n), ee(e, "qAttributeExpressions", n);
	          }), r.forEach(function (e) {
	            ee(e, "qAttributeDimensions", n), ee(e, "qAttributeExpressions", n);
	          });
	        }
	        function ne(e, r) {
	          if (r) {
	            var n = "=" === r.charAt(0);
	            e.color.altLabel = n ? {
	              qStringExpression: {
	                qExpr: r.substr(1)
	              }
	            } : r;
	          }
	        }
	        function te(e) {
	          var r = e.properties,
	            n = e.isDimension,
	            t = e.dimensions,
	            i = e.excludedDimensions,
	            a = e.measures,
	            s = e.label;
	          re(t, i);
	          var u = t[t.length - 1];
	          if (u) {
	            var l = n ? o.getValue(r, "color.byDimDef") : o.getValue(r, "color.byMeasureDef"),
	              c = o.getValue(r, "color.formatting.qNumFormat"),
	              f = o.getValue(r, "color.formatting.isCustomFormatted");
	            if (l) {
	              var m = J.create(J.IDMAP.COLOR_BY_ALTERNATIVE);
	              switch (l.type) {
	                case "expression":
	                  !function (e) {
	                    var r = e.attributeExpression,
	                      n = e.label,
	                      t = e.item,
	                      i = e.isDimension,
	                      o = e.qNumFormat,
	                      a = e.isCustomFormatted;
	                    r.label = n || t.label, i ? r.qDef = t.key : (r.qExpression = t.key, o && (r.qNumFormat = o, r.isCustomFormatted = a)), r.matchMeasure = t.activeMeasureIndex, r.label && "=" === r.label.charAt(0) && (r.labelExpRef = "color.altLabel");
	                  }({
	                    attributeExpression: m,
	                    label: s,
	                    item: l,
	                    isDimension: n,
	                    qNumFormat: c,
	                    isCustomFormatted: f
	                  });
	                  break;
	                case "libraryItem":
	                  !function (e) {
	                    var r = e.attributeExpression,
	                      n = e.measures,
	                      t = e.item,
	                      i = e.qNumFormat,
	                      o = e.isCustomFormatted;
	                    e.isDimension || (r.matchMeasure = p.findIndexByPropertyValue(n, "qLibraryId", t.key), i && (r.qNumFormat = i, r.isCustomFormatted = o)), void 0 !== t.expression ? r.qExpression = t.expression : r.qLibraryId = t.key, r.colorMapRef = t.key;
	                  }({
	                    attributeExpression: m,
	                    measures: a,
	                    item: l,
	                    isDimension: n,
	                    qNumFormat: c,
	                    isCustomFormatted: f
	                  });
	              }
	              n ? (m.qSortBy = {
	                qSortByAscii: 1
	              }, u.qAttributeDimensions.push(m)) : u.qAttributeExpressions.push(m);
	            }
	          }
	        }
	        function ie(e, r, n, t) {
	          var i,
	            o,
	            a,
	            s = {};
	          switch (e) {
	            case "dimension":
	              n.qLibraryId ? (s.type = "dimension", s.name = n.qLibraryId, s.id = n.qLibraryId) : (s.type = "field", r ? (s.name = n.label || n.qDef, s.id = n.qDef) : (s.name = n.qDef.qFieldDefs[0], s.label = (a = n.qDef).qLabelExpression ? a.qLabelExpression : a.qFieldLabels && a.qFieldLabels[0] ? a.qFieldLabels[0] : a.qFieldDefs[0]));
	              break;
	            case "measure":
	              i = function (e, r) {
	                return r ? e.qLibraryId : m().measureBase.getLibraryId(e);
	              }(n, r), i ? (s.type = "measure", s.name = i, s.id = i, o = function (e, r) {
	                return m().hasActiveModifiers({
	                  measures: [e]
	                }) && r ? e.qDef.qDef : void 0;
	              }(n, t), o && (s.expression = o)) : (s.type = "expression", r ? (s.name = n.label || n.qExpression, s.id = n.qExpression) : (s.name = n.qDef.qDef, s.label = function (e) {
	                var r = e.qDef;
	                return r.qLabelExpression ? r.qLabelExpression : r.qLabel ? r.qLabel : r.qDef;
	              }(n)));
	              break;
	            default:
	              throw new Error('columnType should be "dimension" or "measure"');
	          }
	          return s;
	        }
	        const oe = {
	          useMasterNumberFormat: function (e) {
	            e.quarantine = {
	              qNumFormat: e.qNumFormat || {},
	              isCustomFormatted: e.isCustomFormatted || false
	            }, e.qNumFormat = null, e.isCustomFormatted = void 0;
	          }
	        };
	        function ae(e, r, n, t) {
	          var i = r.type,
	            o = e.color,
	            a = o.mode,
	            s = K.getItemLabel(r);
	          switch (ne(e, s || ""), i) {
	            case "field":
	              a = "byDimension", o.byDimDef = {
	                label: r.label || K.wrapFieldName(r.name),
	                key: K.wrapFieldName(r.name),
	                type: "expression",
	                activeDimensionIndex: r.activeDimensionIndex
	              };
	              break;
	            case "expression":
	              a = "byMeasure", o.byMeasureDef = {
	                label: s,
	                key: r.name,
	                type: "expression",
	                activeMeasureIndex: r.activeMeasureIndex
	              };
	              break;
	            case "dimension":
	              a = "byDimension", o.byDimDef = {
	                label: r.name,
	                key: r.id,
	                type: "libraryItem",
	                activeDimensionIndex: r.activeDimensionIndex
	              };
	              break;
	            case "measure":
	              a = "byMeasure", o.byMeasureDef = {
	                label: r.name,
	                key: r.id,
	                expression: r.expression,
	                type: "libraryItem",
	                activeMeasureIndex: r.activeMeasureIndex
	              }, o.formatting && oe.useMasterNumberFormat(o.formatting);
	          }
	          (o.auto = false, o.mode = a);
	        }
	        function se(e, r) {
	          var n = o.getValue(e, "".concat(r, "qDimensions"), []),
	            t = o.getValue(e, "".concat(r, "qMeasures"), []),
	            i = o.getValue(e, "".concat(r, "qLayoutExclude.qHyperCubeDef.qDimensions"), []),
	            a = o.getValue(e, "color.byDimDef");
	          if (a && ne(e, a.label), function (e) {
	            return !!(e && e.activeDimensionIndex > -1);
	          }(a)) !function (e, r) {
	            var n = o.getValue(e, "".concat(r, "qDimensions"), []),
	              t = o.getValue(e, "color.byDimDef");
	            t.activeDimensionIndex = Math.min(t.activeDimensionIndex, n.length - 1);
	            var i = ie("dimension", false, n[t.activeDimensionIndex]);
	            i.activeDimensionIndex = t.activeDimensionIndex, ae(e, i);
	          }(e, r);else if (function (e) {
	            return !e || !e.key;
	          }(a) && function (e, r) {
	            var n = o.getValue(e, "".concat(r, "qDimensions"), []),
	              t = n[function (e, r, n) {
	                var t = o.getValue(r, "visualization"),
	                  i = n.split("."),
	                  a = Number(i[1]),
	                  s = o.getValue(r, "layers.".concat(a, ".type"));
	                return 2 === e.length && "map" === t && "point" === s;
	              }(n, e, r) ? 0 : n.length - 1],
	              i = J.IDMAP.COLOR_BY_ALTERNATIVE,
	              a = p.findItemByPropertyValue(t.qAttributeDimensions, "id", i);
	            return ae(e, ie("dimension", !!a, a || t)), !!a;
	          }(e, r)) return;
	          te({
	            properties: e,
	            isDimension: true,
	            dimensions: n,
	            excludedDimensions: i,
	            measures: t,
	            label: o.getValue(e, "color.byDimDef.label")
	          });
	        }
	        const ue = function (e, r, n) {
	            o.setValue(e, r, n), o.isAtomicValue(n) && function (e, r, n) {
	              var t = e.qLayoutExclude;
	              t && (t.changed || (t.changed = {}), t.changed[r] = {
	                from: o.getValue(e, r),
	                to: n
	              });
	            }(e, r, n);
	          },
	          le = function (e, r) {
	            var n = {
	              primary: true
	            };
	            if (e) {
	              var t = (Z[r] || X).colorModeOptions || X.colorModeOptions;
	              n.byDimension = t.dimension(e), n.byMeasure = t.measure(e), n.byMultiple = t.multiColor(e), n.byExpression = t.expression(e);
	            }
	            return n;
	          },
	          ce = function (e) {
	            var r = e.canColorBy,
	              n = e.autoColor,
	              t = e.colorMode,
	              i = e.dimensions;
	            return !(r[t] && !n && ("byDimension" !== t && "byMeasure" !== t || !i.length));
	          },
	          pe = function (e, r) {
	            var n,
	              t = o.getValue(e, "color.mode"),
	              i = o.getValue(e, "color.auto"),
	              a = o.getValue(e, "".concat(r, "qDimensions"), []),
	              s = o.getValue(e, "".concat(r, "qMeasures"), []),
	              u = o.getValue(e, "".concat(r, "qLayoutExclude.qHyperCubeDef.qDimensions"), []);
	            i ? re(a, u) : !(n = {
	              auto: i,
	              colorMode: t,
	              dimensions: a
	            }).auto && "byDimension" === n.colorMode && n.dimensions.length > 0 ? se(e, r) : function (e) {
	              var r = e.auto,
	                n = e.colorMode,
	                t = e.dimensions,
	                i = e.measures,
	                a = e.properties,
	                s = o.getValue(a, "visualization");
	              return !(r || "byMeasure" !== n || !t.length || "map" !== s && !i.length);
	            }({
	              auto: i,
	              colorMode: t,
	              dimensions: a,
	              measures: s,
	              properties: e
	            }) ? function (e, r) {
	              var n = o.getValue(e, "".concat(r, "qDimensions"), []),
	                t = o.getValue(e, "".concat(r, "qMeasures"), []),
	                i = o.getValue(e, "".concat(r, "qLayoutExclude.qHyperCubeDef.qDimensions"), []),
	                a = o.getValue(e, "color.byMeasureDef");
	              if (a && ne(e, a.label), function (e) {
	                return !!(e && e.activeMeasureIndex > -1);
	              }(a)) !function (e, r) {
	                var n = o.getValue(e, "".concat(r, "qMeasures"), []),
	                  t = o.getValue(e, "color.byMeasureDef");
	                if (t.activeMeasureIndex = Math.min(t.activeMeasureIndex, n.length - 1), t.activeMeasureIndex > -1) {
	                  var i = ie("measure", false, n[t.activeMeasureIndex], true);
	                  i.activeMeasureIndex = t.activeMeasureIndex, ae(e, i);
	                }
	              }(e, r);else if (function (e, r) {
	                return (!e || !e.key) && r.length > 0;
	              }(a, t) && function (e, r) {
	                var n = o.getValue(e, "".concat(r, "qDimensions"), []),
	                  t = o.getValue(e, "".concat(r, "qMeasures"), []),
	                  i = n[n.length - 1],
	                  a = J.IDMAP.COLOR_BY_ALTERNATIVE,
	                  s = p.findItemByPropertyValue(i.qAttributeExpressions, "id", a);
	                return ae(e, ie("measure", !!s, s || t[0])), !!s;
	              }(e, r)) return;
	              te({
	                properties: e,
	                isDimension: false,
	                dimensions: n,
	                excludedDimensions: i,
	                measures: t,
	                label: o.getValue(e, "color.byMeasureDef.label")
	              });
	            }(e, r) : function (e, r) {
	              var n = o.getValue(e, "color.mode"),
	                t = o.getValue(e, "".concat(r, "qDimensions"), []),
	                i = o.getValue(e, "".concat(r, "qMeasures"), []),
	                a = o.getValue(e, "".concat(r, "qLayoutExclude.qHyperCubeDef.qDimensions"), []);
	              "byMultiple" === n && i.length < 2 && o.setValue(e, "color.mode", "primary"), re(t, a);
	            }(e, r);
	          },
	          fe = function (e) {
	            e.forEach(function (e) {
	              e.qOtherTotalSpec && "qTotalMode" in e.qOtherTotalSpec && delete e.qOtherTotalSpec.qTotalMode;
	            });
	          },
	          me = function (e) {
	            var r = e.shouldUpdateColorBy,
	              n = e.properties,
	              t = o.getValue(n, "qHyperCubeDef.qMeasures", []),
	              i = o.getValue(n, "color.mode", "");
	            return !r && "byExpression" === i && t.length > 0;
	          },
	          de = function (e) {
	            var r = o.getValue(e, "qHyperCubeDef.qMeasures.0.qAttributeExpressions", []),
	              n = o.getValue(e, "color.colorExpression", "");
	            r.splice(0, 0, {
	              qExpression: n,
	              id: "colorByExpression"
	            }), o.setValue(e, "qHyperCubeDef.qMeasures.0.qAttributeExpressions", r);
	          },
	          ye = function (e) {
	            o.setValue(e, "color.mode", "primary"), o.setValue(e, "color.auto", true);
	          },
	          qe = function (e) {
	            var r = o.getValue(e, "qHyperCubeDef.qDimensions", []),
	              n = o.getValue(e, "color.persistent", false);
	            return r.length > 1 && !n;
	          },
	          be = {
	            exportProperties: function (e) {
	              var r = e.propertyTree,
	                n = e.hypercubePath,
	                t = e.viewDataMode,
	                i = U.exportProperties({
	                  propertyTree: r,
	                  hypercubePath: n,
	                  viewDataMode: t
	                }),
	                o = i.data[0],
	                a = o.dimensions.concat(o.excludedDimensions),
	                s = o.measures.concat(o.excludedMeasures),
	                u = J.IDMAP,
	                l = u.COLOR_BY_ALTERNATIVE,
	                c = u.COLOR_BY_EXPRESSION;
	              return J.moveByIdFromGroup(a, [], "qAttributeDimensions", l), J.moveByIdFromGroup(a, [], "qAttributeExpressions", l), J.moveByIdFromGroup(s, [], "qAttributeExpressions", c), i;
	            },
	            importProperties: function (e) {
	              var r = e.exportFormat,
	                n = e.initialProperties,
	                t = e.dataDefinition,
	                i = e.defaultPropertyValues,
	                a = e.hypercubePath,
	                s = e.extension,
	                u = e.supportedFilters,
	                l = e.isHCModifierSupported,
	                c = U.importProperties({
	                  exportFormat: r,
	                  initialProperties: n,
	                  dataDefinition: t,
	                  defaultPropertyValues: i,
	                  hypercubePath: a,
	                  extension: s,
	                  supportedFilters: u,
	                  isHCModifierSupported: l
	                }),
	                p = c.qProperty,
	                f = o.getValue(p, "visualization"),
	                m = o.getValue(p, "qHyperCubeDef.qDimensions", []),
	                d = o.getValue(p, "color.mode", ""),
	                y = o.getValue(p, "color.auto", ""),
	                q = le(p, f),
	                b = ce({
	                  canColorBy: q,
	                  autoColor: y,
	                  colorMode: d,
	                  dimensions: m
	                });
	              return q[d] ? me({
	                shouldUpdateColorBy: b,
	                properties: p
	              }) && de(p) : ye(p), b && pe(p, "qHyperCubeDef."), qe(p) && ue(p, "color.persistent", true), fe(m), c;
	            }
	          };
	        var ve = ["bar", "marker", "line"];
	        const De = function (e) {
	            var r = e.initialProperties,
	              n = e.properties;
	            r.measureAxis && void 0 === r.measureAxis.autoMinMax ? $(n, "unsupportedAutoMinMax") || x()(n.measureAxis, r.measureAxis) : $(n, "supportedAutoMinMax") || x()(n.measureAxis, r.measureAxis);
	          },
	          ge = function (e) {
	            var r,
	              n = e.exportFormat,
	              t = e.initialProperties,
	              i = e.properties,
	              o = e.measureType,
	              a = i.qHyperCubeDef,
	              s = i.measureAxis;
	            if (function (e) {
	              var r = e.initialProperties;
	              return !(!e.exportFormat.properties.measureAxes || r.measureAxes || !r.measureAxis || void 0 === r.measureAxis.autoMinMax);
	            }({
	              exportFormat: n,
	              initialProperties: t
	            })) {
	              var u = function (e) {
	                var r = [];
	                return e.qMeasures.length > 0 && e.qMeasures.forEach(function (e) {
	                  if (e.qDef.series) {
	                    var n = e.qDef.series,
	                      t = n.type,
	                      i = n.axis;
	                    r[i] || (r[i] = {
	                      axis: i,
	                      type: {
	                        line: 0,
	                        marker: 0,
	                        bar: 0,
	                        total: 0
	                      }
	                    }), ve.includes(t) && r[i].type[t]++, r[i].type.total++;
	                  }
	                }), r;
	              }(a);
	              u.length ? (o && (r = u.filter(function (e) {
	                return e.type[o] > 0;
	              }).sort(function (e, r) {
	                return r.type[o] - e.type[o];
	              })), r && r.length || (r = u.sort(function (e, r) {
	                return r.type.total - e.type.total;
	              })), r && r[0] && x()(s, n.properties.measureAxes[r[0].axis])) : x()(s, n.properties.measureAxes[0]);
	            }
	          },
	          he = function (e) {
	            if (e.qDimensions.length > 1) {
	              var r = e.qInterColumnSortOrder.indexOf(0);
	              if (0 !== r) {
	                var n = e.qInterColumnSortOrder[0];
	                e.qInterColumnSortOrder[0] = 0, e.qInterColumnSortOrder[r] = n;
	              }
	            }
	          },
	          xe = {
	            exportProperties: function (e) {
	              var r = e.propertyTree,
	                n = e.hypercubePath,
	                t = e.viewDataMode,
	                i = e.supportedAutoMinMax,
	                o = void 0 === i || i,
	                a = be.exportProperties({
	                  propertyTree: r,
	                  hypercubePath: n,
	                  viewDataMode: t
	                }),
	                s = a.properties;
	              return o ? (g(s, "measureAxis.min", "supportedAutoMinMax"), g(s, "measureAxis.max", "supportedAutoMinMax")) : (g(s, "measureAxis.min", "unsupportedAutoMinMax"), g(s, "measureAxis.max", "unsupportedAutoMinMax")), a;
	            },
	            importProperties: function (e) {
	              var r = e.exportFormat,
	                n = e.initialProperties,
	                t = e.dataDefinition,
	                i = e.defaultPropertyValues,
	                o = e.hypercubePath,
	                a = e.measureType,
	                s = e.extension,
	                u = e.supportedFilters,
	                l = e.isHCModifierSupported,
	                c = be.importProperties({
	                  exportFormat: r,
	                  initialProperties: n,
	                  dataDefinition: t,
	                  defaultPropertyValues: i,
	                  hypercubePath: o,
	                  extension: s,
	                  supportedFilters: u,
	                  isHCModifierSupported: l
	                }),
	                p = c.qProperty;
	              return De({
	                initialProperties: n,
	                properties: p
	              }), ge({
	                exportFormat: r,
	                initialProperties: n,
	                properties: p,
	                measureType: a
	              }), he(p.qHyperCubeDef), p.qHyperCubeDef.qColumnOrder = [], p.qHyperCubeDef.columnOrder = [], c;
	            }
	          };
	        function Ae(e, r, n) {
	          return "qLayoutExclude.quarantine.".concat(e, ".").concat(r, ".").concat(n);
	        }
	        function Ee(e) {
	          var r = e.properties,
	            n = e.arrayPath,
	            t = e.quarantineName,
	            i = e.arrayName,
	            a = e.itemPath;
	          o.getValue(r, n, []).forEach(function (e) {
	            return function (e) {
	              var r = e.properties,
	                n = e.quarantineName,
	                t = e.arrayName,
	                i = e.item,
	                a = e.itemPath,
	                s = o.getValue(i, a);
	              if (void 0 !== s) {
	                var u = o.getValue(i, "qDef.cId");
	                u || (u = o.generateId(), o.setValue(i, "qDef.cId", u));
	                var l = Ae(n, t, u);
	                o.setValue(r, l, s), o.setValue(i, a, void 0);
	              }
	            }({
	              properties: r,
	              quarantineName: t,
	              arrayName: i,
	              item: e,
	              itemPath: a
	            });
	          });
	        }
	        function Ce(e) {
	          var r = e.properties,
	            n = e.arrayPath,
	            t = e.quarantineName,
	            i = e.arrayName,
	            a = e.itemPath;
	          o.getValue(r, n, []).forEach(function (e) {
	            return function (e) {
	              var r = e.properties,
	                n = e.quarantineName,
	                t = e.arrayName,
	                i = e.item,
	                a = e.itemPath,
	                s = o.getValue(i, "qDef.cId");
	              if (s) {
	                var u = Ae(n, t, s),
	                  l = o.getValue(r, u);
	                void 0 !== l && (o.setValue(i, a, l), o.setValue(r, u, void 0));
	              }
	            }({
	              properties: r,
	              quarantineName: t,
	              arrayName: i,
	              item: e,
	              itemPath: a
	            });
	          });
	        }
	        var Ie = "qHyperCubeDef.qMeasures",
	          Se = "conditionalColoring",
	          Me = "measures",
	          Le = "qDef.conditionalColoring";
	        const Oe = {
	          quarantine: function (e) {
	            Ee({
	              properties: e,
	              arrayPath: Ie,
	              quarantineName: Se,
	              arrayName: Me,
	              itemPath: Le
	            });
	          },
	          unquarantine: function (e) {
	            Ce({
	              properties: e,
	              arrayPath: Ie,
	              itemPath: Le,
	              arrayName: Me,
	              quarantineName: Se
	            });
	          }
	        };
	        var Fe = "qHyperCubeDef.qMeasures",
	          Pe = "measures",
	          Ve = "qHyperCubeDef.qDimensions",
	          Ne = "dimensions",
	          we = "qHyperCubeDef.qLayoutExclude.qHyperCubeDef.qMeasures",
	          He = "alternativeMeasures",
	          Te = "qHyperCubeDef.qLayoutExclude.qHyperCubeDef.qDimensions",
	          je = "alternativeDimensions",
	          Re = "qCalcCondition",
	          _e = "conditionalShowHide";
	        const Be = {
	            quarantine: function (e) {
	              Ee({
	                properties: e,
	                arrayPath: Fe,
	                quarantineName: _e,
	                arrayName: Pe,
	                itemPath: Re
	              }), Ee({
	                properties: e,
	                arrayPath: Ve,
	                quarantineName: _e,
	                arrayName: Ne,
	                itemPath: Re
	              });
	            },
	            unquarantine: function (e) {
	              Ce({
	                properties: e,
	                arrayPath: Fe,
	                quarantineName: _e,
	                arrayName: Pe,
	                itemPath: Re
	              }), Ce({
	                properties: e,
	                arrayPath: Ve,
	                quarantineName: _e,
	                arrayName: Ne,
	                itemPath: Re
	              });
	            },
	            quarantineAlternative: function (e) {
	              Ee({
	                properties: e,
	                arrayPath: we,
	                quarantineName: _e,
	                arrayName: He,
	                itemPath: Re
	              }), Ee({
	                properties: e,
	                arrayPath: Te,
	                quarantineName: _e,
	                arrayName: je,
	                itemPath: Re
	              });
	            },
	            unquarantineAlternative: function (e) {
	              Ce({
	                properties: e,
	                arrayPath: we,
	                quarantineName: _e,
	                arrayName: He,
	                itemPath: Re
	              }), Ce({
	                properties: e,
	                arrayPath: Te,
	                quarantineName: _e,
	                arrayName: je,
	                itemPath: Re
	              });
	            }
	          },
	          ke = {
	            hypercube: U,
	            colorChart: be,
	            axisChart: xe,
	            quarantineProperty: g,
	            unquarantineProperty: $,
	            quarantineArrayProp: Ee,
	            unquarantineArrayProp: Ce,
	            conditionalColoring: Oe,
	            conditionalShow: Be
	          };
	      })(), t.default;
	    })());
	  })(conversion$1);
	  return conversion$1.exports;
	}

	var conversionExports = requireConversion();
	var conversion = /*@__PURE__*/getDefaultExportFromCjs(conversionExports);

	const BINNING_DEFAULTS = {
	  AUTO: true,
	  // True means we calculate the BIN_SIZE to generate BIN_COUNT number of bins
	  BIN_COUNT: 10,
	  // The number of bins the user wants when AUTO = true
	  BIN_SIZE: 10,
	  // The size(width) of the bins the user wants when AUTO = false
	  LABEL: 'x',
	  // The label parameter to the Class function
	  OFFSET: 0,
	  // The offset parameter to the Class function
	  COUNT_DISTINCT: false,
	  // True means we only count distinct values
	  BIN_MODE: 'maxCount' // "maxCount" means that we can only adjust the maximum amount of bins. "size" mean that we can adjust the width and offset
	};
	Object.freeze(BINNING_DEFAULTS);

	/**
	 * Color information structure. Holds the actual color and index in palette.
	 * @name paletteColor
	 * @type object
	 * @property {string} color - Color as hex string (mandatory if index: -1)
	 * @property {number} index - Index in palette
	 */

	/**
	 * Styling settings for reference line
	 * @name refLineStyle
	 * @type object
	 * @property {number} [lineThickness=2] Set the thickness for this reference line.
	 * @property {string} [lineType=''] Set the dash type for this reference line.
	 */

	/**
	 * @name refLine
	 * @type object
	 * @property {boolean|ValueExpression} show=true Set to true to display this reference line.
	 * @property {string} label Reference line label.
	 * @property {boolean} [showLabel=true] Set to true to show the label of this reference line.
	 * @property {boolean} [showValue=true] Set to true to show the value of this reference line.
	 * @property {paletteColor} paletteColor
	 * @property {refLineStyle} [style] - Styling settings for reference line
	 * @property {boolean} [coloredBackground=false] Set to true to fill the label and/or value of this reference line with this color
	 */

	/**
	 * @namespace properties
	 * @entry
	 */
	const properties = {
	  /**
	   * Current version of this generic object definition.
	   * @type {string}
	   * @default
	   */
	  // eslint-disable-next-line no-undef
	  version: "1.0.6",
	  /**
	   * Extends `HyperCubeDef`, see Engine API: `HyperCubeDef`.
	   * @extends {HyperCubeDef}
	   */
	  qHyperCubeDef: {
	    qDimensions: [],
	    qMeasures: [],
	    qMode: 'S',
	    qAlwaysFullyExpanded: true,
	    qSuppressZero: false,
	    qSuppressMissing: true
	  },
	  /**
	   * Bin settings.
	   * @type {object}
	   */
	  bins: {
	    /**
	     * Auto mode generates a nice looking histogram without special parameters.
	     * @type {boolean}
	     * @default
	     */
	    auto: BINNING_DEFAULTS.AUTO,
	    /**
	     * Number of bars to be displayed, used when binMode is set to 'maxCount'.
	     * @type {number}
	     * @default
	     */
	    binCount: '',
	    /**
	     * The width of the bars, used when binMode is set to 'size'.
	     * @type {number}
	     * @default
	     */
	    binSize: BINNING_DEFAULTS.BIN_SIZE,
	    /**
	     * Used to know where to start displaying bars on x-axis.
	     * @type {number}
	     * @default
	     */
	    offset: BINNING_DEFAULTS.OFFSET,
	    /**
	     * Shows unique values.
	     * @type {boolean}
	     * @default
	     */
	    countDistinct: BINNING_DEFAULTS.COUNT_DISTINCT,
	    /**
	     * MaxCount - Able to adjust the maximum number of bars to be displayed. size - Able to adjust size of bars and offset from x-axis.
	     * @type {string}
	     * @default
	     */
	    binMode: BINNING_DEFAULTS.BIN_MODE
	  },
	  /**
	   * Color settings.
	   * @type {object}
	   */
	  color: {
	    /**
	     * @type {object}
	     */
	    bar: {
	      /**
	       * The paletteColor object is used to define the bar color.
	       * @type {paletteColor}
	       * @default { index: 6 }
	       */
	      paletteColor: {
	        index: 6,
	        color: '#4477aa'
	      }
	    }
	  },
	  /**
	   * Data points
	   * @type {object}
	   */
	  dataPoint: {
	    /**
	     * Show labels on bars
	     * @type {boolean}
	     * @default
	     */
	    showLabels: false
	  },
	  /**
	   * Dimension axis settings.
	   * @type {object}
	   */
	  dimensionAxis: {
	    /**
	     * Axis docking position
	     * @type {'near'|'far'}
	     * @default "near"
	     */
	    dock: 'near',
	    /**
	     * Label orientation
	     * @type {'auto'}
	     * @default
	     */
	    label: 'auto',
	    /**
	     * Labels and title
	     * @type {'all'|'labels'|'title'|'none'}
	     */
	    show: 'all'
	  },
	  /**
	   * Measure axis settings.
	   * @type {object}
	   */
	  measureAxis: {
	    /**
	     * Automatic max/min
	     * @type {boolean}
	     * @default
	     */
	    autoMinMax: true,
	    /**
	     * Axis docking position
	     * @type {'near'|'far'}
	     * @default "near"
	     */
	    dock: 'near',
	    /**
	     * Label to show on the measure axis, if left empty it defaults to 'Frequency'
	     * @type {(string|StringExpression)=}
	     * @default
	     */
	    label: '',
	    /**
	     * Axis max value. `"autoMinMax"` must be set to false and `"minMax"`
	     * must be set to `"max"` or `"minMax"` to use this property
	     * @type {number|ValueExpression}
	     * @default
	     */
	    max: 10,
	    /**
	     * Axis min value. `"autoMinMax"` must be set to false and `"minMax"`
	     * must be set to `"min"` or `"minMax"` to use this property
	     * @type {number|ValueExpression}
	     * @default
	     */
	    min: 0,
	    /**
	     * Set custom max/min
	     * @type {'min'|'max'|'minMax'}
	     * @default "min"
	     */
	    minMax: 'min',
	    /**
	     * Labels and title
	     * @type {'all'|'labels'|'title'|'none'}
	     * @default "all"
	     */
	    show: 'all',
	    /**
	     * Axis scale
	     * @type {number}
	     * @default
	     */
	    spacing: 1
	  },
	  /**
	   * Grid lines settings.
	   * @type {object}
	   */
	  gridlines: {
	    /**
	     * Automatic grid line spacing.
	     * @type {boolean}
	     * @default
	     */
	    auto: true,
	    /**
	     * Grid line spacing. Used only when auto is set to false.
	     * @type {0|2|3}
	     * @default
	     */
	    spacing: 2
	  },
	  /**
	   * Reference lines settings
	   * @type {object}
	   */
	  refLine: {
	    /**
	     * Array of measure based reference line definitions
	     * @type {refLine[]}
	     */
	    refLines: []
	  },
	  /**
	   * Wrapper for sorting properties which will be set on the outer dimension.
	   * @type {object}
	   */
	  sorting: {
	    /**
	     * Sort automatically
	     * @type {true}
	     * @default
	     */
	    autoSort: true
	  },
	  /**
	   * Show title for the visualization.
	   * @type {boolean=}
	   * @default
	   */
	  showTitles: true,
	  /**
	   * Visualization subtitle.
	   * @type {(string|StringExpression)=}
	   * @default
	   */
	  subtitle: '',
	  /**
	   * Visualization title.
	   * @type {(string|StringExpression)=}
	   * @default
	   */
	  title: '',
	  /**
	   * Visualization footnote.
	   * @type {(string|StringExpression)=}
	   * @default
	   */
	  footnote: ''
	};

	function data(env) {
	  const {
	    translator
	  } = env;
	  const dimensions = {
	    min: 1,
	    max: 1,
	    description() {
	      return translator.get('Visualization.Histogram.Binning');
	    }
	  };
	  const measures = {
	    min: 0,
	    max: 0
	  };
	  return {
	    path: '/qHyperCubeDef',
	    dimensions,
	    measures
	  };
	}

	/*
	* qlik-chart-modules v0.99.3
	* Copyright (c) 2025 QlikTech International AB
	* Released under the MIT license.
	*/

	function w(e, t) {
	  (null == t || t > e.length) && (t = e.length);
	  for (var n = 0, r = Array(t); n < t; n++) r[n] = e[n];
	  return r;
	}
	function M(e, t, n) {
	  return (t = function (e) {
	    var t = function (e, t) {
	      if ("object" != typeof e || !e) return e;
	      var n = e[Symbol.toPrimitive];
	      if (void 0 !== n) {
	        var r = n.call(e, t);
	        if ("object" != typeof r) return r;
	        throw new TypeError("@@toPrimitive must return a primitive value.");
	      }
	      return ("string" === t ? String : Number)(e);
	    }(e, "string");
	    return "symbol" == typeof t ? t : t + "";
	  }(t)) in e ? Object.defineProperty(e, t, {
	    value: n,
	    enumerable: true,
	    configurable: true,
	    writable: true
	  }) : e[t] = n, e;
	}
	function D(e, t) {
	  return function (e) {
	    if (Array.isArray(e)) return e;
	  }(e) || function (e, t) {
	    var n = null == e ? null : "undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"];
	    if (null != n) {
	      var r,
	        i,
	        o,
	        a,
	        l = [],
	        s = true,
	        c = false;
	      try {
	        if (o = (n = n.call(e)).next, 0 === t) {
	          if (Object(n) !== n) return;
	          s = !1;
	        } else for (; !(s = (r = o.call(n)).done) && (l.push(r.value), l.length !== t); s = !0);
	      } catch (e) {
	        c = true, i = e;
	      } finally {
	        try {
	          if (!s && null != n.return && (a = n.return(), Object(a) !== a)) return;
	        } finally {
	          if (c) throw i;
	        }
	      }
	      return l;
	    }
	  }(e, t) || P(e, t) || function () {
	    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	  }();
	}
	function E(e) {
	  return function (e) {
	    if (Array.isArray(e)) return w(e);
	  }(e) || function (e) {
	    if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e);
	  }(e) || P(e) || function () {
	    throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
	  }();
	}
	function P(e, t) {
	  if (e) {
	    if ("string" == typeof e) return w(e, t);
	    var n = {}.toString.call(e).slice(8, -1);
	    return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? w(e, t) : void 0;
	  }
	}
	var N = "unclassified",
	  F = "equal-equal",
	  j = "equal-higher",
	  z = "equal-lower",
	  H = "equal-void",
	  B = "higher-equal",
	  R = "higher-higher-acute",
	  V = "higher-higher-obtuse",
	  _ = "higher-lower-negative",
	  $ = "higher-lower-positive",
	  K = "higher-void",
	  Y = "lower-equal",
	  G = "lower-higher-negative",
	  U = "lower-higher-positive",
	  W = "lower-lower-acute",
	  X = "lower-lower-obtuse",
	  Z = "lower-void",
	  J = "void-equal",
	  Q = "void-higher",
	  ee = "void-lower",
	  te = "void-void";
	var ae = {
	    TOP: "top",
	    TOP_RIGHT: "top-right",
	    RIGHT: "right",
	    BOTTOM_RIGHT: "bottom-right",
	    BOTTOM: "bottom",
	    BOTTOM_LEFT: "bottom-left",
	    LEFT: "left",
	    TOP_LEFT: "top-left"
	  };
	var ce;
	(M(M(M(M(M(M(M(M(M(M(ce = {}, F, [ae.TOP, ae.BOTTOM]), j, [ae.BOTTOM, ae.BOTTOM_RIGHT]), z, [ae.TOP, ae.TOP_RIGHT]), H, [ae.TOP, ae.BOTTOM]), B, [ae.LEFT, ae.BOTTOM_LEFT, ae.TOP, ae.TOP_RIGHT]), R, [ae.BOTTOM, ae.BOTTOM_LEFT, ae.LEFT, ae.TOP_RIGHT]), V, [ae.BOTTOM, ae.TOP]), _, [ae.TOP, ae.TOP_RIGHT, ae.RIGHT]), $, [ae.BOTTOM, ae.BOTTOM_LEFT, ae.LEFT]), K, [ae.TOP]), M(M(M(M(M(M(M(M(M(M(ce, Y, [ae.TOP]), G, [ae.TOP, ae.TOP_LEFT]), U, [ae.BOTTOM_RIGHT]), W, [ae.TOP, ae.TOP_LEFT, ae.LEFT, ae.TOP_RIGHT, ae.RIGHT]), X, [ae.TOP, ae.BOTTOM]), Z, [ae.TOP]), J, [ae.TOP]), Q, [ae.TOP, ae.BOTTOM]), ee, [ae.TOP, ae.BOTTOM, ae.LEFT]), te, [ae.TOP]), M(ce, N, [ae.TOP, ae.BOTTOM, ae.RIGHT, ae.LEFT, ae.TOP_RIGHT, ae.BOTTOM_RIGHT, ae.BOTTOM_LEFT, ae.TOP_LEFT]));
	var ze$1 = ["American Typewriter, serif", "Andalé Mono, monospace", "Arial Black, sans-serif", "Arial, sans-serif", "Bradley Hand, cursive", "Brush Script MT, cursive", "Comic Sans MS, cursive", "Courier, monospace", "Didot, serif", "Georgia, serif", "Impact, sans-serif", "Lucida Console, monospace", "Luminari, fantasy", "Monaco, monospace", "QlikView Sans, sans-serif", "Source Sans Pro, sans-serif", "Tahoma, sans-serif", "Times New Roman, serif", "Trebuchet MS, sans-serif", "Verdana, sans-serif"],
	  He$1 = ["Abril Fatface, serif", "Bangers, fantasy", "Bebas Neue, sans serif", "EB Garamond, serif", "Fredoka One, fantasy", "Graduate, fantasy", "Gravitas One, serif", "Indie Flower, fantasy", "Inter, sans-serif", "Lobster, fantasy", "Montserrat, sans-serif", "Nixie One, sans-serif", "Noto Sans, sans-serif", "Open Sans, sans-serif", "PT Serif, serif", "Pacifico, cursive", "Permanent Marker, fantasy", "QlikView Sans, sans-serif", "Raleway, sans-serif", "Rammetto One, fantasy", "Roboto, sans-serif", "Source Sans Pro, sans-serif", "Titan One, fantasy", "Yanone Kaffeesatz, sans-serif"];
	function Be$1(e) {
	  return null != e && e.isEnabled("PS_20852_WYSIWYG_FONT_SUPPORT") ? He$1 : ze$1;
	}
	var Re$1 = function (e) {
	  return {
	    value: e,
	    label: e.charAt(0).toUpperCase() + e.slice(1),
	    groupHeader: false,
	    disabled: false,
	    styles: {
	      fontFamily: e
	    }
	  };
	};
	function Ve$1(e) {
	  var t = e.theme,
	    n = e.translator,
	    r = e.defaultValue,
	    i = e.flags,
	    o = [],
	    a = t.getStyle("", "", "fontFamilies");
	  return Array.isArray(a) && a.length ? o.push.apply(o, E(new Set([r].concat(E(a.map(function (e) {
	    return e.split(",").map(function (e) {
	      return e.trim();
	    }).map(function (e) {
	      return e.replace(/\s+/g, " ").trim();
	    }).filter(Boolean).join(", ");
	  })))))) : o.push(r), [{
	    value: "ThemeHeader",
	    label: n.get("properties.themeFonts"),
	    metaText: n.get("properties.theme"),
	    groupHeader: true
	  }].concat(E(o.map(function (e) {
	    return Re$1(e);
	  })), [{
	    value: "DefaultHeader",
	    label: n.get("properties.allFonts"),
	    metaText: n.get("properties.default"),
	    groupHeader: true
	  }], E(Be$1(i).map(function (e) {
	    return Re$1(e);
	  })));
	}
	function _e$1(e) {
	  var t = e.theme,
	    n = e.translator,
	    r = e.id,
	    i = e.path,
	    o = e.flags,
	    a = function () {
	      return t.getStyle(r, i, "fontFamily");
	    };
	  return {
	    getDefaultValue: function () {
	      return a();
	    },
	    getOptions: function () {
	      return Ve$1({
	        theme: t,
	        translator: n,
	        defaultValue: a(),
	        flags: o
	      });
	    }
	  };
	}
	var $e$1 = ["10px", "11px", "12px", "13px", "14px", "15px", "16px", "17px", "18px", "19px", "20px", "21px", "22px", "23px", "24px"],
	  Ke$1 = function (e) {
	    return {
	      value: e,
	      label: e,
	      groupHeader: false,
	      disabled: false
	    };
	  };
	function Ye$1(e) {
	  var t = e.theme,
	    n = e.translator,
	    r = e.id,
	    i = e.path,
	    o = function () {
	      return t.getStyle(r, i, "fontSize");
	    };
	  return {
	    getDefaultValue: function () {
	      return o();
	    },
	    getOptions: function () {
	      return function (e) {
	        var t = e.theme,
	          n = e.translator,
	          r = e.defaultValue,
	          i = [],
	          o = t.getStyle("", "", "fontSizes");
	        return Array.isArray(o) && o.length ? i.push.apply(i, E(new Set([r].concat(E(o))))) : i.push(r), [{
	          value: "ThemeHeader",
	          label: n.get("properties.themeFontSizes"),
	          metaText: n.get("properties.theme"),
	          groupHeader: true
	        }].concat(E(i.map(function (e) {
	          return Ke$1(e);
	        })), [{
	          value: "DefaultHeader",
	          label: n.get("properties.allFontSizes"),
	          metaText: n.get("properties.default"),
	          groupHeader: true
	        }], E($e$1.map(function (e) {
	          return Ke$1(e);
	        })));
	      }({
	        theme: t,
	        translator: n,
	        defaultValue: o()
	      });
	    }
	  };
	}
	function Ge$1(e) {
	  var t = e.theme,
	    n = e.translator,
	    r = e.id,
	    i = e.path;
	  return {
	    fontFamily: _e$1({
	      theme: t,
	      translator: n,
	      id: r,
	      path: i,
	      flags: e.flags
	    }),
	    fontSize: Ye$1({
	      theme: t,
	      translator: n,
	      id: r,
	      path: i
	    })
	  };
	}
	var Ue$1 = ["__proto__", "constructor"],
	  We$1 = function (e) {
	    if (Ue$1.some(function (t) {
	      return e.includes(t);
	    })) throw new Error("font-resolver: Forbidden property.");
	  };
	function Xe$1(e) {
	  var t = e.theme,
	    n = e.translator,
	    r = e.config,
	    i = void 0 === r ? {} : r,
	    o = e.flags,
	    a = function (e) {
	      var t = e.config,
	        n = void 0 === t ? {} : t,
	        r = n.id,
	        i = n.paths;
	      return {
	        id: void 0 === r ? "object" : "".concat("object", ".").concat(r),
	        paths: Array.isArray(i) ? i : []
	      };
	    }({
	      config: i
	    }),
	    l = a.id,
	    s = a.paths,
	    c = {};
	  s.forEach(function (e) {
	    var r = e.split(".");
	    We$1(r);
	    for (var i = c, a = 0; a < r.length; a++) {
	      var s = r[a];
	      a === r.length - 1 ? i[s] = Ge$1({
	        theme: t,
	        translator: n,
	        id: l,
	        path: e,
	        flags: o
	      }) : void 0 === i[s] && (i[s] = {}), i = i[s];
	    }
	  });
	  var u = function (e) {
	    var t = e.split(".");
	    We$1(t);
	    for (var n = c, r = 0; r < t.length; r++) {
	      var i = t[r];
	      if (void 0 === n[i]) throw new Error("font-resolver: Path '".concat(e, "' could not be resolved."));
	      n = n[i];
	    }
	    return n;
	  };
	  return c.getDefaultValue = function (e) {
	    return u(e).getDefaultValue();
	  }, c.getOptions = function (e) {
	    return u(e).getOptions();
	  }, c;
	}
	var Ze$1,
	  Je$1;
	function ft$1(e) {
	  return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
	}
	var dt$1 = function () {
	    if (Je$1) return Ze$1;
	    Je$1 = 1;
	    var e = Object.prototype.hasOwnProperty,
	      t = Object.prototype.toString,
	      n = Object.defineProperty,
	      r = Object.getOwnPropertyDescriptor,
	      i = function (e) {
	        return "function" == typeof Array.isArray ? Array.isArray(e) : "[object Array]" === t.call(e);
	      },
	      o = function (n) {
	        if (!n || "[object Object]" !== t.call(n)) return false;
	        var r,
	          i = e.call(n, "constructor"),
	          o = n.constructor && n.constructor.prototype && e.call(n.constructor.prototype, "isPrototypeOf");
	        if (n.constructor && !i && !o) return false;
	        for (r in n);
	        return void 0 === r || e.call(n, r);
	      },
	      a = function (e, t) {
	        n && "__proto__" === t.name ? n(e, t.name, {
	          enumerable: true,
	          configurable: true,
	          value: t.newValue,
	          writable: true
	        }) : e[t.name] = t.newValue;
	      },
	      l = function (t, n) {
	        if ("__proto__" === n) {
	          if (!e.call(t, n)) return;
	          if (r) return r(t, n).value;
	        }
	        return t[n];
	      };
	    return Ze$1 = function e() {
	      var t,
	        n,
	        r,
	        s,
	        c,
	        u,
	        f = arguments[0],
	        d = 1,
	        p = arguments.length,
	        h = false;
	      for ("boolean" == typeof f && (h = f, f = arguments[1] || {}, d = 2), (null == f || "object" != typeof f && "function" != typeof f) && (f = {}); d < p; ++d) if (null != (t = arguments[d])) for (n in t) r = l(f, n), f !== (s = l(t, n)) && (h && s && (o(s) || (c = i(s))) ? (c ? (c = false, u = r && i(r) ? r : []) : u = r && o(r) ? r : {}, a(f, {
	        name: n,
	        newValue: e(h, u, s)
	      })) : void 0 !== s && a(f, {
	        name: n,
	        newValue: s
	      }));
	      return f;
	    }, Ze$1;
	  }();
	  ft$1(dt$1);
	function bt$1(e, t, n) {
	  e.prototype = t.prototype = n, n.constructor = e;
	}
	function xt$1(e, t) {
	  var n = Object.create(e.prototype);
	  for (var r in t) n[r] = t[r];
	  return n;
	}
	function wt$1() {}
	var qt$1 = 1 / .7,
	  kt$1 = "\\s*([+-]?\\d+)\\s*",
	  Mt$1 = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",
	  Ot$1 = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
	  Ct$1 = /^#([0-9a-f]{3,8})$/,
	  Tt$1 = new RegExp(`^rgb\\(${kt$1},${kt$1},${kt$1}\\)$`),
	  St$1 = new RegExp(`^rgb\\(${Ot$1},${Ot$1},${Ot$1}\\)$`),
	  It$1 = new RegExp(`^rgba\\(${kt$1},${kt$1},${kt$1},${Mt$1}\\)$`),
	  Dt$1 = new RegExp(`^rgba\\(${Ot$1},${Ot$1},${Ot$1},${Mt$1}\\)$`),
	  Et = new RegExp(`^hsl\\(${Mt$1},${Ot$1},${Ot$1}\\)$`),
	  At$1 = new RegExp(`^hsla\\(${Mt$1},${Ot$1},${Ot$1},${Mt$1}\\)$`),
	  Pt = {
	    aliceblue: 15792383,
	    antiquewhite: 16444375,
	    aqua: 65535,
	    aquamarine: 8388564,
	    azure: 15794175,
	    beige: 16119260,
	    bisque: 16770244,
	    black: 0,
	    blanchedalmond: 16772045,
	    blue: 255,
	    blueviolet: 9055202,
	    brown: 10824234,
	    burlywood: 14596231,
	    cadetblue: 6266528,
	    chartreuse: 8388352,
	    chocolate: 13789470,
	    coral: 16744272,
	    cornflowerblue: 6591981,
	    cornsilk: 16775388,
	    crimson: 14423100,
	    cyan: 65535,
	    darkblue: 139,
	    darkcyan: 35723,
	    darkgoldenrod: 12092939,
	    darkgray: 11119017,
	    darkgreen: 25600,
	    darkgrey: 11119017,
	    darkkhaki: 12433259,
	    darkmagenta: 9109643,
	    darkolivegreen: 5597999,
	    darkorange: 16747520,
	    darkorchid: 10040012,
	    darkred: 9109504,
	    darksalmon: 15308410,
	    darkseagreen: 9419919,
	    darkslateblue: 4734347,
	    darkslategray: 3100495,
	    darkslategrey: 3100495,
	    darkturquoise: 52945,
	    darkviolet: 9699539,
	    deeppink: 16716947,
	    deepskyblue: 49151,
	    dimgray: 6908265,
	    dimgrey: 6908265,
	    dodgerblue: 2003199,
	    firebrick: 11674146,
	    floralwhite: 16775920,
	    forestgreen: 2263842,
	    fuchsia: 16711935,
	    gainsboro: 14474460,
	    ghostwhite: 16316671,
	    gold: 16766720,
	    goldenrod: 14329120,
	    gray: 8421504,
	    green: 32768,
	    greenyellow: 11403055,
	    grey: 8421504,
	    honeydew: 15794160,
	    hotpink: 16738740,
	    indianred: 13458524,
	    indigo: 4915330,
	    ivory: 16777200,
	    khaki: 15787660,
	    lavender: 15132410,
	    lavenderblush: 16773365,
	    lawngreen: 8190976,
	    lemonchiffon: 16775885,
	    lightblue: 11393254,
	    lightcoral: 15761536,
	    lightcyan: 14745599,
	    lightgoldenrodyellow: 16448210,
	    lightgray: 13882323,
	    lightgreen: 9498256,
	    lightgrey: 13882323,
	    lightpink: 16758465,
	    lightsalmon: 16752762,
	    lightseagreen: 2142890,
	    lightskyblue: 8900346,
	    lightslategray: 7833753,
	    lightslategrey: 7833753,
	    lightsteelblue: 11584734,
	    lightyellow: 16777184,
	    lime: 65280,
	    limegreen: 3329330,
	    linen: 16445670,
	    magenta: 16711935,
	    maroon: 8388608,
	    mediumaquamarine: 6737322,
	    mediumblue: 205,
	    mediumorchid: 12211667,
	    mediumpurple: 9662683,
	    mediumseagreen: 3978097,
	    mediumslateblue: 8087790,
	    mediumspringgreen: 64154,
	    mediumturquoise: 4772300,
	    mediumvioletred: 13047173,
	    midnightblue: 1644912,
	    mintcream: 16121850,
	    mistyrose: 16770273,
	    moccasin: 16770229,
	    navajowhite: 16768685,
	    navy: 128,
	    oldlace: 16643558,
	    olive: 8421376,
	    olivedrab: 7048739,
	    orange: 16753920,
	    orangered: 16729344,
	    orchid: 14315734,
	    palegoldenrod: 15657130,
	    palegreen: 10025880,
	    paleturquoise: 11529966,
	    palevioletred: 14381203,
	    papayawhip: 16773077,
	    peachpuff: 16767673,
	    peru: 13468991,
	    pink: 16761035,
	    plum: 14524637,
	    powderblue: 11591910,
	    purple: 8388736,
	    rebeccapurple: 6697881,
	    red: 16711680,
	    rosybrown: 12357519,
	    royalblue: 4286945,
	    saddlebrown: 9127187,
	    salmon: 16416882,
	    sandybrown: 16032864,
	    seagreen: 3050327,
	    seashell: 16774638,
	    sienna: 10506797,
	    silver: 12632256,
	    skyblue: 8900331,
	    slateblue: 6970061,
	    slategray: 7372944,
	    slategrey: 7372944,
	    snow: 16775930,
	    springgreen: 65407,
	    steelblue: 4620980,
	    tan: 13808780,
	    teal: 32896,
	    thistle: 14204888,
	    tomato: 16737095,
	    turquoise: 4251856,
	    violet: 15631086,
	    wheat: 16113331,
	    white: 16777215,
	    whitesmoke: 16119285,
	    yellow: 16776960,
	    yellowgreen: 10145074
	  };
	function Lt() {
	  return this.rgb().formatHex();
	}
	function Nt$1() {
	  return this.rgb().formatRgb();
	}
	function Ft(e) {
	  var t, n;
	  return e = (e + "").trim().toLowerCase(), (t = Ct$1.exec(e)) ? (n = t[1].length, t = parseInt(t[1], 16), 6 === n ? jt(t) : 3 === n ? new Rt(t >> 8 & 15 | t >> 4 & 240, t >> 4 & 15 | 240 & t, (15 & t) << 4 | 15 & t, 1) : 8 === n ? zt(t >> 24 & 255, t >> 16 & 255, t >> 8 & 255, (255 & t) / 255) : 4 === n ? zt(t >> 12 & 15 | t >> 8 & 240, t >> 8 & 15 | t >> 4 & 240, t >> 4 & 15 | 240 & t, ((15 & t) << 4 | 15 & t) / 255) : null) : (t = Tt$1.exec(e)) ? new Rt(t[1], t[2], t[3], 1) : (t = St$1.exec(e)) ? new Rt(255 * t[1] / 100, 255 * t[2] / 100, 255 * t[3] / 100, 1) : (t = It$1.exec(e)) ? zt(t[1], t[2], t[3], t[4]) : (t = Dt$1.exec(e)) ? zt(255 * t[1] / 100, 255 * t[2] / 100, 255 * t[3] / 100, t[4]) : (t = Et.exec(e)) ? Gt(t[1], t[2] / 100, t[3] / 100, 1) : (t = At$1.exec(e)) ? Gt(t[1], t[2] / 100, t[3] / 100, t[4]) : Pt.hasOwnProperty(e) ? jt(Pt[e]) : "transparent" === e ? new Rt(NaN, NaN, NaN, 0) : null;
	}
	function jt(e) {
	  return new Rt(e >> 16 & 255, e >> 8 & 255, 255 & e, 1);
	}
	function zt(e, t, n, r) {
	  return r <= 0 && (e = t = n = NaN), new Rt(e, t, n, r);
	}
	function Ht(e) {
	  return e instanceof wt$1 || (e = Ft(e)), e ? new Rt((e = e.rgb()).r, e.g, e.b, e.opacity) : new Rt();
	}
	function Bt(e, t, n, r) {
	  return 1 === arguments.length ? Ht(e) : new Rt(e, t, n, null == r ? 1 : r);
	}
	function Rt(e, t, n, r) {
	  this.r = +e, this.g = +t, this.b = +n, this.opacity = +r;
	}
	function Vt() {
	  return `#${Yt(this.r)}${Yt(this.g)}${Yt(this.b)}`;
	}
	function _t() {
	  const e = $t(this.opacity);
	  return `${1 === e ? "rgb(" : "rgba("}${Kt(this.r)}, ${Kt(this.g)}, ${Kt(this.b)}${1 === e ? ")" : `, ${e})`}`;
	}
	function $t(e) {
	  return isNaN(e) ? 1 : Math.max(0, Math.min(1, e));
	}
	function Kt(e) {
	  return Math.max(0, Math.min(255, Math.round(e) || 0));
	}
	function Yt(e) {
	  return ((e = Kt(e)) < 16 ? "0" : "") + e.toString(16);
	}
	function Gt(e, t, n, r) {
	  return r <= 0 ? e = t = n = NaN : n <= 0 || n >= 1 ? e = t = NaN : t <= 0 && (e = NaN), new Wt(e, t, n, r);
	}
	function Ut(e) {
	  if (e instanceof Wt) return new Wt(e.h, e.s, e.l, e.opacity);
	  if (e instanceof wt$1 || (e = Ft(e)), !e) return new Wt();
	  if (e instanceof Wt) return e;
	  var t = (e = e.rgb()).r / 255,
	    n = e.g / 255,
	    r = e.b / 255,
	    i = Math.min(t, n, r),
	    o = Math.max(t, n, r),
	    a = NaN,
	    l = o - i,
	    s = (o + i) / 2;
	  return l ? (a = t === o ? (n - r) / l + 6 * (n < r) : n === o ? (r - t) / l + 2 : (t - n) / l + 4, l /= s < .5 ? o + i : 2 - o - i, a *= 60) : l = s > 0 && s < 1 ? 0 : a, new Wt(a, l, s, e.opacity);
	}
	function Wt(e, t, n, r) {
	  this.h = +e, this.s = +t, this.l = +n, this.opacity = +r;
	}
	function Xt(e) {
	  return (e = (e || 0) % 360) < 0 ? e + 360 : e;
	}
	function Zt(e) {
	  return Math.max(0, Math.min(1, e || 0));
	}
	function Jt(e, t, n) {
	  return 255 * (e < 60 ? t + (n - t) * e / 60 : e < 180 ? n : e < 240 ? t + (n - t) * (240 - e) / 60 : t);
	}
	bt$1(wt$1, Ft, {
	  copy(e) {
	    return Object.assign(new this.constructor(), this, e);
	  },
	  displayable() {
	    return this.rgb().displayable();
	  },
	  hex: Lt,
	  formatHex: Lt,
	  formatHex8: function () {
	    return this.rgb().formatHex8();
	  },
	  formatHsl: function () {
	    return Ut(this).formatHsl();
	  },
	  formatRgb: Nt$1,
	  toString: Nt$1
	}), bt$1(Rt, Bt, xt$1(wt$1, {
	  brighter(e) {
	    return e = null == e ? qt$1 : Math.pow(qt$1, e), new Rt(this.r * e, this.g * e, this.b * e, this.opacity);
	  },
	  darker(e) {
	    return e = null == e ? .7 : Math.pow(.7, e), new Rt(this.r * e, this.g * e, this.b * e, this.opacity);
	  },
	  rgb() {
	    return this;
	  },
	  clamp() {
	    return new Rt(Kt(this.r), Kt(this.g), Kt(this.b), $t(this.opacity));
	  },
	  displayable() {
	    return -0.5 <= this.r && this.r < 255.5 && -0.5 <= this.g && this.g < 255.5 && -0.5 <= this.b && this.b < 255.5 && 0 <= this.opacity && this.opacity <= 1;
	  },
	  hex: Vt,
	  formatHex: Vt,
	  formatHex8: function () {
	    return `#${Yt(this.r)}${Yt(this.g)}${Yt(this.b)}${Yt(255 * (isNaN(this.opacity) ? 1 : this.opacity))}`;
	  },
	  formatRgb: _t,
	  toString: _t
	})), bt$1(Wt, function (e, t, n, r) {
	  return 1 === arguments.length ? Ut(e) : new Wt(e, t, n, null == r ? 1 : r);
	}, xt$1(wt$1, {
	  brighter(e) {
	    return e = null == e ? qt$1 : Math.pow(qt$1, e), new Wt(this.h, this.s, this.l * e, this.opacity);
	  },
	  darker(e) {
	    return e = null == e ? .7 : Math.pow(.7, e), new Wt(this.h, this.s, this.l * e, this.opacity);
	  },
	  rgb() {
	    var e = this.h % 360 + 360 * (this.h < 0),
	      t = isNaN(e) || isNaN(this.s) ? 0 : this.s,
	      n = this.l,
	      r = n + (n < .5 ? n : 1 - n) * t,
	      i = 2 * n - r;
	    return new Rt(Jt(e >= 240 ? e - 240 : e + 120, i, r), Jt(e, i, r), Jt(e < 120 ? e + 240 : e - 120, i, r), this.opacity);
	  },
	  clamp() {
	    return new Wt(Xt(this.h), Zt(this.s), Zt(this.l), $t(this.opacity));
	  },
	  displayable() {
	    return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && 0 <= this.l && this.l <= 1 && 0 <= this.opacity && this.opacity <= 1;
	  },
	  formatHsl() {
	    const e = $t(this.opacity);
	    return `${1 === e ? "hsl(" : "hsla("}${Xt(this.h)}, ${100 * Zt(this.s)}%, ${100 * Zt(this.l)}%${1 === e ? ")" : `, ${e})`}`;
	  }
	}));
	const Qt = Math.PI / 180,
	  en = 180 / Math.PI,
	  tn = 4 / 29,
	  nn = 6 / 29,
	  rn = 3 * nn * nn;
	function on(e) {
	  if (e instanceof an) return new an(e.l, e.a, e.b, e.opacity);
	  if (e instanceof pn) return hn(e);
	  e instanceof Rt || (e = Ht(e));
	  var t,
	    n,
	    r = un(e.r),
	    i = un(e.g),
	    o = un(e.b),
	    a = ln((.2225045 * r + .7168786 * i + .0606169 * o) / 1);
	  return r === i && i === o ? t = n = a : (t = ln((.4360747 * r + .3850649 * i + .1430804 * o) / .96422), n = ln((.0139322 * r + .0971045 * i + .7141733 * o) / .82521)), new an(116 * a - 16, 500 * (t - a), 200 * (a - n), e.opacity);
	}
	function an(e, t, n, r) {
	  this.l = +e, this.a = +t, this.b = +n, this.opacity = +r;
	}
	function ln(e) {
	  return e > .008856451679035631 ? Math.pow(e, 1 / 3) : e / rn + tn;
	}
	function sn(e) {
	  return e > nn ? e * e * e : rn * (e - tn);
	}
	function cn(e) {
	  return 255 * (e <= .0031308 ? 12.92 * e : 1.055 * Math.pow(e, 1 / 2.4) - .055);
	}
	function un(e) {
	  return (e /= 255) <= .04045 ? e / 12.92 : Math.pow((e + .055) / 1.055, 2.4);
	}
	function fn(e) {
	  if (e instanceof pn) return new pn(e.h, e.c, e.l, e.opacity);
	  if (e instanceof an || (e = on(e)), 0 === e.a && 0 === e.b) return new pn(NaN, 0 < e.l && e.l < 100 ? 0 : NaN, e.l, e.opacity);
	  var t = Math.atan2(e.b, e.a) * en;
	  return new pn(t < 0 ? t + 360 : t, Math.sqrt(e.a * e.a + e.b * e.b), e.l, e.opacity);
	}
	function dn(e, t, n, r) {
	  return 1 === arguments.length ? fn(e) : new pn(e, t, n, null == r ? 1 : r);
	}
	function pn(e, t, n, r) {
	  this.h = +e, this.c = +t, this.l = +n, this.opacity = +r;
	}
	function hn(e) {
	  if (isNaN(e.h)) return new an(e.l, 0, 0, e.opacity);
	  var t = e.h * Qt;
	  return new an(e.l, Math.cos(t) * e.c, Math.sin(t) * e.c, e.opacity);
	}
	bt$1(an, function (e, t, n, r) {
	  return 1 === arguments.length ? on(e) : new an(e, t, n, null == r ? 1 : r);
	}, xt$1(wt$1, {
	  brighter(e) {
	    return new an(this.l + 18 * (null == e ? 1 : e), this.a, this.b, this.opacity);
	  },
	  darker(e) {
	    return new an(this.l - 18 * (null == e ? 1 : e), this.a, this.b, this.opacity);
	  },
	  rgb() {
	    var e = (this.l + 16) / 116,
	      t = isNaN(this.a) ? e : e + this.a / 500,
	      n = isNaN(this.b) ? e : e - this.b / 200;
	    return new Rt(cn(3.1338561 * (t = .96422 * sn(t)) - 1.6168667 * (e = 1 * sn(e)) - .4906146 * (n = .82521 * sn(n))), cn(-0.9787684 * t + 1.9161415 * e + .033454 * n), cn(.0719453 * t - .2289914 * e + 1.4052427 * n), this.opacity);
	  }
	})), bt$1(pn, dn, xt$1(wt$1, {
	  brighter(e) {
	    return new pn(this.h, this.c, this.l + 18 * (null == e ? 1 : e), this.opacity);
	  },
	  darker(e) {
	    return new pn(this.h, this.c, this.l - 18 * (null == e ? 1 : e), this.opacity);
	  },
	  rgb() {
	    return hn(this).rgb();
	  }
	}));
	var mn = e => () => e;
	function gn$1(e) {
	  return 1 == (e = +e) ? vn : function (t, n) {
	    return n - t ? function (e, t, n) {
	      return e = Math.pow(e, n), t = Math.pow(t, n) - e, n = 1 / n, function (r) {
	        return Math.pow(e + r * t, n);
	      };
	    }(t, n, e) : mn(isNaN(t) ? n : t);
	  };
	}
	function vn(e, t) {
	  var n = t - e;
	  return n ? function (e, t) {
	    return function (n) {
	      return e + n * t;
	    };
	  }(e, n) : mn(isNaN(e) ? t : e);
	}
	(function e(t) {
	    var n = gn$1(t);
	    function r(e, t) {
	      var r = n((e = Bt(e)).r, (t = Bt(t)).r),
	        i = n(e.g, t.g),
	        o = n(e.b, t.b),
	        a = vn(e.opacity, t.opacity);
	      return function (t) {
	        return e.r = r(t), e.g = i(t), e.b = o(t), e.opacity = a(t), e + "";
	      };
	    }
	    return r.gamma = e, r;
	  })(1);
	var tr = "center",
	  nr = "bottom";
	  [{
	    key: "NoDataExist",
	    alignment: tr,
	    condition: function (e) {
	      var t = e.layoutService;
	      if (!t) return false;
	      var n = t.meta.size;
	      return n.x * n.y == 0;
	    }
	  }, {
	    key: "OnlyNanDataMeasure",
	    translationKey: "OnlyNanData",
	    alignment: tr,
	    condition: function (e) {
	      var t = e.layoutService;
	      return !!t && t.getHyperCubeValue("qMeasureInfo").every(function (e) {
	        return "NaN" === e.qMin && "NaN" === e.qMax;
	      });
	    }
	  }, {
	    key: "OnlyNanDataDimensionContinuous",
	    translationKey: "OnlyNanData",
	    alignment: tr,
	    condition: function (e) {
	      var t = e.layoutService;
	      if (!t) return false;
	      if (!t.meta.isContinuous) return false;
	      var n = t.getHyperCubeValue("qDimensionInfo.0");
	      return n && (n.qMax < n.qMin || "NaN" === n.qMax);
	    }
	  }, {
	    key: "OnlyNegativeOrZeroValues",
	    alignment: tr
	  }, {
	    key: "DataRangeIncludingZero",
	    alignment: nr
	  }, {
	    key: "LimitedData",
	    alignment: nr
	  }, {
	    key: "NegativeOrZeroValues",
	    alignment: nr
	  }].reduce(function (e, t) {
	    return e[t.key] = t, e;
	  }, {});
	function vr(e, t, n) {
	  if (void 0 === e || void 0 === t) return n;
	  for (var r = t.split("."), i = e, o = 0; o < r.length; ++o) {
	    var a = r[o];
	    if (void 0 === i[a]) return n;
	    i = i[a];
	  }
	  return i;
	}
	var yr = ["__proto__", "constructor"];
	function br(e, t, n) {
	  if (void 0 !== e && void 0 !== t) {
	    var r = t.split("."),
	      i = r[r.length - 1];
	    if (!yr.some(function (e) {
	      return r.includes(e);
	    })) {
	      for (var o = e, a = 0; a < r.length - 1; ++a) {
	        var l = r[a];
	        void 0 === o[l] && (o[l] = Number.isNaN(+r[a + 1]) ? {} : []), o = o[l];
	      }
	      void 0 !== n ? o[i] = n : delete o[i];
	    }
	  }
	}
	function Ur(e) {
	  var t = 0,
	    n = e.children,
	    r = n && n.length;
	  if (r) for (; --r >= 0;) t += n[r].value;else t = 1;
	  e.value = t;
	}
	function Wr(e, t) {
	  e instanceof Map ? (e = [void 0, e], void 0 === t && (t = Zr)) : void 0 === t && (t = Xr);
	  for (var n, r, i, o, a, l = new ei(e), s = [l]; n = s.pop();) if ((i = t(n.data)) && (a = (i = Array.from(i)).length)) for (n.children = i, o = a - 1; o >= 0; --o) s.push(r = i[o] = new ei(i[o])), r.parent = n, r.depth = n.depth + 1;
	  return l.eachBefore(Qr);
	}
	function Xr(e) {
	  return e.children;
	}
	function Zr(e) {
	  return Array.isArray(e) ? e[1] : null;
	}
	function Jr(e) {
	  void 0 !== e.data.value && (e.value = e.data.value), e.data = e.data.data;
	}
	function Qr(e) {
	  var t = 0;
	  do {
	    e.height = t;
	  } while ((e = e.parent) && e.height < ++t);
	}
	function ei(e) {
	  this.data = e, this.depth = this.height = 0, this.parent = null;
	}
	ei.prototype = Wr.prototype = {
	  constructor: ei,
	  count: function () {
	    return this.eachAfter(Ur);
	  },
	  each: function (e, t) {
	    let n = -1;
	    for (const r of this) e.call(t, r, ++n, this);
	    return this;
	  },
	  eachAfter: function (e, t) {
	    for (var n, r, i, o = this, a = [o], l = [], s = -1; o = a.pop();) if (l.push(o), n = o.children) for (r = 0, i = n.length; r < i; ++r) a.push(n[r]);
	    for (; o = l.pop();) e.call(t, o, ++s, this);
	    return this;
	  },
	  eachBefore: function (e, t) {
	    for (var n, r, i = this, o = [i], a = -1; i = o.pop();) if (e.call(t, i, ++a, this), n = i.children) for (r = n.length - 1; r >= 0; --r) o.push(n[r]);
	    return this;
	  },
	  find: function (e, t) {
	    let n = -1;
	    for (const r of this) if (e.call(t, r, ++n, this)) return r;
	  },
	  sum: function (e) {
	    return this.eachAfter(function (t) {
	      for (var n = +e(t.data) || 0, r = t.children, i = r && r.length; --i >= 0;) n += r[i].value;
	      t.value = n;
	    });
	  },
	  sort: function (e) {
	    return this.eachBefore(function (t) {
	      t.children && t.children.sort(e);
	    });
	  },
	  path: function (e) {
	    for (var t = this, n = function (e, t) {
	        if (e === t) return e;
	        var n = e.ancestors(),
	          r = t.ancestors(),
	          i = null;
	        e = n.pop(), t = r.pop();
	        for (; e === t;) i = e, e = n.pop(), t = r.pop();
	        return i;
	      }(t, e), r = [t]; t !== n;) t = t.parent, r.push(t);
	    for (var i = r.length; e !== n;) r.splice(i, 0, e), e = e.parent;
	    return r;
	  },
	  ancestors: function () {
	    for (var e = this, t = [e]; e = e.parent;) t.push(e);
	    return t;
	  },
	  descendants: function () {
	    return Array.from(this);
	  },
	  leaves: function () {
	    var e = [];
	    return this.eachBefore(function (t) {
	      t.children || e.push(t);
	    }), e;
	  },
	  links: function () {
	    var e = this,
	      t = [];
	    return e.each(function (n) {
	      n !== e && t.push({
	        source: n.parent,
	        target: n
	      });
	    }), t;
	  },
	  copy: function () {
	    return Wr(this).eachBefore(Jr);
	  },
	  [Symbol.iterator]: function* () {
	    var e,
	      t,
	      n,
	      r,
	      i = this,
	      o = [i];
	    do {
	      for (e = o.reverse(), o = []; i = e.pop();) if (yield i, t = i.children) for (n = 0, r = t.length; n < r; ++n) o.push(t[n]);
	    } while (o.length);
	  }
	};
	var Si,
	  Ii;
	  (Si = function (e) {
	    /*! javascript-number-formatter - v1.1.11 - http://mottie.github.com/javascript-number-formatter/ * © ecava */
	    e.exports = function (e, t) {
	      if (!e || isNaN(+t)) return t;
	      var n,
	        r,
	        i,
	        o,
	        a,
	        l,
	        s,
	        c,
	        u,
	        f,
	        d = e.length,
	        p = e.search(/[0-9\-\+#]/),
	        h = p > 0 ? e.substring(0, p) : "",
	        m = e.split("").reverse().join(""),
	        g = m.search(/[0-9\-\+#]/),
	        v = d - g,
	        y = e.substring(v, v + 1),
	        b = v + ("." === y || "," === y ? 1 : 0),
	        x = g > 0 ? e.substring(b, d) : "";
	      if (n = (t = "-" === (e = e.substring(p, b)).charAt(0) ? -t : +t) < 0 ? t = -t : 0, i = (r = e.match(/[^\d\-\+#]/g)) && r[r.length - 1] || ".", o = r && r[1] && r[0] || ",", e = e.split(i), t = +(t = t.toFixed(e[1] && e[1].length)) + "", l = e[1] && e[1].lastIndexOf("0"), (!(c = t.split("."))[1] || c[1] && c[1].length <= l) && (t = (+t).toFixed(l + 1)), u = e[0].split(o), e[0] = u.join(""), (a = e[0] && e[0].indexOf("0")) > -1) for (; c[0].length < e[0].length - a;) c[0] = "0" + c[0];else 0 == +c[0] && (c[0] = "");
	      if ((t = t.split("."))[0] = c[0], s = u[1] && u[u.length - 1].length) {
	        for (m = "", v = (f = t[0]).length % s, d = f.length, b = 0; b < d; b++) m += f.charAt(b), !((b - v + 1) % s) && b < d - s && (m += o);
	        t[0] = m;
	      }
	      return t[1] = e[1] && t[1] ? i + t[1] : "", "0" !== (r = t.join("")) && "" !== r || (n = false), h + (n ? "-" : "") + r + x;
	    };
	  }, Si(Ii = {
	    exports: {}
	  }, Ii.exports), Ii.exports);
	var pa = "'Source Sans Pro', 'Arial', 'sans-serif'",
	  ha = "#333333",
	  ma = "#595959",
	  ga = "#737373",
	  va = "#cccccc",
	  ya = "#e6e6e6";
	function ba(e) {
	  var t = {};
	  return [].concat(E(e), E([["", "", "color"], ["object", "", "fontFamily"], ["object", "axis.label.name", "color", ma], ["object", "axis.label.name", "fontFamily", pa], ["object", "axis.label.name", "fontSize", "12px"], ["object", "axis.line.major", "color", va], ["object", "axis.line.minor", "color", ya], ["object", "axis.title", "color"], ["object", "axis.title", "fontFamily", pa], ["object", "axis.title", "fontSize", "13px"], ["object", "grid.line.highContrast", "color", ya], ["object", "grid.line.major", "color", va], ["object", "grid.line.minor", "color", ya], ["object", "label.value", "color", ma], ["object", "label.value", "fontFamily", pa], ["object", "label.value", "fontSize", "12px"], [false, "label.value", "darkColor", ma], [false, "label.value", "lightColor", ya], ["object", "outOfRange", "color", "#999"], ["object", "legend.title", "color", ha], ["object", "legend.title", "fontFamily", pa], ["object", "legend.title", "fontSize", "15px"], ["object", "legend.label", "color", ma], ["object", "legend.label", "fontFamily", pa], ["object", "legend.label", "fontSize", "13px"], ["object", "referenceLine.label.name", "color", ha], ["object", "referenceLine.label.name", "fontFamily", pa], ["object", "referenceLine.label.name", "fontSize", "12px"], ["object", "referenceLine.outOfBounds", "color", ya], ["object", "referenceLine.outOfBounds", "fontFamily", pa], ["object", "referenceLine.outOfBounds", "fontSize", "12px"], ["object", "referenceLine.outOfBounds", "backgroundColor", ga, function (e) {
	    return "transparent" === e ? ga : e;
	  }]])).reduce(function (e, n) {
	    var r = "".concat(n[0], "-").concat(n[1], "-").concat(n[2], "}");
	    return t[r] || (t[r] = true, e.push(n)), e;
	  }, []).sort(function (e, t) {
	    return (e[0].split ? e[0].split(".").length : 0) - (t[0].split ? t[0].split(".").length : 0);
	  });
	}
	var xa = function (e) {
	  return e;
	};
	function wa(e) {
	  var t = e.theme,
	    n = e.id,
	    r = e.transform,
	    i = e.extend,
	    o = e.matrix,
	    a = {},
	    l = r.reduce(function (e, t) {
	      var n = D(t, 2),
	        r = n[0],
	        i = n[1];
	      return e[r] = i, e;
	    }, {});
	  return o.forEach(function (e) {
	    var r = D(e, 5),
	      i = r[0],
	      o = r[1],
	      s = r[2],
	      c = r[3],
	      u = r[4],
	      f = void 0 === u ? function (e) {
	        return e;
	      } : u,
	      d = function (e) {
	        var t = e.theme,
	          n = e.base,
	          r = e.path,
	          i = e.attribute,
	          o = e.defaultValue,
	          a = void 0 === o ? void 0 : o;
	        if (!t || false === n) return a;
	        var l = t.getStyle(n, r, i);
	        return void 0 === l ? a : l;
	      }({
	        theme: t,
	        base: "object" === i && n ? "".concat("object", ".").concat(n) : i,
	        path: o,
	        attribute: s,
	        defaultValue: c
	      }),
	      p = (l["".concat(o, ".").concat(s)] || xa)(f(d));
	    br(a, [o, s].filter(Boolean).join("."), p);
	  }), i.forEach(function (e) {
	    var t = D(e, 2),
	      n = t[0],
	      r = t[1];
	    br(a, n, r);
	  }), a;
	}
	function qa(e) {
	  var t = e.theme,
	    n = e.config,
	    r = void 0 === n ? {} : n,
	    i = r.id,
	    o = r.resolve,
	    a = void 0 === o ? [] : o,
	    l = r.transform,
	    s = void 0 === l ? [] : l,
	    c = r.extend,
	    u = void 0 === c ? [] : c,
	    f = {
	      theme: t,
	      matrix: ba(a),
	      styles: void 0
	    };
	  return f.styles = wa({
	    theme: t,
	    id: i,
	    transform: s,
	    extend: u,
	    matrix: f.matrix
	  }), {
	    getStyles: function () {
	      return f.styles;
	    },
	    getTheme: function () {
	      return f.theme;
	    },
	    setTheme: function (e) {
	      f.theme = e, f.styles = wa({
	        theme: e,
	        id: i,
	        transform: s,
	        extend: u,
	        matrix: f.matrix
	      });
	    }
	  };
	}

	var extend$2;
	var hasRequiredExtend;
	function requireExtend() {
	  if (hasRequiredExtend) return extend$2;
	  hasRequiredExtend = 1;
	  var hasOwn = Object.prototype.hasOwnProperty;
	  var toStr = Object.prototype.toString;
	  var defineProperty = Object.defineProperty;
	  var gOPD = Object.getOwnPropertyDescriptor;
	  var isArray = function isArray(arr) {
	    if (typeof Array.isArray === 'function') {
	      return Array.isArray(arr);
	    }
	    return toStr.call(arr) === '[object Array]';
	  };
	  var isPlainObject = function isPlainObject(obj) {
	    if (!obj || toStr.call(obj) !== '[object Object]') {
	      return false;
	    }
	    var hasOwnConstructor = hasOwn.call(obj, 'constructor');
	    var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
	    // Not own constructor property must be Object
	    if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
	      return false;
	    }

	    // Own properties are enumerated firstly, so to speed up,
	    // if last one is own, then all properties are own.
	    var key;
	    for (key in obj) {/**/}
	    return typeof key === 'undefined' || hasOwn.call(obj, key);
	  };

	  // If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
	  var setProperty = function setProperty(target, options) {
	    if (defineProperty && options.name === '__proto__') {
	      defineProperty(target, options.name, {
	        enumerable: true,
	        configurable: true,
	        value: options.newValue,
	        writable: true
	      });
	    } else {
	      target[options.name] = options.newValue;
	    }
	  };

	  // Return undefined instead of __proto__ if '__proto__' is not an own property
	  var getProperty = function getProperty(obj, name) {
	    if (name === '__proto__') {
	      if (!hasOwn.call(obj, name)) {
	        return void 0;
	      } else if (gOPD) {
	        // In early versions of node, obj['__proto__'] is buggy when obj has
	        // __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
	        return gOPD(obj, name).value;
	      }
	    }
	    return obj[name];
	  };
	  extend$2 = function extend() {
	    var options, name, src, copy, copyIsArray, clone;
	    var target = arguments[0];
	    var i = 1;
	    var length = arguments.length;
	    var deep = false;

	    // Handle a deep copy situation
	    if (typeof target === 'boolean') {
	      deep = target;
	      target = arguments[1] || {};
	      // skip the boolean and the target
	      i = 2;
	    }
	    if (target == null || typeof target !== 'object' && typeof target !== 'function') {
	      target = {};
	    }
	    for (; i < length; ++i) {
	      options = arguments[i];
	      // Only deal with non-null/undefined values
	      if (options != null) {
	        // Extend the base object
	        for (name in options) {
	          src = getProperty(target, name);
	          copy = getProperty(options, name);

	          // Prevent never-ending loop
	          if (target !== copy) {
	            // Recurse if we're merging plain objects or arrays
	            if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
	              if (copyIsArray) {
	                copyIsArray = false;
	                clone = src && isArray(src) ? src : [];
	              } else {
	                clone = src && isPlainObject(src) ? src : {};
	              }

	              // Never move original objects, clone them
	              setProperty(target, {
	                name: name,
	                newValue: extend(deep, clone, copy)
	              });

	              // Don't bring in undefined values
	            } else if (typeof copy !== 'undefined') {
	              setProperty(target, {
	                name: name,
	                newValue: copy
	              });
	            }
	          }
	        }
	      }
	    }

	    // Return the modified object
	    return target;
	  };
	  return extend$2;
	}

	var extendExports = requireExtend();
	var extend$1 = /*@__PURE__*/getDefaultExportFromCjs(extendExports);

	/*
	* qlik-chart-modules v0.95.0
	* Copyright (c) 2025 QlikTech International AB
	* Released under the MIT license.
	*/

	var ue,
	  fe;
	function pe(e) {
	  return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
	}
	var he = function () {
	    if (fe) return ue;
	    fe = 1;
	    var e = Object.prototype.hasOwnProperty,
	      t = Object.prototype.toString,
	      n = Object.defineProperty,
	      r = Object.getOwnPropertyDescriptor,
	      i = function (e) {
	        return "function" == typeof Array.isArray ? Array.isArray(e) : "[object Array]" === t.call(e);
	      },
	      o = function (n) {
	        if (!n || "[object Object]" !== t.call(n)) return false;
	        var r,
	          i = e.call(n, "constructor"),
	          o = n.constructor && n.constructor.prototype && e.call(n.constructor.prototype, "isPrototypeOf");
	        if (n.constructor && !i && !o) return false;
	        for (r in n);
	        return void 0 === r || e.call(n, r);
	      },
	      a = function (e, t) {
	        n && "__proto__" === t.name ? n(e, t.name, {
	          enumerable: true,
	          configurable: true,
	          value: t.newValue,
	          writable: true
	        }) : e[t.name] = t.newValue;
	      },
	      l = function (t, n) {
	        if ("__proto__" === n) {
	          if (!e.call(t, n)) return;
	          if (r) return r(t, n).value;
	        }
	        return t[n];
	      };
	    return ue = function e() {
	      var t,
	        n,
	        r,
	        s,
	        c,
	        u,
	        f = arguments[0],
	        d = 1,
	        p = arguments.length,
	        h = false;
	      for ("boolean" == typeof f && (h = f, f = arguments[1] || {}, d = 2), (null == f || "object" != typeof f && "function" != typeof f) && (f = {}); d < p; ++d) if (null != (t = arguments[d])) for (n in t) r = l(f, n), f !== (s = l(t, n)) && (h && s && (o(s) || (c = i(s))) ? (c ? (c = false, u = r && i(r) ? r : []) : u = r && o(r) ? r : {}, a(f, {
	        name: n,
	        newValue: e(h, u, s)
	      })) : void 0 !== s && a(f, {
	        name: n,
	        newValue: s
	      }));
	      return f;
	    }, ue;
	  }();
	  pe(he);
	function qe(e, t, n) {
	  e.prototype = t.prototype = n, n.constructor = e;
	}
	function we(e, t) {
	  var n = Object.create(e.prototype);
	  for (var r in t) n[r] = t[r];
	  return n;
	}
	function ke() {}
	var Me = 1 / .7,
	  Ce = "\\s*([+-]?\\d+)\\s*",
	  Se = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",
	  De = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
	  Oe = /^#([0-9a-f]{3,8})$/,
	  Ie = new RegExp(`^rgb\\(${Ce},${Ce},${Ce}\\)$`),
	  Ae = new RegExp(`^rgb\\(${De},${De},${De}\\)$`),
	  Ee = new RegExp(`^rgba\\(${Ce},${Ce},${Ce},${Se}\\)$`),
	  Te = new RegExp(`^rgba\\(${De},${De},${De},${Se}\\)$`),
	  Ne = new RegExp(`^hsl\\(${Se},${De},${De}\\)$`),
	  Le = new RegExp(`^hsla\\(${Se},${De},${De},${Se}\\)$`),
	  Pe = {
	    aliceblue: 15792383,
	    antiquewhite: 16444375,
	    aqua: 65535,
	    aquamarine: 8388564,
	    azure: 15794175,
	    beige: 16119260,
	    bisque: 16770244,
	    black: 0,
	    blanchedalmond: 16772045,
	    blue: 255,
	    blueviolet: 9055202,
	    brown: 10824234,
	    burlywood: 14596231,
	    cadetblue: 6266528,
	    chartreuse: 8388352,
	    chocolate: 13789470,
	    coral: 16744272,
	    cornflowerblue: 6591981,
	    cornsilk: 16775388,
	    crimson: 14423100,
	    cyan: 65535,
	    darkblue: 139,
	    darkcyan: 35723,
	    darkgoldenrod: 12092939,
	    darkgray: 11119017,
	    darkgreen: 25600,
	    darkgrey: 11119017,
	    darkkhaki: 12433259,
	    darkmagenta: 9109643,
	    darkolivegreen: 5597999,
	    darkorange: 16747520,
	    darkorchid: 10040012,
	    darkred: 9109504,
	    darksalmon: 15308410,
	    darkseagreen: 9419919,
	    darkslateblue: 4734347,
	    darkslategray: 3100495,
	    darkslategrey: 3100495,
	    darkturquoise: 52945,
	    darkviolet: 9699539,
	    deeppink: 16716947,
	    deepskyblue: 49151,
	    dimgray: 6908265,
	    dimgrey: 6908265,
	    dodgerblue: 2003199,
	    firebrick: 11674146,
	    floralwhite: 16775920,
	    forestgreen: 2263842,
	    fuchsia: 16711935,
	    gainsboro: 14474460,
	    ghostwhite: 16316671,
	    gold: 16766720,
	    goldenrod: 14329120,
	    gray: 8421504,
	    green: 32768,
	    greenyellow: 11403055,
	    grey: 8421504,
	    honeydew: 15794160,
	    hotpink: 16738740,
	    indianred: 13458524,
	    indigo: 4915330,
	    ivory: 16777200,
	    khaki: 15787660,
	    lavender: 15132410,
	    lavenderblush: 16773365,
	    lawngreen: 8190976,
	    lemonchiffon: 16775885,
	    lightblue: 11393254,
	    lightcoral: 15761536,
	    lightcyan: 14745599,
	    lightgoldenrodyellow: 16448210,
	    lightgray: 13882323,
	    lightgreen: 9498256,
	    lightgrey: 13882323,
	    lightpink: 16758465,
	    lightsalmon: 16752762,
	    lightseagreen: 2142890,
	    lightskyblue: 8900346,
	    lightslategray: 7833753,
	    lightslategrey: 7833753,
	    lightsteelblue: 11584734,
	    lightyellow: 16777184,
	    lime: 65280,
	    limegreen: 3329330,
	    linen: 16445670,
	    magenta: 16711935,
	    maroon: 8388608,
	    mediumaquamarine: 6737322,
	    mediumblue: 205,
	    mediumorchid: 12211667,
	    mediumpurple: 9662683,
	    mediumseagreen: 3978097,
	    mediumslateblue: 8087790,
	    mediumspringgreen: 64154,
	    mediumturquoise: 4772300,
	    mediumvioletred: 13047173,
	    midnightblue: 1644912,
	    mintcream: 16121850,
	    mistyrose: 16770273,
	    moccasin: 16770229,
	    navajowhite: 16768685,
	    navy: 128,
	    oldlace: 16643558,
	    olive: 8421376,
	    olivedrab: 7048739,
	    orange: 16753920,
	    orangered: 16729344,
	    orchid: 14315734,
	    palegoldenrod: 15657130,
	    palegreen: 10025880,
	    paleturquoise: 11529966,
	    palevioletred: 14381203,
	    papayawhip: 16773077,
	    peachpuff: 16767673,
	    peru: 13468991,
	    pink: 16761035,
	    plum: 14524637,
	    powderblue: 11591910,
	    purple: 8388736,
	    rebeccapurple: 6697881,
	    red: 16711680,
	    rosybrown: 12357519,
	    royalblue: 4286945,
	    saddlebrown: 9127187,
	    salmon: 16416882,
	    sandybrown: 16032864,
	    seagreen: 3050327,
	    seashell: 16774638,
	    sienna: 10506797,
	    silver: 12632256,
	    skyblue: 8900331,
	    slateblue: 6970061,
	    slategray: 7372944,
	    slategrey: 7372944,
	    snow: 16775930,
	    springgreen: 65407,
	    steelblue: 4620980,
	    tan: 13808780,
	    teal: 32896,
	    thistle: 14204888,
	    tomato: 16737095,
	    turquoise: 4251856,
	    violet: 15631086,
	    wheat: 16113331,
	    white: 16777215,
	    whitesmoke: 16119285,
	    yellow: 16776960,
	    yellowgreen: 10145074
	  };
	function je() {
	  return this.rgb().formatHex();
	}
	function Fe() {
	  return this.rgb().formatRgb();
	}
	function He(e) {
	  var t, n;
	  return e = (e + "").trim().toLowerCase(), (t = Oe.exec(e)) ? (n = t[1].length, t = parseInt(t[1], 16), 6 === n ? ze(t) : 3 === n ? new _e(t >> 8 & 15 | t >> 4 & 240, t >> 4 & 15 | 240 & t, (15 & t) << 4 | 15 & t, 1) : 8 === n ? Re(t >> 24 & 255, t >> 16 & 255, t >> 8 & 255, (255 & t) / 255) : 4 === n ? Re(t >> 12 & 15 | t >> 8 & 240, t >> 8 & 15 | t >> 4 & 240, t >> 4 & 15 | 240 & t, ((15 & t) << 4 | 15 & t) / 255) : null) : (t = Ie.exec(e)) ? new _e(t[1], t[2], t[3], 1) : (t = Ae.exec(e)) ? new _e(255 * t[1] / 100, 255 * t[2] / 100, 255 * t[3] / 100, 1) : (t = Ee.exec(e)) ? Re(t[1], t[2], t[3], t[4]) : (t = Te.exec(e)) ? Re(255 * t[1] / 100, 255 * t[2] / 100, 255 * t[3] / 100, t[4]) : (t = Ne.exec(e)) ? We(t[1], t[2] / 100, t[3] / 100, 1) : (t = Le.exec(e)) ? We(t[1], t[2] / 100, t[3] / 100, t[4]) : Pe.hasOwnProperty(e) ? ze(Pe[e]) : "transparent" === e ? new _e(NaN, NaN, NaN, 0) : null;
	}
	function ze(e) {
	  return new _e(e >> 16 & 255, e >> 8 & 255, 255 & e, 1);
	}
	function Re(e, t, n, r) {
	  return r <= 0 && (e = t = n = NaN), new _e(e, t, n, r);
	}
	function Ve(e) {
	  return e instanceof ke || (e = He(e)), e ? new _e((e = e.rgb()).r, e.g, e.b, e.opacity) : new _e();
	}
	function $e(e, t, n, r) {
	  return 1 === arguments.length ? Ve(e) : new _e(e, t, n, null == r ? 1 : r);
	}
	function _e(e, t, n, r) {
	  this.r = +e, this.g = +t, this.b = +n, this.opacity = +r;
	}
	function Be() {
	  return `#${Ge(this.r)}${Ge(this.g)}${Ge(this.b)}`;
	}
	function Ke() {
	  const e = Ye(this.opacity);
	  return `${1 === e ? "rgb(" : "rgba("}${Ue(this.r)}, ${Ue(this.g)}, ${Ue(this.b)}${1 === e ? ")" : `, ${e})`}`;
	}
	function Ye(e) {
	  return isNaN(e) ? 1 : Math.max(0, Math.min(1, e));
	}
	function Ue(e) {
	  return Math.max(0, Math.min(255, Math.round(e) || 0));
	}
	function Ge(e) {
	  return ((e = Ue(e)) < 16 ? "0" : "") + e.toString(16);
	}
	function We(e, t, n, r) {
	  return r <= 0 ? e = t = n = NaN : n <= 0 || n >= 1 ? e = t = NaN : t <= 0 && (e = NaN), new Ze(e, t, n, r);
	}
	function Xe(e) {
	  if (e instanceof Ze) return new Ze(e.h, e.s, e.l, e.opacity);
	  if (e instanceof ke || (e = He(e)), !e) return new Ze();
	  if (e instanceof Ze) return e;
	  var t = (e = e.rgb()).r / 255,
	    n = e.g / 255,
	    r = e.b / 255,
	    i = Math.min(t, n, r),
	    o = Math.max(t, n, r),
	    a = NaN,
	    l = o - i,
	    s = (o + i) / 2;
	  return l ? (a = t === o ? (n - r) / l + 6 * (n < r) : n === o ? (r - t) / l + 2 : (t - n) / l + 4, l /= s < .5 ? o + i : 2 - o - i, a *= 60) : l = s > 0 && s < 1 ? 0 : a, new Ze(a, l, s, e.opacity);
	}
	function Ze(e, t, n, r) {
	  this.h = +e, this.s = +t, this.l = +n, this.opacity = +r;
	}
	function Je(e) {
	  return (e = (e || 0) % 360) < 0 ? e + 360 : e;
	}
	function Qe(e) {
	  return Math.max(0, Math.min(1, e || 0));
	}
	function et(e, t, n) {
	  return 255 * (e < 60 ? t + (n - t) * e / 60 : e < 180 ? n : e < 240 ? t + (n - t) * (240 - e) / 60 : t);
	}
	qe(ke, He, {
	  copy(e) {
	    return Object.assign(new this.constructor(), this, e);
	  },
	  displayable() {
	    return this.rgb().displayable();
	  },
	  hex: je,
	  formatHex: je,
	  formatHex8: function () {
	    return this.rgb().formatHex8();
	  },
	  formatHsl: function () {
	    return Xe(this).formatHsl();
	  },
	  formatRgb: Fe,
	  toString: Fe
	}), qe(_e, $e, we(ke, {
	  brighter(e) {
	    return e = null == e ? Me : Math.pow(Me, e), new _e(this.r * e, this.g * e, this.b * e, this.opacity);
	  },
	  darker(e) {
	    return e = null == e ? .7 : Math.pow(.7, e), new _e(this.r * e, this.g * e, this.b * e, this.opacity);
	  },
	  rgb() {
	    return this;
	  },
	  clamp() {
	    return new _e(Ue(this.r), Ue(this.g), Ue(this.b), Ye(this.opacity));
	  },
	  displayable() {
	    return -0.5 <= this.r && this.r < 255.5 && -0.5 <= this.g && this.g < 255.5 && -0.5 <= this.b && this.b < 255.5 && 0 <= this.opacity && this.opacity <= 1;
	  },
	  hex: Be,
	  formatHex: Be,
	  formatHex8: function () {
	    return `#${Ge(this.r)}${Ge(this.g)}${Ge(this.b)}${Ge(255 * (isNaN(this.opacity) ? 1 : this.opacity))}`;
	  },
	  formatRgb: Ke,
	  toString: Ke
	})), qe(Ze, function (e, t, n, r) {
	  return 1 === arguments.length ? Xe(e) : new Ze(e, t, n, null == r ? 1 : r);
	}, we(ke, {
	  brighter(e) {
	    return e = null == e ? Me : Math.pow(Me, e), new Ze(this.h, this.s, this.l * e, this.opacity);
	  },
	  darker(e) {
	    return e = null == e ? .7 : Math.pow(.7, e), new Ze(this.h, this.s, this.l * e, this.opacity);
	  },
	  rgb() {
	    var e = this.h % 360 + 360 * (this.h < 0),
	      t = isNaN(e) || isNaN(this.s) ? 0 : this.s,
	      n = this.l,
	      r = n + (n < .5 ? n : 1 - n) * t,
	      i = 2 * n - r;
	    return new _e(et(e >= 240 ? e - 240 : e + 120, i, r), et(e, i, r), et(e < 120 ? e + 240 : e - 120, i, r), this.opacity);
	  },
	  clamp() {
	    return new Ze(Je(this.h), Qe(this.s), Qe(this.l), Ye(this.opacity));
	  },
	  displayable() {
	    return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && 0 <= this.l && this.l <= 1 && 0 <= this.opacity && this.opacity <= 1;
	  },
	  formatHsl() {
	    const e = Ye(this.opacity);
	    return `${1 === e ? "hsl(" : "hsla("}${Je(this.h)}, ${100 * Qe(this.s)}%, ${100 * Qe(this.l)}%${1 === e ? ")" : `, ${e})`}`;
	  }
	}));
	const tt = Math.PI / 180,
	  nt = 180 / Math.PI,
	  rt = 4 / 29,
	  it = 6 / 29,
	  ot = 3 * it * it;
	function at(e) {
	  if (e instanceof lt) return new lt(e.l, e.a, e.b, e.opacity);
	  if (e instanceof ht) return mt(e);
	  e instanceof _e || (e = Ve(e));
	  var t,
	    n,
	    r = ft(e.r),
	    i = ft(e.g),
	    o = ft(e.b),
	    a = st((.2225045 * r + .7168786 * i + .0606169 * o) / 1);
	  return r === i && i === o ? t = n = a : (t = st((.4360747 * r + .3850649 * i + .1430804 * o) / .96422), n = st((.0139322 * r + .0971045 * i + .7141733 * o) / .82521)), new lt(116 * a - 16, 500 * (t - a), 200 * (a - n), e.opacity);
	}
	function lt(e, t, n, r) {
	  this.l = +e, this.a = +t, this.b = +n, this.opacity = +r;
	}
	function st(e) {
	  return e > .008856451679035631 ? Math.pow(e, 1 / 3) : e / ot + rt;
	}
	function ct(e) {
	  return e > it ? e * e * e : ot * (e - rt);
	}
	function ut(e) {
	  return 255 * (e <= .0031308 ? 12.92 * e : 1.055 * Math.pow(e, 1 / 2.4) - .055);
	}
	function ft(e) {
	  return (e /= 255) <= .04045 ? e / 12.92 : Math.pow((e + .055) / 1.055, 2.4);
	}
	function dt(e) {
	  if (e instanceof ht) return new ht(e.h, e.c, e.l, e.opacity);
	  if (e instanceof lt || (e = at(e)), 0 === e.a && 0 === e.b) return new ht(NaN, 0 < e.l && e.l < 100 ? 0 : NaN, e.l, e.opacity);
	  var t = Math.atan2(e.b, e.a) * nt;
	  return new ht(t < 0 ? t + 360 : t, Math.sqrt(e.a * e.a + e.b * e.b), e.l, e.opacity);
	}
	function pt(e, t, n, r) {
	  return 1 === arguments.length ? dt(e) : new ht(e, t, n, null == r ? 1 : r);
	}
	function ht(e, t, n, r) {
	  this.h = +e, this.c = +t, this.l = +n, this.opacity = +r;
	}
	function mt(e) {
	  if (isNaN(e.h)) return new lt(e.l, 0, 0, e.opacity);
	  var t = e.h * tt;
	  return new lt(e.l, Math.cos(t) * e.c, Math.sin(t) * e.c, e.opacity);
	}
	qe(lt, function (e, t, n, r) {
	  return 1 === arguments.length ? at(e) : new lt(e, t, n, null == r ? 1 : r);
	}, we(ke, {
	  brighter(e) {
	    return new lt(this.l + 18 * (null == e ? 1 : e), this.a, this.b, this.opacity);
	  },
	  darker(e) {
	    return new lt(this.l - 18 * (null == e ? 1 : e), this.a, this.b, this.opacity);
	  },
	  rgb() {
	    var e = (this.l + 16) / 116,
	      t = isNaN(this.a) ? e : e + this.a / 500,
	      n = isNaN(this.b) ? e : e - this.b / 200;
	    return new _e(ut(3.1338561 * (t = .96422 * ct(t)) - 1.6168667 * (e = 1 * ct(e)) - .4906146 * (n = .82521 * ct(n))), ut(-0.9787684 * t + 1.9161415 * e + .033454 * n), ut(.0719453 * t - .2289914 * e + 1.4052427 * n), this.opacity);
	  }
	})), qe(ht, pt, we(ke, {
	  brighter(e) {
	    return new ht(this.h, this.c, this.l + 18 * (null == e ? 1 : e), this.opacity);
	  },
	  darker(e) {
	    return new ht(this.h, this.c, this.l - 18 * (null == e ? 1 : e), this.opacity);
	  },
	  rgb() {
	    return mt(this).rgb();
	  }
	}));
	var vt = -0.14861,
	  gt = 1.78277,
	  yt = -0.29227,
	  bt = -0.90649,
	  xt = 1.97294,
	  qt = xt * bt,
	  wt = xt * gt,
	  kt = gt * yt - bt * vt;
	function Mt(e) {
	  if (e instanceof St) return new St(e.h, e.s, e.l, e.opacity);
	  e instanceof _e || (e = Ve(e));
	  var t = e.r / 255,
	    n = e.g / 255,
	    r = e.b / 255,
	    i = (kt * r + qt * t - wt * n) / (kt + qt - wt),
	    o = r - i,
	    a = (xt * (n - i) - yt * o) / bt,
	    l = Math.sqrt(a * a + o * o) / (xt * i * (1 - i)),
	    s = l ? Math.atan2(a, o) * nt - 120 : NaN;
	  return new St(s < 0 ? s + 360 : s, l, i, e.opacity);
	}
	function Ct(e, t, n, r) {
	  return 1 === arguments.length ? Mt(e) : new St(e, t, n, null == r ? 1 : r);
	}
	function St(e, t, n, r) {
	  this.h = +e, this.s = +t, this.l = +n, this.opacity = +r;
	}
	qe(St, Ct, we(ke, {
	  brighter(e) {
	    return e = null == e ? Me : Math.pow(Me, e), new St(this.h, this.s, this.l * e, this.opacity);
	  },
	  darker(e) {
	    return e = null == e ? .7 : Math.pow(.7, e), new St(this.h, this.s, this.l * e, this.opacity);
	  },
	  rgb() {
	    var e = isNaN(this.h) ? 0 : (this.h + 120) * tt,
	      t = +this.l,
	      n = isNaN(this.s) ? 0 : this.s * t * (1 - t),
	      r = Math.cos(e),
	      i = Math.sin(e);
	    return new _e(255 * (t + n * (vt * r + gt * i)), 255 * (t + n * (yt * r + bt * i)), 255 * (t + n * (xt * r)), this.opacity);
	  }
	}));
	var Dt = e => () => e;
	function Ot(e, t) {
	  return function (n) {
	    return e + n * t;
	  };
	}
	function It(e) {
	  return 1 == (e = +e) ? At : function (t, n) {
	    return n - t ? function (e, t, n) {
	      return e = Math.pow(e, n), t = Math.pow(t, n) - e, n = 1 / n, function (r) {
	        return Math.pow(e + r * t, n);
	      };
	    }(t, n, e) : Dt(isNaN(t) ? n : t);
	  };
	}
	function At(e, t) {
	  var n = t - e;
	  return n ? Ot(e, n) : Dt(isNaN(e) ? t : e);
	}
	(function e(t) {
	  var n = It(t);
	  function r(e, t) {
	    var r = n((e = $e(e)).r, (t = $e(t)).r),
	      i = n(e.g, t.g),
	      o = n(e.b, t.b),
	      a = At(e.opacity, t.opacity);
	    return function (t) {
	      return e.r = r(t), e.g = i(t), e.b = o(t), e.opacity = a(t), e + "";
	    };
	  }
	  return r.gamma = e, r;
	})(1);
	function Tt(e) {
	  return ((e = Math.exp(e)) + 1 / e) / 2;
	}
	function Nt(e) {
	  return function t(n) {
	    function r(t, r) {
	      var i = e((t = Ct(t)).h, (r = Ct(r)).h),
	        o = At(t.s, r.s),
	        a = At(t.l, r.l),
	        l = At(t.opacity, r.opacity);
	      return function (e) {
	        return t.h = i(e), t.s = o(e), t.l = a(Math.pow(e, n)), t.opacity = l(e), t + "";
	      };
	    }
	    return n = +n, r.gamma = t, r;
	  }(1);
	}
	!function e(t, n, r) {
	  function i(e, i) {
	    var o,
	      a,
	      l = e[0],
	      s = e[1],
	      c = e[2],
	      u = i[0],
	      f = i[1],
	      d = i[2],
	      p = u - l,
	      h = f - s,
	      m = p * p + h * h;
	    if (m < 1e-12) a = Math.log(d / c) / t, o = function (e) {
	      return [l + e * p, s + e * h, c * Math.exp(t * e * a)];
	    };else {
	      var v = Math.sqrt(m),
	        g = (d * d - c * c + r * m) / (2 * c * n * v),
	        y = (d * d - c * c - r * m) / (2 * d * n * v),
	        b = Math.log(Math.sqrt(g * g + 1) - g),
	        x = Math.log(Math.sqrt(y * y + 1) - y);
	      a = (x - b) / t, o = function (e) {
	        var r,
	          i = e * a,
	          o = Tt(b),
	          u = c / (n * v) * (o * (r = t * i + b, ((r = Math.exp(2 * r)) - 1) / (r + 1)) - function (e) {
	            return ((e = Math.exp(e)) - 1 / e) / 2;
	          }(b));
	        return [l + u * p, s + u * h, c * o / Tt(t * i + b)];
	      };
	    }
	    return o.duration = 1e3 * a * t / Math.SQRT2, o;
	  }
	  return i.rho = function (t) {
	    var n = Math.max(.001, +t),
	      r = n * n;
	    return e(n, r, r * r);
	  }, i;
	}(Math.SQRT2, 2, 4), Nt(function (e, t) {
	  var n = t - e;
	  return n ? Ot(e, n > 180 || n < -180 ? n - 360 * Math.round(n / 360) : n) : Dt(isNaN(e) ? t : e);
	}), Nt(At);
	var gn = "center",
	  yn = "bottom";
	  [{
	    key: "NoDataExist",
	    alignment: gn,
	    condition: function (e) {
	      var t = e.layoutService;
	      if (!t) return false;
	      var n = t.meta.size;
	      return n.x * n.y == 0;
	    }
	  }, {
	    key: "OnlyNanDataMeasure",
	    translationKey: "OnlyNanData",
	    alignment: gn,
	    condition: function (e) {
	      var t = e.layoutService;
	      return !!t && t.getHyperCubeValue("qMeasureInfo").every(function (e) {
	        return "NaN" === e.qMin && "NaN" === e.qMax;
	      });
	    }
	  }, {
	    key: "OnlyNanDataDimensionContinuous",
	    translationKey: "OnlyNanData",
	    alignment: gn,
	    condition: function (e) {
	      var t = e.layoutService;
	      if (!t) return false;
	      if (!t.meta.isContinuous) return false;
	      var n = t.getHyperCubeValue("qDimensionInfo.0");
	      return n && (n.qMax < n.qMin || "NaN" === n.qMax);
	    }
	  }, {
	    key: "OnlyNegativeOrZeroValues",
	    alignment: gn
	  }, {
	    key: "DataRangeIncludingZero",
	    alignment: yn
	  }, {
	    key: "LimitedData",
	    alignment: yn
	  }, {
	    key: "NegativeOrZeroValues",
	    alignment: yn
	  }].reduce(function (e, t) {
	    return e[t.key] = t, e;
	  }, {});
	function Nn(e, t, n) {
	  if (void 0 === e || void 0 === t) return n;
	  for (var r = t.split("."), i = e, o = 0; o < r.length; ++o) {
	    var a = r[o];
	    if (void 0 === i[a]) return n;
	    i = i[a];
	  }
	  return i;
	}
	var Gn,
	  Wn = {
	    exports: {}
	  };
	var Xn = Gn ? Wn.exports : (Gn = 1, Wn.exports = function () {
	    function e(e, t, n) {
	      return (t = i(t)) in e ? Object.defineProperty(e, t, {
	        value: n,
	        enumerable: true,
	        configurable: true,
	        writable: true
	      }) : e[t] = n, e;
	    }
	    function t(e, t) {
	      var n = Object.keys(e);
	      if (Object.getOwnPropertySymbols) {
	        var r = Object.getOwnPropertySymbols(e);
	        t && (r = r.filter(function (t) {
	          return Object.getOwnPropertyDescriptor(e, t).enumerable;
	        })), n.push.apply(n, r);
	      }
	      return n;
	    }
	    function n(n) {
	      for (var r = 1; r < arguments.length; r++) {
	        var i = null != arguments[r] ? arguments[r] : {};
	        r % 2 ? t(Object(i), true).forEach(function (t) {
	          e(n, t, i[t]);
	        }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(n, Object.getOwnPropertyDescriptors(i)) : t(Object(i)).forEach(function (e) {
	          Object.defineProperty(n, e, Object.getOwnPropertyDescriptor(i, e));
	        });
	      }
	      return n;
	    }
	    function r(e, t) {
	      if ("object" != typeof e || !e) return e;
	      var n = e[Symbol.toPrimitive];
	      if (void 0 !== n) {
	        var r = n.call(e, t);
	        if ("object" != typeof r) return r;
	        throw new TypeError("@@toPrimitive must return a primitive value.");
	      }
	      return ("string" === t ? String : Number)(e);
	    }
	    function i(e) {
	      var t = r(e, "string");
	      return "symbol" == typeof t ? t : t + "";
	    }
	    var o = Object.prototype.hasOwnProperty,
	      a = Object.prototype.toString,
	      l = Object.defineProperty,
	      s = Object.getOwnPropertyDescriptor,
	      c = function (e) {
	        return "function" == typeof Array.isArray ? Array.isArray(e) : "[object Array]" === a.call(e);
	      },
	      u = function (e) {
	        if (!e || "[object Object]" !== a.call(e)) return false;
	        var t,
	          n = o.call(e, "constructor"),
	          r = e.constructor && e.constructor.prototype && o.call(e.constructor.prototype, "isPrototypeOf");
	        if (e.constructor && !n && !r) return false;
	        for (t in e);
	        return void 0 === t || o.call(e, t);
	      },
	      f = function (e, t) {
	        l && "__proto__" === t.name ? l(e, t.name, {
	          enumerable: true,
	          configurable: true,
	          value: t.newValue,
	          writable: true
	        }) : e[t.name] = t.newValue;
	      },
	      d = function (e, t) {
	        if ("__proto__" === t) {
	          if (!o.call(e, t)) return;
	          if (s) return s(e, t).value;
	        }
	        return e[t];
	      },
	      p = function e() {
	        var t,
	          n,
	          r,
	          i,
	          o,
	          a,
	          l = arguments[0],
	          s = 1,
	          p = arguments.length,
	          h = false;
	        for ("boolean" == typeof l && (h = l, l = arguments[1] || {}, s = 2), (null == l || "object" != typeof l && "function" != typeof l) && (l = {}); s < p; ++s) if (null != (t = arguments[s])) for (n in t) r = d(l, n), l !== (i = d(t, n)) && (h && i && (u(i) || (o = c(i))) ? (o ? (o = false, a = r && c(r) ? r : []) : a = r && u(r) ? r : {}, f(l, {
	          name: n,
	          newValue: e(h, a, i)
	        })) : void 0 !== i && f(l, {
	          name: n,
	          newValue: i
	        }));
	        return l;
	      };
	    function h(e, t, n, r) {
	      if (!e) return -1;
	      const i = n.cache,
	        o = e.origin ? e.origin() : null;
	      o && (e = o);
	      let a = i.fields.indexOf(e),
	        l = -1,
	        s = -1;
	      if (-1 === a) for (let t = 0; t < i.wrappedFields.length; t++) if (s = i.wrappedFields[t].attrDims.map(e => e.instance).indexOf(e), l = i.wrappedFields[t].attrExps.map(e => e.instance).indexOf(e), -1 !== s || -1 !== l) {
	        a = t;
	        break;
	      }
	      if (Array.isArray(r) && r.some((e, t) => e !== t)) {
	        const e = r.indexOf(a);
	        -1 !== e && (a = e);
	      }
	      return a -= t.qArea.qLeft, a < 0 || a >= t.qArea.qWidth ? -1 : s >= 0 ? e => e[a].qAttrDims.qValues[s] : l >= 0 ? e => e[a].qAttrExps.qValues[l] : e => e[a];
	    }
	    function m(e, t, n) {
	      let {
	        key: r
	      } = n;
	      const i = {
	        value: "function" == typeof e.value ? e.value(t) : void 0 !== e.value ? e.value : t
	      };
	      return i.label = "function" == typeof e.label ? e.label(t) : void 0 !== e.label ? String(e.label) : String(i.value), e.field && (i.source = {
	        key: r,
	        field: e.field.key()
	      }), i;
	    }
	    function v(e) {
	      let {
	          cache: t,
	          f: n,
	          mainCell: r,
	          p: i,
	          page: a,
	          rowIdx: l,
	          row: s,
	          sourceKey: c,
	          target: u,
	          targetProp: f,
	          columnOrder: d
	        } = e,
	        v = r;
	      if (i.field && i.field !== n) {
	        const e = h(i.field, a, {
	          cache: t
	        }, d);
	        if (-1 === e) return;
	        v = p({
	          qRow: l
	        }, e(s));
	      }
	      u[f] = m(i, v, {
	        key: c
	      });
	    }
	    function g(e, t, n, r) {
	      const i = Array.isArray(e) ? e : [e];
	      let o = [];
	      for (let e = 0; e < i.length; e++) if (void 0 !== i[e].field) {
	        const a = t.raw(),
	          l = t.key(),
	          s = "object" == typeof i[e].field ? i[e].field : t.field(i[e].field),
	          {
	            props: c,
	            main: u
	          } = r.normalizeConfig(i[e], t),
	          f = Object.keys(c),
	          d = !!i[e].trackBy,
	          g = typeof i[e].trackBy,
	          y = {},
	          b = [],
	          x = [];
	        for (let t = 0; t < a.qDataPages.length; t++) {
	          const o = h(s, a.qDataPages[t], {
	            cache: n
	          }, a.qColumnOrder);
	          if (-1 !== o) for (let h = 0; h < a.qDataPages[t].qMatrix.length; h++) {
	            const q = a.qDataPages[t].qArea.qTop + h,
	              w = p({
	                qRow: q
	              }, o(a.qDataPages[t].qMatrix[h])),
	              k = m(u, w, {
	                key: l
	              });
	            if (!u.filter || u.filter(w)) {
	              for (let e = 0; e < f.length; e++) {
	                const r = c[f[e]];
	                let i = r.fields || [r];
	                r.fields && (k[f[e]] = []);
	                for (let o = 0; o < i.length; o++) v({
	                  cache: n,
	                  f: s,
	                  mainCell: w,
	                  p: i[o],
	                  prop: f[e],
	                  page: a.qDataPages[t],
	                  rowIdx: q,
	                  row: a.qDataPages[t].qMatrix[h],
	                  sourceKey: l,
	                  target: r.fields ? k[f[e]] : k,
	                  targetProp: r.fields ? o : f[e],
	                  columnOrder: a.qColumnOrder
	                });
	                if (r.fields) {
	                  const t = k[f[e]].map(e => e.value),
	                    n = k[f[e]].map(e => e.label);
	                  k[f[e]] = {
	                    value: "function" == typeof r.value ? r.value(t) : void 0 !== r.value ? r.value : t,
	                    label: "function" == typeof r.label ? r.label(n) : void 0 !== r.label ? String(r.label) : String(k[f[e]].value)
	                  };
	                }
	              }
	              d && r.track({
	                cfg: i[e],
	                itemData: w,
	                obj: k,
	                target: b,
	                tracker: y,
	                trackType: g
	              }), x.push(k);
	            }
	          }
	        }
	        const q = d ? r.collect(b, {
	          main: u,
	          propsArr: f,
	          props: c
	        }) : x;
	        o = [...o, ...q];
	      }
	      return o;
	    }
	    function y(e) {
	      var t = 0,
	        n = e.children,
	        r = n && n.length;
	      if (r) for (; --r >= 0;) t += n[r].value;else t = 1;
	      e.value = t;
	    }
	    function b() {
	      return this.eachAfter(y);
	    }
	    function x(e, t) {
	      let n = -1;
	      for (const r of this) e.call(t, r, ++n, this);
	      return this;
	    }
	    function q(e, t) {
	      for (var n, r, i = this, o = [i], a = -1; i = o.pop();) if (e.call(t, i, ++a, this), n = i.children) for (r = n.length - 1; r >= 0; --r) o.push(n[r]);
	      return this;
	    }
	    function w(e, t) {
	      for (var n, r, i, o = this, a = [o], l = [], s = -1; o = a.pop();) if (l.push(o), n = o.children) for (r = 0, i = n.length; r < i; ++r) a.push(n[r]);
	      for (; o = l.pop();) e.call(t, o, ++s, this);
	      return this;
	    }
	    function k(e, t) {
	      let n = -1;
	      for (const r of this) if (e.call(t, r, ++n, this)) return r;
	    }
	    function M(e) {
	      return this.eachAfter(function (t) {
	        for (var n = +e(t.data) || 0, r = t.children, i = r && r.length; --i >= 0;) n += r[i].value;
	        t.value = n;
	      });
	    }
	    function C(e) {
	      return this.eachBefore(function (t) {
	        t.children && t.children.sort(e);
	      });
	    }
	    function S(e) {
	      for (var t = this, n = D(t, e), r = [t]; t !== n;) t = t.parent, r.push(t);
	      for (var i = r.length; e !== n;) r.splice(i, 0, e), e = e.parent;
	      return r;
	    }
	    function D(e, t) {
	      if (e === t) return e;
	      var n = e.ancestors(),
	        r = t.ancestors(),
	        i = null;
	      for (e = n.pop(), t = r.pop(); e === t;) i = e, e = n.pop(), t = r.pop();
	      return i;
	    }
	    function O() {
	      for (var e = this, t = [e]; e = e.parent;) t.push(e);
	      return t;
	    }
	    function I() {
	      return Array.from(this);
	    }
	    function A() {
	      var e = [];
	      return this.eachBefore(function (t) {
	        t.children || e.push(t);
	      }), e;
	    }
	    function E() {
	      var e = this,
	        t = [];
	      return e.each(function (n) {
	        n !== e && t.push({
	          source: n.parent,
	          target: n
	        });
	      }), t;
	    }
	    function* T() {
	      var e,
	        t,
	        n,
	        r,
	        i = this,
	        o = [i];
	      do {
	        for (e = o.reverse(), o = []; i = e.pop();) if (yield i, t = i.children) for (n = 0, r = t.length; n < r; ++n) o.push(t[n]);
	      } while (o.length);
	    }
	    function N(e, t) {
	      e instanceof Map ? (e = [void 0, e], void 0 === t && (t = j)) : void 0 === t && (t = P);
	      for (var n, r, i, o, a, l = new z(e), s = [l]; n = s.pop();) if ((i = t(n.data)) && (a = (i = Array.from(i)).length)) for (n.children = i, o = a - 1; o >= 0; --o) s.push(r = i[o] = new z(i[o])), r.parent = n, r.depth = n.depth + 1;
	      return l.eachBefore(H);
	    }
	    function L() {
	      return N(this).eachBefore(F);
	    }
	    function P(e) {
	      return e.children;
	    }
	    function j(e) {
	      return Array.isArray(e) ? e[1] : null;
	    }
	    function F(e) {
	      void 0 !== e.data.value && (e.value = e.data.value), e.data = e.data.data;
	    }
	    function H(e) {
	      var t = 0;
	      do {
	        e.height = t;
	      } while ((e = e.parent) && e.height < ++t);
	    }
	    function z(e) {
	      this.data = e, this.depth = this.height = 0, this.parent = null;
	    }
	    function R(e) {
	      return null == e ? null : V(e);
	    }
	    function V(e) {
	      if ("function" != typeof e) throw new Error();
	      return e;
	    }
	    z.prototype = N.prototype = {
	      constructor: z,
	      count: b,
	      each: x,
	      eachAfter: w,
	      eachBefore: q,
	      find: k,
	      sum: M,
	      sort: C,
	      path: S,
	      ancestors: O,
	      descendants: I,
	      leaves: A,
	      links: E,
	      copy: L,
	      [Symbol.iterator]: T
	    };
	    var $ = {
	        depth: -1
	      },
	      _ = {},
	      B = {};
	    function K(e) {
	      return e.id;
	    }
	    function Y(e) {
	      return e.parentId;
	    }
	    function U() {
	      var e,
	        t = K,
	        n = Y;
	      function r(r) {
	        var i,
	          o,
	          a,
	          l,
	          s,
	          c,
	          u,
	          f,
	          d = Array.from(r),
	          p = t,
	          h = n,
	          m = new Map();
	        if (null != e) {
	          const t = d.map((t, n) => G(e(t, n, r))),
	            n = t.map(W),
	            i = new Set(t).add("");
	          for (const e of n) i.has(e) || (i.add(e), t.push(e), n.push(W(e)), d.push(B));
	          p = (e, n) => t[n], h = (e, t) => n[t];
	        }
	        for (a = 0, i = d.length; a < i; ++a) o = d[a], c = d[a] = new z(o), null != (u = p(o, a, r)) && (u += "") && (f = c.id = u, m.set(f, m.has(f) ? _ : c)), null != (u = h(o, a, r)) && (u += "") && (c.parent = u);
	        for (a = 0; a < i; ++a) if (u = (c = d[a]).parent) {
	          if (!(s = m.get(u))) throw new Error("missing: " + u);
	          if (s === _) throw new Error("ambiguous: " + u);
	          s.children ? s.children.push(c) : s.children = [c], c.parent = s;
	        } else {
	          if (l) throw new Error("multiple roots");
	          l = c;
	        }
	        if (!l) throw new Error("no root");
	        if (null != e) {
	          for (; l.data === B && 1 === l.children.length;) l = l.children[0], --i;
	          for (let e = d.length - 1; e >= 0 && (c = d[e], c.data === B); --e) c.data = null;
	        }
	        if (l.parent = $, l.eachBefore(function (e) {
	          e.depth = e.parent.depth + 1, --i;
	        }).eachBefore(H), l.parent = null, i > 0) throw new Error("cycle");
	        return l;
	      }
	      return r.id = function (e) {
	        return arguments.length ? (t = R(e), r) : t;
	      }, r.parentId = function (e) {
	        return arguments.length ? (n = R(e), r) : n;
	      }, r.path = function (t) {
	        return arguments.length ? (e = R(t), r) : e;
	      }, r;
	    }
	    function G(e) {
	      let t = (e = `${e}`).length;
	      return X(e, t - 1) && !X(e, t - 2) && (e = e.slice(0, -1)), "/" === e[0] ? e : `/${e}`;
	    }
	    function W(e) {
	      let t = e.length;
	      if (t < 2) return "";
	      for (; --t > 1 && !X(e, t););
	      return e.slice(0, t);
	    }
	    function X(e, t) {
	      if ("/" === e[t]) {
	        let n = 0;
	        for (; t > 0 && "\\" === e[--t];) ++n;
	        if (0 == (1 & n)) return true;
	      }
	      return false;
	    }
	    function Z(e, t) {
	      "/" === e.charAt(0) && (e = e.substring(1));
	      const n = e.split("/");
	      let r,
	        i = t;
	      for (let e = 0; e < n.length; e++) {
	        if ("*" === n[e] && Array.isArray(i)) {
	          const t = [];
	          r = n.slice(e + 1).join("/");
	          for (let e = 0; e < i.length; e++) {
	            let n = Z(r, i[e]);
	            Array.isArray(n) ? t.push(...n) : t.push(n);
	          }
	          return t;
	        }
	        if (!n[e] && Array.isArray(i)) {
	          const t = new Array(i.length);
	          r = n.slice(e + 1).join("/");
	          for (let e = 0; e < i.length; e++) t[e] = Z(r, i[e]);
	          return t;
	        }
	        n[e] in i && (i = i[n[e]]);
	      }
	      return i;
	    }
	    function J(e, t, n) {
	      let r = [];
	      if (!e || !e.length) return r;
	      if (t <= 0) {
	        const t = n >= 0 ? [e[n]] : e;
	        r = [...r, ...t];
	      } else for (let i = 0; i < e.length; i++) e[i].children && e[i].children.length && (r = [...r, ...J(e[i].children, t - 1, n)]);
	      return r;
	    }
	    function Q(e, t, n) {
	      if (e === t) return e => e;
	      if (e > t) {
	        const n = Math.max(0, Math.min(100, e - t));
	        return e => {
	          let t = e;
	          for (let e = 0; e < n; ++e) t = t.parent;
	          return t;
	        };
	      }
	      if (t > e) {
	        const r = Math.max(0, Math.min(100, t - e));
	        return e => J(e.children, r - 1, n);
	      }
	      return false;
	    }
	    function ee(e, t) {
	      let {
	        cache: n
	      } = t;
	      if ("number" == typeof e) return n.fields[e];
	      const r = n.allFields;
	      if ("function" == typeof e) {
	        for (let t = 0; t < r.length; t++) if (e(r[t])) return r[t];
	        return false;
	      }
	      if ("string" == typeof e) {
	        for (let t = 0; t < r.length; t++) if (r[t].key() === e || r[t].title() === e) return r[t];
	      } else if (e && -1 !== r.indexOf(e)) return e;
	      throw Error("Field not found: ".concat(e));
	    }
	    const te = /^qDimensionInfo(?:\/(\d+))?/,
	      ne = /^\/?qMeasureInfo\/(\d+)/,
	      re = /\/qAttrExprInfo\/(\d+)/,
	      ie = /\/qAttrDimInfo\/(\d+)/;
	    function oe(e) {
	      const t = e.raw().qColumnOrder,
	        n = e.fields();
	      return t && t.length === n.length ? t : n.map((e, t) => t);
	    }
	    function ae(e) {
	      return (e.qColumnOrder && e.qColumnOrder.length ? e.qColumnOrder : e.qDimensionInfo.map((e, t) => t)).filter(t => t < e.qDimensionInfo.length);
	    }
	    function le(e, t) {
	      let {
	        cube: n
	      } = t;
	      if (!e) return -1;
	      let r = e.origin && e.origin() ? e.origin().key() : e.key(),
	        i = false,
	        o = -1,
	        a = -1,
	        l = -1,
	        s = -1,
	        c = -1,
	        u = -1,
	        f = r;
	      const d = n.qEffectiveInterColumnSortOrder,
	        p = ae(n);
	      return te.test(f) && (i = true, o = +te.exec(f)[1], f = r.replace(te, "")), ne.test(f) && ("K" === n.qMode ? c = +ne.exec(f)[1] : d && -1 !== d.indexOf(-1) ? (c = +ne.exec(f)[1], u = 0) : u = +ne.exec(f)[1], f = f.replace(ne, "")), f && (ie.exec(f) ? l = +ie.exec(f)[1] : re.exec(f) && (a = +re.exec(f)[1])), s = i ? "S" === n.qMode ? p[o] : d ? d.indexOf(o) : o : d && -1 !== d.indexOf(-1) ? d.indexOf(-1) : n.qDimensionInfo.length - ("K" === n.qMode ? 0 : 1), {
	        fieldDepth: s + 1,
	        pseudoMeasureIndex: c,
	        measureIdx: u,
	        attrDimIdx: l,
	        attrIdx: a
	      };
	    }
	    function se(e, t) {
	      let n,
	        r,
	        i = Q(e.fieldDepth, t.fieldDepth, t.pseudoMeasureIndex);
	      return n = t.measureIdx >= 0 ? e => e.data.qValues[t.measureIdx] : e => e.data, t.attrDimIdx >= 0 ? r = e => {
	        var n;
	        return null == e || null === (n = e.qAttrDims) || void 0 === n ? void 0 : n.qValues[t.attrDimIdx];
	      } : t.attrIdx >= 0 && (r = e => {
	        var n;
	        return null == e || null === (n = e.qAttrExps) || void 0 === n ? void 0 : n.qValues[t.attrIdx];
	      }), {
	        nodeFn: i,
	        attrFn: r,
	        valueFn: n
	      };
	    }
	    function ce(e, t, n) {
	      let {
	        key: r
	      } = n;
	      const i = {
	        value: "function" == typeof e.value ? e.value(t) : void 0 !== e.value ? e.value : t
	      };
	      return i.label = "function" == typeof e.label ? e.label(t) : void 0 !== e.label ? String(e.label) : String(i.value), e.field && (i.source = {
	        key: r,
	        field: e.field.key()
	      }), i;
	    }
	    function ue(e) {
	      let {
	        propsArr: t,
	        props: n,
	        item: r,
	        itemData: i,
	        ret: o,
	        sourceKey: a
	      } = e;
	      for (let e = 0; e < t.length; e++) {
	        const l = n[t[e]],
	          s = l.fields || [l];
	        let c, u;
	        l.fields && (c = [], u = []);
	        for (let n = 0; n < s.length; n++) {
	          const f = s[n];
	          let d, p, h, m, v, g;
	          if ("primitive" === f.type ? (h = f.value, g = String(f.value)) : ("function" == typeof f.value && (d = e => f.value(e, r)), "function" == typeof f.label && (p = e => f.label(e, r)), f.accessor ? (m = f.accessor(r), Array.isArray(m) ? (v = m.map(f.valueAccessor), f.attrAccessor && (v = v.map(f.attrAccessor)), d && (h = v.map(d), d = null), p && (g = v.map(p), p = null), h = f.reduce ? f.reduce(h) : h, g = f.reduceLabel ? f.reduceLabel(g, h) : String(h)) : (h = f.attrAccessor ? f.attrAccessor(f.valueAccessor(m)) : f.valueAccessor(m), g = h)) : (h = i, g = i)), l.fields) {
	            const e = d ? d(h) : h;
	            c.push(e), u.push(p && null != g ? p(g) : null != g ? g : String(e));
	          } else {
	            const n = d ? d(h) : h;
	            o[t[e]] = {
	              value: n,
	              label: p ? p(g) : null != g ? g : String(n)
	            }, f.field && (o[t[e]].source = {
	              field: f.field.key(),
	              key: a
	            });
	          }
	        }
	        c && (o[t[e]] = {
	          value: "function" == typeof l.value ? l.value(c, r) : c,
	          label: "function" == typeof l.label ? l.label(u, r) : u
	        });
	      }
	    }
	    const fe = (e, t, n) => {
	      const r = "K" === e.qMode ? "/qStackedDataPages/*/qData" : "/qTreeDataPages/*",
	        i = "K" === e.qMode ? "qSubNodes" : "qNodes",
	        o = Z(r, e);
	      return o && o[0] ? (t.tree = N(o[0], n.children || (e => e[i])), t.tree) : null;
	    };
	    function pe(e) {
	      const t = e.raw().qDataPages.length ? e.raw().qDataPages[0].qMatrix : [],
	        r = oe(e),
	        i = e.fields(),
	        o = e.fields().filter(e => "dimension" === e.type()).map(e => r.indexOf(i.indexOf(e))),
	        a = e.fields().filter(e => "measure" === e.type()).map(e => r.indexOf(i.indexOf(e))),
	        l = {
	          __root: {
	            __id: "__root",
	            qValues: []
	          }
	        };
	      for (let e = 0; e < t.length; e++) {
	        const r = t[e];
	        let i = "__root",
	          c = false;
	        for (let e = 0; e < o.length; e++) {
	          var s;
	          const t = r[o[e]],
	            a = "".concat(i, "__").concat(null !== (s = t.qElemNumber) && void 0 !== s ? s : t.qElemNo);
	          l[a] || (l[a] = n({
	            __id: a,
	            __parent: i,
	            qValues: []
	          }, t), c = true), i = a;
	        }
	        if (c) for (let e = 0; e < a.length; e++) {
	          const t = r[a[e]];
	          l[i].qValues.push(t);
	        }
	      }
	      const c = Object.keys(l).map(e => l[e]);
	      return U().id(e => e.__id).parentId(e => e.__parent)(c);
	    }
	    const he = e => {
	      let {
	        propsArr: t,
	        props: n,
	        cube: r,
	        cache: i,
	        itemDepthObject: o,
	        f: a
	      } = e;
	      for (let e = 0; e < t.length; e++) {
	        const l = n[t[e]],
	          s = l.fields ? l.fields : [l];
	        for (let e = 0; e < s.length; e++) {
	          const t = s[e];
	          if (t.field !== a) {
	            const e = se(o, le(t.field, {
	              cube: r}));
	            t.accessor = e.nodeFn, t.valueAccessor = e.valueFn, t.attrAccessor = e.attrFn;
	          }
	        }
	      }
	    };
	    function me() {
	      let e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
	        t = arguments.length > 1 ? arguments[1] : void 0,
	        r = arguments.length > 2 ? arguments[2] : void 0,
	        i = arguments.length > 3 ? arguments[3] : void 0;
	      const o = t.raw(),
	        a = t.key(),
	        l = "S" === o.qMode ? pe(t) : fe(o, r, e);
	      if (!l) return null;
	      const s = l.height,
	        c = [];
	      for (let a = 0; a <= s; a++) {
	        let l = null;
	        if (a > 0) if ("S" === o.qMode) {
	          let e = ae(o)[a - 1];
	          l = r.fields[e];
	        } else {
	          let e = o.qEffectiveInterColumnSortOrder[a - 1];
	          a > o.qEffectiveInterColumnSortOrder.length && (e = o.qDimensionInfo.length), l = r.fields[e];
	        }
	        const {
	            props: s,
	            main: u
	          } = i.normalizeConfig(n(n({}, e), {}, {
	            field: l ? l.key() : void 0
	          }), t),
	          f = Object.keys(s);
	        c[a] = {
	          propsArr: f,
	          props: s,
	          main: u
	        };
	        const d = l ? le(l, {
	          cube: o}) : {
	          fieldDepth: 0
	        };
	        he({
	          propsArr: f,
	          props: s,
	          cube: o,
	          cache: r,
	          itemDepthObject: d,
	          f: l
	        });
	      }
	      const u = l.copy().descendants(),
	        f = l.descendants();
	      for (let e = 0; e < f.length; e++) {
	        const t = c[f[e].depth].propsArr,
	          n = c[f[e].depth].props,
	          r = c[f[e].depth].main,
	          i = u[e],
	          o = i.data,
	          l = ce(r, o, {
	            key: a
	          });
	        ue({
	          propsArr: t,
	          props: n,
	          item: i,
	          itemData: o,
	          ret: l,
	          sourceKey: a}), f[e].data = l;
	      }
	      return l;
	    }
	    function ve(e, t, n, r) {
	      const i = Array.isArray(e) ? e : [e];
	      let o = [];
	      for (let a = 0; a < i.length; a++) if (void 0 !== i[a].field) {
	        const l = t.raw(),
	          s = t.key();
	        if (!fe(l, n, e)) continue;
	        const c = "object" == typeof i[a].field ? i[a].field : t.field(i[a].field),
	          {
	            props: u,
	            main: f
	          } = r.normalizeConfig(i[a], t),
	          d = Object.keys(u),
	          p = le(c, {
	            cube: l}),
	          {
	            nodeFn: h,
	            attrFn: m,
	            valueFn: v
	          } = se({
	            fieldDepth: 0
	          }, p);
	        he({
	          propsArr: d,
	          props: u,
	          cube: l,
	          cache: n,
	          itemDepthObject: p,
	          f: c
	        });
	        const g = !!i[a].trackBy,
	          y = typeof i[a].trackBy,
	          b = {},
	          x = [],
	          q = h(n.tree),
	          w = [];
	        for (let e = 0; e < q.length; e++) {
	          const t = q[e],
	            n = m ? m(v(t)) : v(t);
	          if (f.filter && !f.filter(n)) continue;
	          const o = ce(f, n, {
	            key: s
	          });
	          ue({
	            propsArr: d,
	            props: u,
	            item: t,
	            itemData: n,
	            ret: o,
	            sourceKey: s
	          }), g && r.track({
	            cfg: i[a],
	            itemData: n,
	            obj: o,
	            target: x,
	            tracker: b,
	            trackType: y
	          }), w.push(o);
	        }
	        const k = g ? r.collect(x, {
	          main: f,
	          propsArr: d,
	          props: u
	        }) : w;
	        o = [...o, ...k];
	      }
	      return o;
	    }
	    function ge(e, t) {
	      return e(t = {
	        exports: {}
	      }, t.exports), t.exports;
	    }
	    var ye = ge(function (e) {
	      var t;
	      t = function () {
	        return function (e, t) {
	          if (!e || isNaN(+t)) return t;
	          var n,
	            r,
	            i,
	            o,
	            a,
	            l,
	            s,
	            c,
	            u,
	            f,
	            d = e.length,
	            p = e.search(/[0-9\-\+#]/),
	            h = p > 0 ? e.substring(0, p) : "",
	            m = e.split("").reverse().join(""),
	            v = m.search(/[0-9\-\+#]/),
	            g = d - v,
	            y = e.substring(g, g + 1),
	            b = g + ("." === y || "," === y ? 1 : 0),
	            x = v > 0 ? e.substring(b, d) : "";
	          if (n = (t = "-" === (e = e.substring(p, b)).charAt(0) ? -t : +t) < 0 ? t = -t : 0, i = (r = e.match(/[^\d\-\+#]/g)) && r[r.length - 1] || ".", o = r && r[1] && r[0] || ",", e = e.split(i), t = +(t = t.toFixed(e[1] && e[1].length)) + "", l = e[1] && e[1].lastIndexOf("0"), (!(c = t.split("."))[1] || c[1] && c[1].length <= l) && (t = (+t).toFixed(l + 1)), u = e[0].split(o), e[0] = u.join(""), (a = e[0] && e[0].indexOf("0")) > -1) for (; c[0].length < e[0].length - a;) c[0] = "0" + c[0];else 0 == +c[0] && (c[0] = "");
	          if ((t = t.split("."))[0] = c[0], s = u[1] && u[u.length - 1].length) {
	            for (m = "", g = (f = t[0]).length % s, d = f.length, b = 0; b < d; b++) m += f.charAt(b), !((b - g + 1) % s) && b < d - s && (m += o);
	            t[0] = m;
	          }
	          return t[1] = e[1] && t[1] ? i + t[1] : "", "0" !== (r = t.join("")) && "" !== r || (n = false), h + (n ? "-" : "") + r + x;
	        };
	      }, e.exports = t();
	    });
	    const be = 1e-15;
	    function xe(e) {
	      return e.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
	    }
	    const qe = {
	        3: "k",
	        6: "M",
	        9: "G",
	        12: "T",
	        15: "P",
	        18: "E",
	        21: "Z",
	        24: "Y",
	        "-3": "m",
	        "-6": "μ",
	        "-9": "n",
	        "-12": "p",
	        "-15": "f",
	        "-18": "a",
	        "-21": "z",
	        "-24": "y"
	      },
	      we = /%\)?$/,
	      ke = /^\(r(0[2-9]|[12]\d|3[0-6])\)/i,
	      Me = /^\(oct\)/i,
	      Ce = /^\(dec\)/i,
	      Se = /^\(hex\)/i,
	      De = /^\(bin\)/i,
	      Oe = /^\(rom\)/i,
	      Ie = /^(\(rom\)|\(bin\)|\(hex\)|\(dec\)|\(oct\)|\(r(0[2-9]|[12]\d|3[0-6])\))/i,
	      Ae = /#|0/g;
	    function Ee(e, t, n, r) {
	      return e = e.toString(t), n[1] === n[1].toUpperCase() && (e = e.toUpperCase()), e.length - e.indexOf(".") > 10 && (e = e.slice(0, e.indexOf(".") + 11)), e.replace(".", r || ".");
	    }
	    function Te(e, t) {
	      let n,
	        r = "",
	        i = Number(String(e).slice(-3)),
	        o = (e - i) / 1e3,
	        a = [0, 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900].reverse(),
	        l = ["0", "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM"].reverse();
	      for (; i > 0;) for (n = 0; n < a.length; n++) if (a[n] <= i) {
	        r += l[n], i -= a[n];
	        break;
	      }
	      for (n = 0; n < o; n++) r = "M".concat(r);
	      return t[1] !== t[1].toUpperCase() && (r = r.toLowerCase()), r;
	    }
	    function Ne(e, t, n) {
	      let r;
	      return ke.test(t) ? e = Ee(e, Number(/\d{2}/.exec(t)[0]), t, n) : Me.test(t) ? e = Ee(e, 8, t, n) : Ce.test(t) ? e = Ee(e, 10, t, n) : Se.test(t) ? e = Ee(e, 16, t, n) : De.test(t) ? e = Ee(e, 2, t, n) : Oe.test(t) && (r = "", e < 0 && (r = "-", e = -e), e = 0 === (e = Math.floor(e)) ? "0" : e <= 5e5 ? r + (e = Te(e, t)) : t + r + e.toExponential(0)), e;
	    }
	    function Le(e, t, n) {
	      const r = xe(e);
	      return n ? r : new RegExp(r || "", t);
	    }
	    function Pe(e, t) {
	      return t && (t = xe(t)), e && (e = xe(e)), new RegExp("(?:[#0]+".concat(e, ")?[#0]+(?:").concat(t, "[#0]+)?"));
	    }
	    function je(e, t) {
	      if (!e || !e.qNumericalAbbreviation) return qe;
	      const n = {};
	      return e.qNumericalAbbreviation.split(t).forEach(e => {
	        let t = e.split(":");
	        2 === t.length && (n[t[0]] = t[1]);
	      }), n;
	    }
	    function Fe(e, t, n, r) {
	      let i,
	        o,
	        a,
	        l,
	        s,
	        c,
	        u,
	        f,
	        d,
	        p = e.pattern;
	      r && (e.abbreviate = true), d = Pe(t, n), a = p.match(d), a = a ? a[0] : "", l = a ? p.substr(0, p.indexOf(a)) : p, s = a ? p.substring(p.indexOf(a) + a.length) : "", a || (a = p ? "#" : "##########"), t && t === n && (i = a.split(n), o = i.pop(), a = i.join("") + n + o, t = ""), c = t, t = /,/.test(n) ? "¤" : ",", c && (a = a.replace(Le(c, "g"), t)), u = n, n = ".", u && (a = a.replace(Le(u, "g"), n)), f = a.match(/#/g), f = f ? f.length : 0;
	      const h = p.split(u);
	      let m;
	      h[1] && (m = h[1].match(Ae)), e.prefix = l || "", e.postfix = s || "", e.pattern = p, e.maxPrecision = m ? m.length : 2, e.percentage = we.test(p), e.numericPattern = a || "", e.numericRegex = new RegExp("".concat(Le(t, null, true), "|").concat(Le(n, null, true)), "g"), e.groupTemp = c, e.decTemp = u, e.t = t, e.d = n, e.temp = f;
	    }
	    class He {
	      constructor(e, t, n, r, i) {
	        this.localeInfo = e, this.pattern = t, this.thousandDelimiter = n || ",", this.decimalDelimiter = r || ".", this.type = i || "numeric", this.patternSeparator = ";", this.abbreviations = je(e, this.patternSeparator), this.prepare();
	      }
	      clone() {
	        const e = new He(this.localeInfo, this.pattern, this.thousandDelimiter, this.decimalDelimiter, this.type);
	        return e.subtype = this.subtype, e;
	      }
	      format(e, t, n, r) {
	        return this.prepare(t, n, r), this.formatValue(e);
	      }
	      prepare(e, t, n) {
	        let r;
	        if (void 0 === e && (e = this.pattern), void 0 === t && (t = this.thousandDelimiter), void 0 === n && (n = this.decimalDelimiter), !e) return void (this._prepared = {
	          pattern: false
	        });
	        this._prepared = {
	          positive: {
	            d: n,
	            t: t,
	            abbreviate: false,
	            isFunctional: false,
	            prefix: "",
	            postfix: ""
	          },
	          negative: {
	            d: n,
	            t: t,
	            abbreviate: false,
	            isFunctional: false,
	            prefix: "",
	            postfix: ""
	          },
	          zero: {
	            d: n,
	            t: t,
	            abbreviate: false,
	            isFunctional: false,
	            prefix: "",
	            postfix: ""
	          }
	        }, r = this._prepared, e = e.split(this.patternSeparator), r.positive.pattern = e[0], r.negative.pattern = e[1], r.zero.pattern = e[2], Ie.test(e[0]) && (r.positive.isFunctional = true), e[1] ? Ie.test(e[1]) && (r.negative.isFunctional = true) : r.negative = false, e[2] ? Ie.test(e[2]) && (r.zero.isFunctional = true) : r.zero = false;
	        const i = "U" === this.type;
	        r.positive.isFunctional || Fe(r.positive, t, n, i), r.negative && !r.negative.isFunctional && Fe(r.negative, t, n, i), r.zero && !r.zero.isFunctional && Fe(r.zero, t, n, i);
	      }
	      formatValue(e) {
	        let t,
	          n,
	          r,
	          i,
	          o,
	          a,
	          l,
	          s,
	          c,
	          u = this._prepared,
	          f = "",
	          d = "",
	          p = e;
	        if (isNaN(e)) return "".concat(p);
	        if (e = +e, false === u.pattern) return e.toString();
	        if (0 === e && u.zero) return u = u.zero, u.pattern;
	        if (e < 0 && u.negative ? (u = u.negative, e = -e) : u = u.positive, o = u.d, a = u.t, u.isFunctional) e = Ne(e, u.pattern, o);else {
	          if (u.percentage && (e *= 100), u.abbreviate) {
	            const t = Object.keys(this.abbreviations).map(e => parseInt(e, 10)).sort((e, t) => e - t);
	            let r,
	              i,
	              o = t[0];
	            for (l = 0, n = Number(Number(e).toExponential().split("e")[1]); o <= n && l < t.length;) l++, o = t[l];
	            l > 0 && (r = t[l - 1]), r && n > 0 && r > 0 ? i = r : (n < 0 && r < 0 || !r) && (o < 0 && o - n <= u.maxPrecision ? i = o : r <= n && !(o > 0 && -n <= u.maxPrecision) && (i = r)), i && (f = this.abbreviations[i], e /= 10 ** i);
	          }
	          if (r = Math.abs(e), t = u.temp, s = u.numericPattern, c = s.split(o)[1], "I" === this.type && (e = Math.round(e)), i = e, c || "#" !== s.slice(-1)[0]) {
	            if (r >= 1e15 || r > 0 && r <= 1e-14) e = r ? r.toExponential(15).replace(/\.?0+(?=e)/, "") : "0";else {
	              const t = Number((e + be * (e < 0 ? -1 : 1)).toFixed(Math.min(20, c ? c.length : 0)).split(".")[0]);
	              let n = s.split(o)[0];
	              if (n += o, e = ye(n, t) || "0", c) {
	                const t = Math.max(0, Math.min(14, c.length)),
	                  n = c.replace(/#+$/, "").length;
	                let i = ("I" === this.type ? 0 : r % 1 + be).toFixed(t).slice(2).replace(/0+$/, "");
	                for (l = i.length; l < n; l++) i += "0";
	                i && (e += o + i);
	              } else 0 === t && (i = 0);
	            }
	          } else if (r >= 10 ** t || r < 1 || r < 1e-4) 0 === e ? e = "0" : r < 1e-4 || r >= 1e20 ? (e = (e = i.toExponential(Math.max(1, Math.min(14, t)) - 1)).replace(/\.?0+(?=e)/, ""), d = "") : (e = e.toPrecision(Math.max(1, Math.min(14, t)))).indexOf(".") >= 0 && (e = (e = e.replace(e.indexOf("e") < 0 ? /0+$/ : /\.?0+(?=e)/, "")).replace(".", o));else {
	            for (s += o, t = Math.max(0, Math.min(20, t - Math.ceil(Math.log(r) / Math.log(10)))), l = 0; l < t; l++) s += "#";
	            e = ye(s, e);
	          }
	          e = e.replace(u.numericRegex, e => e === a ? u.groupTemp : e === o ? u.decTemp : ""), i < 0 && !/^-/.test(e) && (e = "-".concat(e));
	        }
	        return u.prefix + e + d + f + u.postfix;
	      }
	      static getStaticFormatter() {
	        return {
	          prepare() {},
	          formatValue: e => "".concat(e)
	        };
	      }
	    }
	    function ze() {
	      for (var e = arguments.length, t = new Array(e), n = 0; n < e; n++) t[n] = arguments[n];
	      return new He(...t);
	    }
	    function Re(e) {
	      let t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
	      const {
	        size: n = 5e3,
	        multipleArguments: r = false,
	        toKey: i = e => e
	      } = t;
	      let o,
	        a,
	        l = Object.create(null),
	        s = Object.create(null),
	        c = 0,
	        u = 0;
	      return o = r ? function () {
	        return a = i(...arguments), o.has(a) ? o.get(a) : o.set(a, e(...arguments));
	      } : t => (a = i(t), o.has(a) ? o.get(a) : o.set(a, e(t))), o.set = (e, t) => (c >= n && (delete l[s[u]], delete s[u], c--, u++), l[e] = t, s[c] = e, c++, t), o.get = e => l[e], o.has = e => e in l, o.clear = () => {
	        l = Object.create(null), s = Object.create(null), c = 0, u = 0;
	      }, o.size = () => c, o;
	    }
	    function Ve(e, t, n, r, i) {
	      const o = ze(i, e, t, n, r),
	        a = Re(o.formatValue.bind(o), {
	          toKey: e => isNaN(e) ? e : +e
	        });
	      function l(e) {
	        return a(e);
	      }
	      return l.format = function (e, t, n, r) {
	        return a.clear(), o.format(t, e, n, r);
	      }, l.pattern = function (e) {
	        return e && (a.clear(), o.pattern = e, o.prepare()), o.pattern;
	      }, l;
	    }
	    const $e = {
	        DATE: "D",
	        TIME: "T",
	        DATE_TIME: "TS",
	        INTERVAL: "IV"
	      },
	      _e = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
	      Be = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
	      Ke = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
	      Ye = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
	      Ue = 86400;
	    function Ge(e, t) {
	      for (let n = e.length; n < t; n++) e = "0".concat(e);
	      return e;
	    }
	    function We(e, t) {
	      let n = e.getUTCHours(),
	        r = e.getUTCDay() - 1;
	      return t && (n %= 12, n || (n = 12)), r < 0 && (r = 6), {
	        year: e.getUTCFullYear(),
	        month: e.getUTCMonth(),
	        day: r,
	        date: e.getUTCDate(),
	        h: n,
	        m: e.getUTCMinutes(),
	        s: e.getUTCSeconds(),
	        f: e.getUTCMilliseconds(),
	        t: e.getUTCHours() >= 12 ? "pm" : "am"
	      };
	    }
	    function Xe(e) {
	      let t = e.toString().split(".");
	      return t[1] ? (t = Number("0.".concat(t[1])), t) : 0;
	    }
	    function Ze(e) {
	      const t = e,
	        n = 24 * Xe(t),
	        r = 60 * Xe(n),
	        i = 60 * Xe(r),
	        o = 1e3 * Xe(i);
	      return {
	        d: Math.floor(t),
	        h: Math.floor(n),
	        m: Math.floor(r),
	        s: Math.floor(i),
	        f: Math.round(o)
	      };
	    }
	    function Je(e, t) {
	      let n,
	        r = Ze(e),
	        i = r.d,
	        o = r.h,
	        a = r.m,
	        l = r.s,
	        s = r.f,
	        c = 0;
	      /w+|t+/gi.test(t) && (n = new Date(Date.UTC(1899, 11, 30 + Math.floor(e), 0, 0, Math.round(Ue * (e - Math.floor(e))))), isNaN(n.getTime()) && (n = null)), /D+/gi.test(t) || (o += 24 * i), /h+/gi.test(t) || (a += 60 * o), /m+/gi.test(t) || (l += 60 * a), /w+/gi.test(t) && (c = n ? n.getDay() - 1 : 0, c < 0 && (c = 6));
	      let u = "";
	      return n && (u = n.getUTCHours() >= 12 ? "pm" : "am"), {
	        year: 0,
	        month: 0,
	        day: c,
	        date: i,
	        h: o,
	        m: a,
	        s: l,
	        f: s,
	        t: u
	      };
	    }
	    function Qe(e, t) {
	      return {
	        "Y+|y+": {
	          Y: "".concat(Number("".concat(t.year).slice(-2))),
	          YY: Ge("".concat(t.year).slice(-2), 2),
	          YYY: Ge("".concat(t.year).slice(-3), 3),
	          def: e => Ge("".concat(t.year), e.length)
	        },
	        "M+": {
	          M: t.month + 1,
	          MM: Ge("".concat(t.month + 1), 2),
	          MMM: e.locale_months_abbr[t.month],
	          def: e.locale_months[t.month]
	        },
	        "W+|w+": {
	          W: t.day,
	          WW: Ge("".concat(t.day), 2),
	          WWW: e.locale_days_abbr[t.day],
	          def: e.locale_days[t.day]
	        },
	        "D+|d+": {
	          D: t.date,
	          def: e => Ge("".concat(t.date), e.length)
	        },
	        "h+|H+": {
	          h: t.h,
	          def: e => Ge("".concat(t.h), e.length)
	        },
	        "m+": {
	          m: t.m,
	          def: e => Ge("".concat(t.m), e.length)
	        },
	        "s+|S+": {
	          s: t.s,
	          def: e => Ge("".concat(t.s), e.length)
	        },
	        "f+|F+": {
	          def(e) {
	            let n = "".concat(t.f),
	              r = e.length - n.length;
	            if (r > 0) for (let e = 0; e < r; e++) n += "0";else r < 0 && (n = n.slice(0, e.length));
	            return n;
	          }
	        },
	        "t{1,2}|T{1,2}": {
	          def(e) {
	            let n = t.t;
	            return e[0].toUpperCase() === e[0] && (n = n.toUpperCase()), n = n.slice(0, e.length), n;
	          }
	        }
	      };
	    }
	    class et {
	      constructor(e, t, n) {
	        const r = e || {};
	        r.qCalendarStrings || (r.qCalendarStrings = {
	          qLongDayNames: _e,
	          qDayNames: Be,
	          qLongMonthNames: Ke,
	          qMonthNames: Ye
	        }), this.localeInfo = r, this.locale_days = r.qCalendarStrings.qLongDayNames.slice(), this.locale_days_abbr = r.qCalendarStrings.qDayNames.slice(), this.locale_months = r.qCalendarStrings.qLongMonthNames.slice(), this.locale_months_abbr = r.qCalendarStrings.qMonthNames.slice(), t || (t = {
	          [$e.TIME]: r.qTimeFmt || "hh:mm:ss",
	          [$e.DATE]: r.qDateFmt || "YYYY-MM-DD",
	          [$e.DATE_TIME]: r.qTimestampFmt || "YYYY-MM-DD hh:mm:ss"
	        }[n]), this.pattern = t;
	      }
	      clone() {
	        const e = new et(this.localeInfo, this.pattern);
	        return e.subtype = this.subtype, e;
	      }
	      format(e, t) {
	        t || (t = this.pattern ? this.pattern : "YYYY-MM-DD hh:mm:ss"), t = t.replace(/\[.+]|\[|]/g, "");
	        const n = /t+/gi.test(t);
	        let r;
	        e instanceof Date ? r = We(e, n) : (e < 0 && (e = -e, t = "-".concat(t)), r = Je(e, t));
	        const i = Qe(this, r),
	          o = [];
	        for (const e in i) Object.prototype.hasOwnProperty.call(i, e) && o.push(e);
	        const a = new RegExp(o.join("|"), "g");
	        return t.replace(a, e => {
	          let t, n, r;
	          for (n in i) if (Object.prototype.hasOwnProperty.call(i, n) && (t = new RegExp(n), t.test(e))) break;
	          if (!t) return "";
	          for (const t in i[n]) if (t === e || t.toLowerCase() === e) {
	            r = i[n][t], void 0 === r && (r = i[n][t.toLowerCase()]);
	            break;
	          }
	          return void 0 === r && (r = i[n].def), "function" == typeof r && (r = r(e)), r;
	        });
	      }
	    }
	    function tt() {
	      for (var e = arguments.length, t = new Array(e), n = 0; n < e; n++) t[n] = arguments[n];
	      return new et(...t);
	    }
	    const nt = 864e5;
	    function rt(e) {
	      return new Date(Date.UTC(1899, 11, 30 + Math.floor(e), 0, 0, 0, Math.round(nt * (e - Math.floor(e)))));
	    }
	    function it(e) {
	      let t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "TS",
	        n = tt(arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : null, e, t),
	        r = Re(n.format.bind(n), {
	          toKey: e => "object" == typeof e && "function" == typeof e.getTime ? e.getTime() : e
	        });
	      function i(e) {
	        return t !== $e.INTERVAL ? rt(e) : e;
	      }
	      function o(e) {
	        return e = i(e), r(e);
	      }
	      return o.format = function (e, t) {
	        return r.clear(), t = i(t), n.format(t, e);
	      }, o.locale = function (i) {
	        return n = tt(i, e, t), r = Re(n.format.bind(n), {
	          toKey: e => "object" == typeof e ? e.getTime() : e
	        }), this;
	      }, o.qtype = function (e) {
	        return void 0 !== e && (t = e, r.clear()), t;
	      }, o;
	    }
	    function ot(e, t) {
	      if (e && e.qNumFormat && -1 !== ["D", "T", "TS", "IV"].indexOf(e.qNumFormat.qType)) return it(e.qNumFormat.qFmt, e.qNumFormat.qType, t);
	      let n = "#",
	        r = t && void 0 !== t.qThousandSep ? t.qThousandSep : ",",
	        i = t && void 0 !== t.qDecimalSep ? t.qDecimalSep : ".",
	        o = "U",
	        a = e && !!e.qIsAutoFormat;
	      return e && e.qNumFormat ? (n = e.qNumFormat.qFmt || n, r = e.qNumFormat.qThou || r, i = e.qNumFormat.qDec || i, o = e.qNumFormat.qType || o, a = a && -1 === ["M"].indexOf(e.qNumFormat.qType)) : a = true, (a || "U" === o) && (n = "#".concat(i, "##"), o = "U"), Ve(n, r, i, o, t);
	    }
	    function at() {
	      let e,
	        {
	          meta: t,
	          id: n,
	          key: r,
	          localeInfo: i,
	          fieldExtractor: o,
	          value: a,
	          type: l,
	          sourceField: s
	        } = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
	      const c = a || ("dimension" === l ? e => null == e ? void 0 : e.qElemNo : e => null == e ? void 0 : e.qValue),
	        u = e => (null == e ? void 0 : e.qText) || "",
	        f = "dimension" === l ? "first" : "avg",
	        d = ot(t, i),
	        p = {
	          id: () => n,
	          key: () => r,
	          raw: () => t,
	          title: () => t.qFallbackTitle || t.label,
	          type: () => l,
	          origin: () => s,
	          items: () => (e || (e = o(p)), e),
	          min: () => t.qMin,
	          max: () => t.qMax,
	          value: c,
	          label: u,
	          reduce: f,
	          reduceLabel: "dimension" === l ? "first" : (e, t) => d(t),
	          formatter: () => d,
	          tags: () => t.qTags
	        };
	      return p;
	    }
	    function lt(e, t, n, r, i) {
	      return (t[e] || []).map((t, o) => {
	        const a = "".concat(r ? "".concat(r, "/") : "").concat(e, "/").concat(o),
	          l = {
	            instance: at(p({
	              id: "".concat(n ? "".concat(n, "/") : "").concat(a),
	              key: a,
	              meta: t
	            }, i))
	          };
	        return l.attrDims = lt("qAttrDimInfo", t, n, a, p({}, i, {
	          value: e => null == e ? void 0 : e.qElemNo,
	          type: "dimension"
	        })), l.attrExps = lt("qAttrExprInfo", t, n, a, p({}, i, {
	          value: e => null == e ? void 0 : e.qNum,
	          type: "measure"
	        })), l.measures = lt("qMeasureInfo", t, n, a, p({}, i, {
	          value: e => null == e ? void 0 : e.qValue,
	          type: "measure"
	        })), l;
	      });
	    }
	    function st() {
	      let {
	        key: e,
	        data: t,
	        config: r = {}
	      } = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
	      const i = {
	          fields: [],
	          wrappedFields: [],
	          allFields: [],
	          virtualFields: []
	        },
	        o = t;
	      if (!o) throw new Error('Missing "data" input');
	      if (!o.qDimensionInfo) throw new Error('The "data" input is not recognized as a hypercube');
	      const a = st.util,
	        l = {
	          cache: i,
	          cube: o,
	          localeInfo: r.localeInfo,
	          fieldExtractor: null,
	          pages: null,
	          hierarchy: () => null,
	          virtualFields: r.virtualFields
	        },
	        s = {
	          key: () => e,
	          raw: () => o,
	          field: e => ee(e, l),
	          fields: () => i.fields.slice(),
	          extract: e => l.extractor(e, s, i, a),
	          hierarchy: e => l.hierarchy(e, s, i, a),
	          _cache: () => i
	        };
	      "K" === o.qMode || "T" === o.qMode || !o.qMode && o.qNodesOnDim ? (l.extractor = ve, l.hierarchy = me, l.pages = "K" === o.qMode ? o.qStackedDataPages : o.qTreeDataPages) : "S" === o.qMode ? (l.extractor = g, l.pages = o.qDataPages, l.hierarchy = me) : l.extractor = () => [], l.fieldExtractor = e => l.extractor({
	        field: e
	      }, s, i, a);
	      const c = "S" === o.qMode ? e => e.qElemNumber : void 0,
	        u = "S" === o.qMode ? e => e.qNum : void 0;
	      i.wrappedFields.push(...lt("qDimensionInfo", o, e, "", p({}, l, {
	        value: c,
	        type: "dimension"
	      }))), i.wrappedFields.push(...lt("qMeasureInfo", o, e, "", p({}, l, {
	        value: u,
	        type: "measure"
	      }))), i.fields = i.wrappedFields.map(e => e.instance);
	      const f = e => {
	        e.forEach(e => {
	          i.allFields.push(e.instance), f(e.measures), f(e.attrDims), f(e.attrExps);
	        });
	      };
	      return f(i.wrappedFields), (r.virtualFields || []).forEach(t => {
	        const r = s.field(t.from),
	          o = at(n({
	            meta: r.raw(),
	            id: "".concat(e, "/").concat(t.key),
	            sourceField: r,
	            fieldExtractor: e => l.extractor({
	              field: e
	            }, s, i, a),
	            key: t.key,
	            type: r.type(),
	            localeInfo: l.localeInfo,
	            value: r.value
	          }, t.override || {}));
	        i.virtualFields.push(o);
	      }), i.allFields.push(...i.virtualFields), s;
	    }
	    const ct = [["qHyperCube", "qHyperCubeDef"], ["qTreeData", "qTreeDataDef"], ["qDimensionInfo", "qDimensions"], ["qMeasureInfo", "qMeasures"], ["qAttrDimInfo", "qAttributeDimensions"], ["qAttrExprInfo", "qAttributeExpressions"]],
	      ut = /\/qDimensionInfo(?:\/(\d+))?/,
	      ft = /\/qMeasureInfo\/(\d+)/,
	      dt = /\/qAttrDimInfo\/(\d+)(?:\/(\d+))?/,
	      pt = /\/qAttrExprInfo\/(\d+)/,
	      ht = /\/?qHyperCube/,
	      mt = /\/?qTreeData/,
	      vt = e => "".concat(e.substr(0, e.indexOf("/qHyperCubeDef") + 14)),
	      gt = e => "".concat(e.substr(0, e.indexOf("/qTreeDataDef") + 13));
	    function yt(e, t) {
	      let n = e,
	        r = -1,
	        i = -1,
	        o = "",
	        a = e => e;
	      ht.test(e) ? (o = "".concat(n.substr(0, n.indexOf("qHyperCube") + 10)), a = vt) : mt.test(e) && (o = "".concat(n.substr(0, n.indexOf("qTreeData") + 9)), a = gt);
	      let l = true;
	      if (ut.test(e) && (r = +ut.exec(e)[1]), ft.test(e) && (i = +ft.exec(e)[1]), dt.test(e)) {
	        i = -1, r = 0;
	        const e = +dt.exec(n)[2];
	        isNaN(e) || (r = e, n = n.replace(/\/\d+$/, "")), l = false;
	      }
	      if (pt.test(e)) {
	        const e = i;
	        if (t) {
	          i = 0;
	          const a = Z(o, t);
	          i += (a.qMeasureInfo || []).length, r > -1 ? (i = a.qDimensionInfo.slice(0, r).reduce((e, t) => e + t.qAttrExprInfo.length, i), r = -1) : (i = a.qDimensionInfo.reduce((e, t) => e + t.qAttrExprInfo.length, i), i = a.qMeasureInfo.slice(0, e).reduce((e, t) => e + t.qAttrExprInfo.length, i)), i += +pt.exec(n)[1];
	        } else r > -1 ? (r = -1, i = +pt.exec(n)[1]) : i += +pt.exec(n)[1] + 1;
	      }
	      return ct.forEach(e => {
	        let [t, r] = e;
	        n = n.replace(t, r);
	      }), l && (n = a(n)), n && "/" !== n[0] && (n = "/".concat(n)), {
	        measureIdx: i,
	        dimensionIdx: r,
	        path: n
	      };
	    }
	    function bt(e) {
	      let t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
	        n = arguments.length > 2 ? arguments[2] : void 0;
	      const r = t.byCells,
	        i = t.primarySource,
	        o = [],
	        a = {},
	        l = e.isActive();
	      let s = false;
	      return e.brushes().forEach(e => {
	        const t = yt(e.id, n);
	        if ("range" === e.type && t.measureIdx > -1 && t.dimensionIdx > -1) {
	          const n = e.brush.ranges();
	          n.length && (s = true, a.multiRangeSelectTreeDataValues || (a.multiRangeSelectTreeDataValues = {
	            path: t.path,
	            ranges: []
	          }), n.forEach(e => a.multiRangeSelectTreeDataValues.ranges.push({
	            qMeasureIx: t.measureIdx,
	            qDimensionIx: t.dimensionIdx,
	            qRange: {
	              qMin: e.min,
	              qMax: e.max,
	              qMinInclEq: true,
	              qMaxInclEq: true
	            }
	          })));
	        } else {
	          if ("range" === e.type && t.measureIdx > -1) {
	            const n = e.brush.ranges();
	            n.length && (s = true, a.rangeSelectHyperCubeValues || (a.rangeSelectHyperCubeValues = {
	              path: t.path,
	              ranges: []
	            }), n.forEach(e => a.rangeSelectHyperCubeValues.ranges.push({
	              qMeasureIx: t.measureIdx,
	              qRange: {
	                qMin: e.min,
	                qMax: e.max,
	                qMinInclEq: true,
	                qMaxInclEq: true
	              }
	            })));
	          }
	          if ("range" === e.type && t.dimensionIdx > -1) {
	            const n = e.brush.ranges();
	            n.length && (s = true, a.selectHyperCubeContinuousRange || (a.selectHyperCubeContinuousRange = {
	              path: t.path,
	              ranges: []
	            }), n.forEach(e => a.selectHyperCubeContinuousRange.ranges.push({
	              qDimIx: t.dimensionIdx,
	              qRange: {
	                qMin: e.min,
	                qMax: e.max,
	                qMinInclEq: true,
	                qMaxInclEq: false
	              }
	            })));
	          }
	          if ("value" === e.type && t.dimensionIdx > -1) if (r) {
	            if (n && n.qHyperCube && ("P" === n.qHyperCube.qMode || "T" === n.qHyperCube.qMode || "K" === n.qHyperCube.qMode)) {
	              const r = n.qHyperCube,
	                o = r.qNoOfLeftDims,
	                l = r.qEffectiveInterColumnSortOrder.indexOf(t.dimensionIdx);
	              if (a.selectPivotCells || (a.selectPivotCells = {
	                path: t.path,
	                cells: []
	              }), e.id === i || !i) {
	                const n = e.brush.values().map(e => +e).filter(e => !isNaN(e));
	                (0 === o || l >= o) && o > -1 ? n.forEach(e => {
	                  a.selectPivotCells.cells.push({
	                    qType: "T",
	                    qCol: e,
	                    qRow: l - o
	                  });
	                }) : n.forEach(e => {
	                  a.selectPivotCells.cells.push({
	                    qType: "L",
	                    qCol: t.dimensionIdx,
	                    qRow: e
	                  });
	                }), s = !!a.selectPivotCells.cells.length;
	              }
	            } else a.selectHyperCubeCells || (a.selectHyperCubeCells = {
	              path: t.path,
	              cols: []
	            }), a.selectHyperCubeCells.cols.push(t.dimensionIdx), e.id !== i && (i || a.selectHyperCubeCells.values) || (a.selectHyperCubeCells.values = e.brush.values().map(e => +e).filter(e => !isNaN(e)), s = !!a.selectHyperCubeCells.values.length);
	          } else {
	            const n = e.brush.values().map(e => +e).filter(e => !isNaN(e));
	            s = !!n.length, o.push({
	              params: [t.path, t.dimensionIdx, n, false],
	              method: "selectHyperCubeValues"
	            });
	          }
	        }
	      }), !s && l ? [{
	        method: "resetMadeSelections",
	        params: []
	      }] : (a.rangeSelectHyperCubeValues && o.push({
	        method: "rangeSelectHyperCubeValues",
	        params: [a.rangeSelectHyperCubeValues.path, a.rangeSelectHyperCubeValues.ranges, [], null === (c = t.orMode) || void 0 === c || c]
	      }), a.selectHyperCubeContinuousRange && o.push({
	        method: "selectHyperCubeContinuousRange",
	        params: [a.selectHyperCubeContinuousRange.path, a.selectHyperCubeContinuousRange.ranges]
	      }), a.selectHyperCubeCells && o.push({
	        method: "selectHyperCubeCells",
	        params: [a.selectHyperCubeCells.path, a.selectHyperCubeCells.values, a.selectHyperCubeCells.cols]
	      }), a.selectPivotCells && o.push({
	        method: "selectPivotCells",
	        params: [a.selectPivotCells.path, a.selectPivotCells.cells]
	      }), a.multiRangeSelectTreeDataValues && o.push({
	        method: "multiRangeSelectTreeDataValues",
	        params: [a.multiRangeSelectTreeDataValues.path, a.multiRangeSelectTreeDataValues.ranges]
	      }), o);
	      var c;
	    }
	    function xt(e) {
	      st.util = e.data("matrix").util, e.data("q", st), e.formatter("q-number", Ve), e.formatter("q-time", it);
	    }
	    return xt.qBrushHelper = bt, xt.selections = bt, xt;
	  }());
	  pe(Xn);

	/* eslint-disable prefer-rest-params */
	/* eslint-disable guard-for-in */
	/* eslint-disable no-restricted-syntax */

	/* Simple JavaScript Inheritance
	 * By John Resig http://ejohn.org/
	 * MIT Licensed.
	 * Modified by Qliktech
	 */
	// Inspired by base2 and Prototype

	/* eslint no-new-func:0,no-unused-vars:0 */

	const fnTest = /xyz/.test(() => {
	}) ? /\b_super\b/ : /.*/;

	/**
	 * Helper module for creating subclasses (or rather prototypal inheritance) of superclasses.
	 *
	 * @class
	 *
	 * @example
	 * var Animal = Class.extend( "Animal", {
	 *   init: function ( name ) {
	 *     this.name = name || "Unnamed";
	 *   },
	 *   say: function ( sound ) {
	 *     console.log( this.name + " says " + sound );
	 *   }
	 * } );
	 *
	 * var Cat = Animal.extend( "Cat", {
	 *   say: function () {
	 *     this._super( "Meouw" );
	 *   }
	 * } );
	 *
	 * var cat = new Cat( "Gustaf" );
	 * cat.say(); => "Gustaf says Meouw"
	 *
	 * @example
	 * var MyClass = Class.extend();
	 *
	 * var a = new MyClass();
	 * console.log( a instanceof MyClass ) // => true
	 * console.log( a.constructor.name ) // => Class
	 *
	 * @example
	 * var MyClass = Class.extend( "MyClass" );
	 *
	 * var a = new MyClass();
	 * console.log( a instanceof MyClass ) // => true
	 * console.log( a.constructor.name ) // => MyClass
	 *
	 */
	const Class = function () {};

	/**
	 * This method is available inside each function defined on the prototype when using {@link module:assets/core/utils/class~Class.extend}.
	 *
	 * It will invoke the super class' method with the same name, but it's up to programmer to invoke it with the arguments needed.
	 * @method module:assets/core/utils/class~Class#_super
	 */

	/**
	 * Create a new Class that inherits from this class
	 * @param {String} [className="Class"] The name of the new class constructor.
	 * @param {Object} proto The prototype for the new class.
	 */
	Class.extend = function extend(className, proto) {
	  const _super = this.prototype;
	  if (typeof className !== 'string') {
	    proto = className;
	    className = 'Class';
	  }

	  // Instantiate a base class (but only create the instance,
	  // don't run the init constructor)
	  const prototype = Object.create(this.prototype);

	  // Copy the properties over onto the new prototype
	  for (const name in proto) {
	    // Check if we're overwriting an existing function
	    prototype[name] = typeof proto[name] === 'function' && typeof _super[name] === 'function' && fnTest.test(proto[name]) ? function (name, fn) {
	      return function () {
	        const tmp = this._super;

	        // Add a new ._super() method that is the same method
	        // but on the super-class
	        this._super = _super[name];

	        // The method only need to be bound temporarily, so we
	        // remove it when we're done executing
	        const ret = fn.apply(this, arguments);
	        this._super = tmp;
	        return ret;
	      };
	    }(name, proto[name]) : proto[name];
	  }
	  if (!/^[_a-z][_a-z\d]*$/i.test(className)) {
	    throw new Error('Invalid subclass name. Alphanumericals only.');
	  }

	  // The dummy class constructor
	  const ctor = new Function(`return (function ${className}(){ typeof this.init === 'function' && this.init.apply(this, [].slice.call(arguments)) });`)();

	  // Populate our constructed prototype object
	  ctor.prototype = prototype;

	  // Enforce the constructor to be what we expect
	  ctor.prototype.constructor = ctor;

	  // And make this class extendable
	  ctor.extend = extend;
	  return ctor;
	};

	// private
	const idGen = {
	  getChar(value) {
	    //               0   o    O   i    I   l
	    const banned = [48, 111, 79, 105, 73, 108];
	    let val = value;
	    let charCode;
	    if (val > 9) {
	      charCode = 65 + val - 10;
	      if (charCode > 90) {
	        charCode += 6;
	      }
	    } else {
	      val = `${val}`.charCodeAt(0);
	    }
	    return banned.indexOf(charCode) > -1 ? this.getChar(val + 1) : String.fromCharCode(charCode);
	  },
	  base62(value) {
	    const chr = this.getChar(value % 62);
	    const y = Math.floor(value / 62);
	    return y > 0 ? this.base62(y) + chr : chr;
	  },
	  id() {
	    const s = this.base62(Math.round(Math.random() * (1e13 - 1e11) + 1e11));
	    return s.replace(/\W/g, '');
	  }
	};
	function generateId() {
	  return idGen.id();
	}

	const SCROLLBAR_KEY = 'scrollbar';
	function getActions(isEnabledFn) {
	  function targetIsScrollbar(manager, e) {
	    if (!e || !isEnabledFn()) {
	      return false;
	    }
	    const startPoint = {
	      x: e.center.x - e.deltaX,
	      y: e.center.y - e.deltaY
	    };
	    const components = this.chart.componentsFromPoint(startPoint);
	    return components.some(c => c.settings.key === SCROLLBAR_KEY);
	  }
	  const tap = {
	    // single tap
	    type: 'Tap',
	    options: {
	      enable: targetIsScrollbar
	    },
	    events: {
	      tap(e) {
	        this.chart.component(SCROLLBAR_KEY).emit('tap', e);
	      }
	    }
	  };
	  const pan = {
	    type: 'Pan',
	    options: {
	      enable: targetIsScrollbar
	    },
	    events: {
	      panstart(e) {
	        this.chart.component(SCROLLBAR_KEY).emit('panStart', e);
	      },
	      pan(e) {
	        this.chart.component(SCROLLBAR_KEY).emit('panMove', e);
	      },
	      panend(e) {
	        this.chart.component(SCROLLBAR_KEY).emit('panEnd', e);
	      },
	      pancancel(e) {
	        this.chart.component(SCROLLBAR_KEY).emit('panCancel', e);
	      }
	    }
	  };
	  const actions = [tap, pan];
	  return actions;
	}

	function getAxisDock(direction, dock, isRtl) {
	  return direction === 'y' ? getYAxisDock(dock, isRtl) : getXAxisDock(dock);
	}
	function getOppositeAxisDock(direction, dock, isRtl) {
	  const oppositeDock = dock === 'far' ? 'near' : 'far';
	  return getAxisDock(direction, oppositeDock, isRtl);
	}
	function getYAxisDock(dock, isRtl) {
	  const yDockNearFar = dock || 'near';
	  return isRtl && yDockNearFar === 'near' || !isRtl && yDockNearFar === 'far' ? 'right' : 'left';
	}
	function getXAxisDock(dock) {
	  return dock === 'far' ? 'top' : 'bottom';
	}
	var axisDockUtil = {
	  getAxisDock,
	  getOppositeAxisDock,
	  getYAxisDock
	};

	// Source: https://en.wikipedia.org/wiki/Bi-directional_text and http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt
	// 3 types of strong direction characters: L (strong left-to-right), R(strong right-to-left, Hebrew) and AL(strong right-to-left, Arabic language)
	const rangesOfLChars = '[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u02BB-\u02C1\u02D0-\u02D1\u02E0-\u02E4\u02EE\u0370-\u0373\u0376-\u037D\u0386\u0388-\u03F5\u03F7-\u0482\u048A-\u0589\u0903-\u0939\u093B\u093D-\u0940\u0949-\u094C\u094E-\u0950\u0958-\u0961\u0964-\u097F\u0982-\u09B9\u09BD-\u09C0\u09C7-\u09CC\u09CE-\u09E1\u09E6-\u09F1\u09F4-\u09FA\u0A03-\u0A39\u0A3E-\u0A40\u0A59-\u0A6F\u0A72-\u0A74\u0A83-\u0AB9\u0ABD-\u0AC0\u0AC9-\u0ACC\u0AD0-\u0AE1\u0AE6-\u0AEF\u0B02-\u0B39\u0B3D-\u0B3E\u0B40\u0B47-\u0B4C\u0B57-\u0B61\u0B66-\u0B77\u0B83-\u0BBF\u0BC1-\u0BCC\u0BD0-\u0BF2\u0C01-\u0C3D\u0C41-\u0C44\u0C58-\u0C61\u0C66-\u0C6F\u0C7F-\u0CB9\u0CBD-\u0CCB\u0CD5-\u0CE1\u0CE6-\u0D40\u0D46-\u0D4C\u0D4E-\u0D61\u0D66-\u0DC6\u0DCF-\u0DD1\u0DD8-\u0E30\u0E32-\u0E33\u0E40-\u0E46\u0E4F-\u0EB0\u0EB2-\u0EB3\u0EBD-\u0EC6\u0ED0-\u0F17\u0F1A-\u0F34\u0F36\u0F38\u0F3E-\u0F6C\u0F7F\u0F85\u0F88-\u0F8C\u0FBE-\u0FC5\u0FC7-\u102C\u1031\u1038\u103B-\u103C\u103F-\u1057\u105A-\u105D\u1061-\u1070\u1075-\u1081\u1083-\u1084\u1087-\u108C\u108E-\u109C\u109E-\u135A\u1360-\u138F\u13A0-\u13F4\u1401-\u167F\u1681-\u169A\u16A0-\u1711\u1720-\u1731\u1735-\u1751\u1760-\u1770\u1780-\u17B6\u17BE-\u17C5\u17C7-\u17C8\u17D4-\u17DA\u17DC\u17E0-\u17E9\u1810-\u18A8\u18AA-\u191C\u1923-\u1926\u1929-\u1931\u1933-\u1938\u1946-\u19DA\u1A00-\u1A16\u1A19-\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1A80-\u1AAD\u1B04-\u1B33\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B6A\u1B74-\u1B7C\u1B82-\u1BA1\u1BA6-\u1BA7\u1BAA-\u1BE5\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1C2B\u1C34-\u1C35\u1C3B-\u1C7F\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1DBF\u1E00-\u1FBC\u1FBE\u1FC2-\u1FCC\u1FD0-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FFC\u200E\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E-\u214F\u2160-\u2188\u2336-\u237A\u2395\u249C-\u24E9\u26AC\u2800-\u28FF\u2C00-\u2CE4\u2CEB-\u2CEE\u2D00-\u2D70\u2D80-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u31BA\u31F0-\u321C\u3220-\u324F\u3260-\u327B\u327F-\u32B0\u32C0-\u32CB\u32D0-\u3376\u337B-\u33DD\u33E0-\u33FE\u3400-\u4DB5\u4E00-\uA48C\uA4D0-\uA60C\uA610-\uA66E\uA680-\uA6EF\uA6F2-\uA6F7\uA722-\uA787\uA789-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA824\uA827\uA830-\uA837\uA840-\uA873\uA880-\uA8C3\uA8CE-\uA8D9\uA8F2-\uA925\uA92E-\uA946\uA952-\uA97C\uA983-\uA9B2\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uAA28\uAA2F-\uAA30\uAA33-\uAA34\uAA40-\uAA42\uAA44-\uAA4B\uAA4D-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2-\uABE4\uABE6-\uABE7\uABE9-\uABEC\uABF0-\uFB17\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]';
	const rangesOfRChars = '[\u05BE\u05C0\u05C3\u05C6\u05D0-\u05F4\u07C0-\u07EA\u07F4-\u07F5\u07FA-\u0815\u081A\u0824\u0828\u0830-\u0858\u085E\u200F\uFB1D\uFB1F-\uFB28\uFB2A-\uFB4F]';
	const rangesOfALChars = '[\u0608\u060B\u060D\u061B-\u064A\u066D-\u066F\u0671-\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u070D\u0710\u0712-\u072F\u074D-\u07A5\u07B1\uFB50-\uFD3D\uFD50-\uFDFC\uFE70-\uFEFC]';
	// eslint-disable-next-line no-misleading-character-class
	const rangesOfLRgExp = new RegExp(rangesOfLChars);
	const rangesOfRRgExp = new RegExp(rangesOfRChars);
	const rangesOfALRgExp = new RegExp(rangesOfALChars);
	const
	// left-to-right marker
	lrm = String.fromCharCode(8206); // right-to-left marker
	function isLtrChar(c) {
	  return rangesOfLRgExp.test(c);
	}
	function isRtlChar(c) {
	  return rangesOfRRgExp.test(c) || rangesOfALRgExp.test(c);
	}
	function detectTextDirection(s) {
	  const n = s ? s.length : 0;
	  let i;
	  let c;
	  for (i = 0; i < n; i++) {
	    c = s[i];
	    if (isLtrChar(c)) {
	      return 'ltr';
	    }
	    if (isRtlChar(c)) {
	      return 'rtl';
	    }
	  }
	  return 'ltr';
	}
	var rtlUtils = {
	  lrm,
	  detectTextDirection
	};

	/**
	 * Get Picasso settings for an individual ref-line.
	 *
	 * @param {*} settings Default settings for the ref-line
	 * @param {*} lineColorIndex Chart builder options + paletteColor option
	 */
	function lineSettings(settings, options) {
	  const lineStroke = typeof options.paletteColor !== 'undefined' ? options.theme.getColorPickerColor(options.paletteColor) : 'transparent';
	  const defaultSettings = {
	    value: 0,
	    line: {
	      stroke: lineStroke,
	      strokeDasharray: options?.style?.lineType
	    }
	  };
	  return extend$1(true, defaultSettings, settings || {});
	}

	/**
	 * Get Picasso settings for an individual ref-line used to display label and OOB.
	 *
	 * @param {*} settings Default settings for the ref-line label
	 * @param {*} options Chart builder options + paletteColor option
	 */
	function lineLabelSettings(settings, options) {
	  const chartID = options && options.chartID; // Should we validate if the parameter exists?
	  let labelColor = options.theme.getStyle(chartID, 'referenceLine.label.name', 'color');
	  const labelFontSize = options.theme.getStyle(chartID, 'referenceLine.label.name', 'fontSize');
	  const labelFontFamily = options.theme.getStyle(chartID, 'referenceLine.label.name', 'fontFamily');
	  if (options.paletteColor) {
	    labelColor = options.theme.getColorPickerColor(options.paletteColor);
	  } else if (!labelColor) {
	    labelColor = 'transparent';
	  }
	  const defaultSettings = {
	    value: 0,
	    line: {
	      stroke: 'transparent'
	    },
	    label: {
	      align: 'center',
	      vAlign: 'middle',
	      text: '',
	      fill: labelColor,
	      fontFamily: labelFontFamily,
	      fontSize: labelFontSize,
	      maxWidthPx: 135
	    }
	  };
	  return extend$1(true, defaultSettings, settings || {});
	}
	const isVisible = refLine => refLine && refLine.show !== false && refLine.show !== 0 && refLine.show !== '0' && refLine.refLineExpr !== undefined;
	function getRefLineTitle({
	  refLine,
	  label,
	  valueString
	}) {
	  if (refLine.showValue !== false) {
	    if (refLine.showLabel !== false) {
	      return `${label} ${rtlUtils.lrm}(${valueString})${rtlUtils.lrm}`;
	    }
	    return `${rtlUtils.lrm}(${valueString})${rtlUtils.lrm}`;
	  }
	  if (refLine.showLabel !== false) {
	    return label;
	  }
	  return '';
	}
	var refLineUtil = {
	  lineSettings,
	  lineLabelSettings,
	  isVisible,
	  getRefLineTitle
	};

	var DimensionMeasureChartLayoutSettings = {
	  lasso: {
	    displayOrder: 10000
	  },
	  rangeDim: {
	    displayOrder: 10000
	  },
	  rangeMeasure: {
	    displayOrder: 10000
	  },
	  rangeMinor: {
	    displayOrder: 10000
	  },
	  // SPARK
	  scrollBar: {
	    minimumLayoutMode: 'SPARK',
	    prioOrder: -1,
	    displayOrder: 100
	  },
	  refLines: {
	    layout: {
	      minimumLayoutMode: 'SPARK',
	      prioOrder: 60,
	      displayOrder: 1110
	    }
	  },
	  // XMALL
	  measureAxisTitle: {
	    minimumLayoutMode: 'XSMALL',
	    prioOrder: 30,
	    displayOrder: 90
	  },
	  dimensionAxisTitle: {
	    minimumLayoutMode: 'XSMALL',
	    prioOrder: 30,
	    displayOrder: 90
	  },
	  measureAxis: {
	    minimumLayoutMode: 'XSMALL',
	    prioOrder: 10,
	    displayOrder: 80
	  },
	  dimensionAxis: {
	    minimumLayoutMode: 'XSMALL',
	    prioOrder: 10,
	    displayOrder: 80
	  },
	  gridLines: {
	    minimumLayoutMode: 'XSMALL',
	    displayOrder: -100
	  },
	  // SMALL
	  refLinesLabels: {
	    minimumLayoutMode: 'SMALL',
	    prioOrder: 60,
	    displayOrder: 0
	  }
	};

	const constants = {
	  SHOW_AXIS_LABELS_OPTIONS: ['all', 'labels'],
	  // show dim/measure axis labels when it matches one of this values
	  SHOW_TITLE_OPTIONS: ['all', 'title'],
	  // show the dimension/measure title when the show option matches one of these values
	  HORIZONTAL: 'horizontal',
	  VERTICAL: 'vertical',
	  LAYOUTSETTINGS: DimensionMeasureChartLayoutSettings
	};
	constants.DEFAULT_CHART_ORIENTATION = constants.HORIZONTAL;

	const SENSE_PICASSO_SPACING_COEFFICIENT = 100;
	function DimensionMeasureChart(chartBuilder, opts) {
	  const options = opts || {};
	  const measureAxisProperties = options.measureAxisProperties || {};
	  const dimensionAxisProperties = options.dimensionAxisProperties || {};
	  const chartOrientation = options.orientation || constants.DEFAULT_CHART_ORIENTATION;
	  const isChartHorizontal = chartOrientation === constants.HORIZONTAL;
	  const measureDirection = isChartHorizontal ? 'x' : 'y';
	  const dimensionDirection = isChartHorizontal ? 'y' : 'x';
	  const SHOW_AXIS_LABELS_OPTIONS = constants.SHOW_AXIS_LABELS_OPTIONS;
	  const SHOW_TITLE_OPTIONS = constants.SHOW_TITLE_OPTIONS;
	  const includeMeasureAxisComponent = SHOW_AXIS_LABELS_OPTIONS.includes(measureAxisProperties.show);
	  const includeMeasureAxisTitleComponent = !!options.measureTitleText && SHOW_TITLE_OPTIONS.includes(measureAxisProperties.show);
	  const includeDimensionAxisComponent = options.includeDimensionAxis && SHOW_AXIS_LABELS_OPTIONS.includes(dimensionAxisProperties.show);
	  const includeDimensionAxisTitleComponent = options.includeDimensionAxis && !!options.dimensionTitleText && SHOW_TITLE_OPTIONS.includes(dimensionAxisProperties.show);
	  const includeGridlines = options.gridlines && !(!options.gridlines.auto && options.gridlines.spacing === 0);
	  const includeRefLines = options.refLines && options.refLines.some(refLine => refLine.show);
	  const interactionActions = [];
	  if (includeMeasureAxisComponent) {
	    addMeasureAxisComponent(chartBuilder, options, measureDirection, measureAxisProperties);
	  }
	  if (includeMeasureAxisTitleComponent) {
	    addMeasureAxisTitleComponent(chartBuilder, options, measureDirection);
	  }
	  addMeasureScale(chartBuilder, options, chartOrientation, measureAxisProperties);
	  if (includeDimensionAxisComponent) {
	    addDimensionAxisComponent(chartBuilder, options, dimensionDirection);
	  }
	  if (includeDimensionAxisTitleComponent) {
	    addDimensionAxisTitleComponent(chartBuilder, options, dimensionDirection);
	  }
	  if (options.includeDimensionAxis) {
	    addDimensionScale(chartBuilder, options, chartOrientation);
	  }
	  if (includeGridlines) {
	    addGridlinesComponent(chartBuilder, options.gridlines, measureDirection);
	  }
	  if (options.hasNavigation) {
	    addScrollbarComponent(chartBuilder, interactionActions, options, isChartHorizontal);
	  }
	  if (includeRefLines) {
	    addRefLineComponent(chartBuilder, options, measureDirection, measureAxisProperties);
	  }
	  if (options.enableLasso && options.selectionsEnabled) {
	    const lassoOptions = options.lasso || {};
	    addLassoComponent(chartBuilder, lassoOptions);
	  }
	  if (options.enableDimRange && options.includeDimensionAxis && options.selectionsEnabled) {
	    const rangeDimOptions = options.dimRange || {};
	    const dimensionAxisOptions = getDimensionAxisOptions(options, dimensionDirection);
	    addRangeDimComponent(chartBuilder, rangeDimOptions, isChartHorizontal, dimensionAxisOptions.dock, options.isRtl);
	  }
	  if (options.enableMeasureRange && options.selectionsEnabled) {
	    const rangeMeasureOptions = options.measureRange || {};
	    const measureAxisOptions = getMeasureAxisOptions(options, measureDirection);
	    addRangeMeasureComponent(chartBuilder, rangeMeasureOptions, isChartHorizontal, measureAxisOptions.dock, options.isRtl);
	  }
	  if (options.enableAreaRange && options.selectionsEnabled) {
	    const areaDimOptions = options.areaRange || {};
	    const dimAreaAxisOptions = getDimensionAxisOptions(options, dimensionDirection);
	    addRangeAreaComponent(chartBuilder, areaDimOptions, isChartHorizontal, dimAreaAxisOptions.dock, options.isRtl);
	  }
	  if (options.brushActions) {
	    addInteractionActions(interactionActions, options.brushActions);
	  }
	  if (interactionActions.length) {
	    addInteractionComponent(chartBuilder, interactionActions);
	  }
	}
	function addInteractionComponent(chartBuilder, interactionActions) {
	  return chartBuilder.addInteraction({}, {
	    gestures: interactionActions
	  });
	}
	function addInteractionActions(interactionActions, actions) {
	  actions.forEach(a => {
	    interactionActions.push(a);
	  });
	}
	function addMeasureScale(chartBuilder, options, chartOrientation, measureAxisProperties) {
	  let measureScaleSettings = options.measureScaleSettings;
	  const measureScaleOptions = {
	    isRtl: options.isRtl,
	    source: options.measureSource,
	    orientation: chartOrientation,
	    measureAxisProperties
	  };
	  if (measureAxisProperties && measureAxisProperties.spacing > 0) {
	    measureScaleSettings = extend$1(true, measureScaleSettings || {}, {
	      component: {
	        ticks: {
	          distance: measureAxisProperties.spacing * SENSE_PICASSO_SPACING_COEFFICIENT
	        }
	      }
	    });
	  }
	  chartBuilder.addScale('measure-scale', measureScaleSettings, measureScaleOptions);
	}
	function addMeasureAxisComponent(chartBuilder, options, measureDirection, measureAxisProperties) {
	  let measureAxisSettings = {
	    scale: 'measure',
	    settings: options.axisLabelStyle || {},
	    forceBounds: measureAxisProperties && !measureAxisProperties.autoMinMax && measureAxisProperties.showBounds
	  };
	  measureAxisSettings = extend$1(measureAxisSettings, constants.LAYOUTSETTINGS.measureAxis);
	  const measureAxisOptions = getMeasureAxisOptions(options, measureDirection);
	  chartBuilder.addComponent(`${measureDirection}-axis`, measureAxisSettings, measureAxisOptions);
	}
	function addMeasureAxisTitleComponent(chartBuilder, options, measureDirection) {
	  let measureTitleSettings = {
	    text: options.measureTitleText,
	    style: options.axisTitleStyle || {}
	  };
	  measureTitleSettings = extend$1(measureTitleSettings, constants.LAYOUTSETTINGS.measureAxisTitle);
	  const measureAxisOptions = getMeasureAxisTitleOptions(options, measureDirection);
	  chartBuilder.addComponent(`${measureDirection}-axis-title`, measureTitleSettings, measureAxisOptions);
	}
	function addDimensionScale(chartBuilder, options, chartOrientation) {
	  const dimensionScaleOptions = {
	    isRtl: options.isRtl,
	    source: options.dimensionSource,
	    orientation: chartOrientation === constants.HORIZONTAL ? constants.VERTICAL : constants.HORIZONTAL
	  };
	  chartBuilder.addScale('dimension-scale', options.dimensionScaleSettings, dimensionScaleOptions);
	}
	function addDimensionAxisComponent(chartBuilder, options, dimensionDirection) {
	  let dimensionAxisSettings = {
	    scale: 'dimension',
	    settings: options.axisLabelStyle || {}
	  };
	  dimensionAxisSettings = extend$1(dimensionAxisSettings, constants.LAYOUTSETTINGS.dimensionAxis);
	  const dimensionAxisOptions = getDimensionAxisOptions(options, dimensionDirection);
	  extend$1(true, dimensionAxisSettings, options.dimensionAxisSettings || {});
	  chartBuilder.addComponent(`${dimensionDirection}-axis`, dimensionAxisSettings, dimensionAxisOptions);
	}
	function addDimensionAxisTitleComponent(chartBuilder, options, dimensionDirection) {
	  let dimensionAxisTitleSettings = {
	    text: options.dimensionTitleText,
	    style: options.axisTitleStyle || {}
	  };
	  dimensionAxisTitleSettings = extend$1(dimensionAxisTitleSettings, constants.LAYOUTSETTINGS.dimensionAxisTitle);
	  const dimensionAxisTitleOptions = getDimensionAxisTitleOptions(options, dimensionDirection);
	  chartBuilder.addComponent(`${dimensionDirection}-axis-title`, dimensionAxisTitleSettings, dimensionAxisTitleOptions);
	}
	function addGridlinesComponent(chartBuilder, gridlinesOptions, measureDirection) {
	  let gridlinesSettings = {
	    ticks: {
	      show: true
	    },
	    minorTicks: {
	      show: !gridlinesOptions.auto && !gridlinesOptions.auto && gridlinesOptions.spacing === 3
	    }
	  };
	  gridlinesSettings = extend$1(gridlinesSettings, constants.LAYOUTSETTINGS.gridLines);
	  gridlinesSettings[measureDirection] = {
	    scale: 'measure'
	  };
	  chartBuilder.addComponent('grid-line', gridlinesSettings);
	}
	function addScrollbarComponent(chartBuilder, interactionActions, options, isChartHorizontal) {
	  const settings = chartBuilder.getSettings();
	  settings.scroll = {
	    dimension: {
	      viewSize: options.scrollSettings && options.scrollSettings.viewSize || 0,
	      max: options.scrollSettings && options.scrollSettings.max || 0
	    }
	  };
	  const scrollbarOptions = {
	    isRtl: options.isRtl,
	    chartID: options.chartID,
	    isHorizontal: !isChartHorizontal
	  };
	  const scrollBarSettings = extend$1({}, constants.LAYOUTSETTINGS.scrollBar);
	  chartBuilder.addComponent('scrollbar', scrollBarSettings, scrollbarOptions);
	  addInteractionActions(interactionActions, getActions(options.isNavigationEnabledFn));
	}

	/*
	 * Add "ref-line" component(s). Currently two "ref-line" components are used to reserve space for labels and
	 * OOB markers outside of the data area. First component: shows the line(s) within the data area. Second component:
	 * shows the label(s) and OOB marker(s).
	 */
	function addRefLineComponent(chartBuilder, options, measureDirection, measureAxisProperties) {
	  const axisDock = axisDockUtil.getAxisDock(measureDirection, measureAxisProperties.dock, options.isRtl);
	  let refLinesSettings = {
	    // First component
	    key: 'ref-line',
	    style: {
	      oob: {
	        show: false
	      }
	    },
	    lines: {
	      x: [],
	      y: []
	    }
	  };
	  refLinesSettings = extend$1(refLinesSettings, constants.LAYOUTSETTINGS.refLines);
	  let refLinesLabelsSettings = {
	    // Second component
	    // Use a unique key to force re-render of this component in Picasso.
	    // This must be done because Picasso does not allow re-binding of functions (and shouldn't either).
	    key: `ref-line-labels-${generateId()}`,
	    require: ['renderer', 'chart'],
	    dock: axisDockUtil.getOppositeAxisDock(measureDirection, measureAxisProperties.dock, options.isRtl),
	    preferredSize() {
	      if (measureDirection === 'x') {
	        // Use constant component size if horizontal
	        return 26;
	      }

	      // Adapt component size to the longest label if vertical
	      const measureText = this.renderer.measureText;
	      const formatter = this.chart.formatter({
	        data: chartBuilder.settings.scales.measure.data
	      });
	      const labelWidths = refLinesLabelsSettings.lines.y.map(line => {
	        const formattedValue = line.label.showValue !== false ? `(${formatter(line.value)})` : '';
	        const text = `${line.label.text} ${formattedValue}`;
	        const minimumText = line.label.text && formattedValue ? `  ${formattedValue}` : formattedValue;
	        return {
	          wanted: measureText({
	            text,
	            fontSize: line.fontSize,
	            fontFamily: line.fontFamily
	          }).width,
	          required: measureText({
	            text: minimumText,
	            fontSize: line.fontSize,
	            fontFamily: line.fontFamily
	          }).width
	        };
	      });
	      const maxLabelWidth = labelWidths[0];
	      for (let i = 1; i < labelWidths.length; i++) {
	        if (labelWidths[i].wanted > maxLabelWidth.wanted) {
	          maxLabelWidth.wanted = labelWidths[i].wanted;
	        }
	        if (labelWidths[i].required > maxLabelWidth.required) {
	          maxLabelWidth.required = labelWidths[i].required;
	        }
	      }
	      const labelPadding = 12;
	      if (maxLabelWidth.required + labelPadding > 100) {
	        return maxLabelWidth.required + labelPadding; // Always have space for the value
	      }
	      return Math.min(maxLabelWidth.wanted + labelPadding, 100); // Limit to 100 px width
	    },
	    lines: {
	      x: [],
	      y: []
	    }
	  };
	  refLinesLabelsSettings = extend$1(refLinesLabelsSettings, constants.LAYOUTSETTINGS.refLinesLabels);
	  options.refLines.forEach(refLine => {
	    if (!refLine.show) {
	      return;
	    }
	    const expressionValue = refLine.refLineExpr && refLine.refLineExpr.value;
	    const lineOptions = extend$1(true, {}, options, {
	      paletteColor: refLine.paletteColor,
	      style: refLine.style,
	      chartID: chartBuilder.options.chartID
	    });

	    // Add a line for each visible ref line
	    const lineSettings = refLineUtil.lineSettings({
	      scale: 'measure',
	      dir: measureDirection,
	      value: expressionValue
	    }, lineOptions);
	    refLinesSettings.lines[measureDirection].push(lineSettings);

	    // Add a label and an OOB marker for each visible ref line (using the second component)
	    const lineLabelSettings = refLineUtil.lineLabelSettings({
	      scale: 'measure',
	      value: expressionValue,
	      label: {
	        text: refLine.showLabel !== false ? refLine.label : '',
	        showValue: refLine.showValue !== false
	      }
	    }, lineOptions);
	    if (measureDirection === 'x') {
	      lineLabelSettings.label.vAlign = axisDock === 'near' ? 1 : 0;
	    } else {
	      // y
	      lineLabelSettings.label.align = axisDock === 'near' ? 0 : 1;
	    }
	    refLinesLabelsSettings.lines[measureDirection].push(lineLabelSettings);
	  });
	  chartBuilder.addComponent('ref-line', refLinesSettings, {});
	  chartBuilder.addComponent('ref-line', refLinesLabelsSettings, {});
	}

	/**
	 * Adds a lasso component to the chart builder
	 * @param {ChartBuilder} chartBuilder
	 * @param {object} options - lasso options
	 * @param {string} options.brushKey - key used as context for lasso selection triggers
	 * @param {string} options.brushComponent - target component key
	 */
	function addLassoComponent(chartBuilder, options) {
	  const lassoOptions = {
	    brushKey: options.brushKey,
	    brushComponents: options.brushComponents,
	    brushData: options.brushData
	  };
	  chartBuilder.addComponent('lasso', constants.LAYOUTSETTINGS.lasso, lassoOptions);
	}
	/**
	 * Adds a dimension range component to the chart builder
	 * @param {any} chartBuilder
	 * @param {object} options - range dim options
	 * @param {string} options.brushKey - key used as context for range selection triggers
	 * @param {string} options.brushAxis - target axis to perform range select on
	 * @param {string} options.brushScale - Scale to use
	 * @param {boolean} isChartHorizontal - Whether the chart is horizontal or not
	 */
	function addRangeDimComponent(chartBuilder, options, isChartHorizontal, dock, isRtl) {
	  let rangeDimSettings = {
	    key: 'rangeDim'
	  };
	  rangeDimSettings = extend$1(rangeDimSettings, constants.LAYOUTSETTINGS.rangeDim);
	  const rangeDimOptions = {
	    brushKey: options.brushKey,
	    brushAxis: options.brushAxis,
	    brushArea: options.brushArea,
	    brushScale: options.brushScale,
	    isHorizontal: !isChartHorizontal,
	    dock,
	    isRtl
	  };
	  chartBuilder.addComponent('range', rangeDimSettings, rangeDimOptions);
	}
	function addRangeMeasureComponent(chartBuilder, options, isChartHorizontal, dock, isRtl) {
	  let rangeMeasureSettings = {
	    key: 'rangeMeasure'
	  };
	  rangeMeasureSettings = extend$1(rangeMeasureSettings, constants.LAYOUTSETTINGS.rangeMeasure);
	  const rangeMeasureOptions = {
	    brushKey: options.brushKey,
	    brushAxis: options.brushAxis,
	    brushArea: options.brushArea,
	    brushScale: options.brushScale,
	    multiple: options.multiple,
	    isHorizontal: isChartHorizontal,
	    dock,
	    isRtl
	  };
	  chartBuilder.addComponent('range', rangeMeasureSettings, rangeMeasureOptions);
	}
	function addRangeAreaComponent(chartBuilder, options, isChartHorizontal, dock, isRtl) {
	  let rangeMinorSettings = {
	    key: 'rangeMinor'
	  };
	  rangeMinorSettings = extend$1(rangeMinorSettings, constants.LAYOUTSETTINGS.rangeMinor);
	  const rangeMeasureOptions = {
	    brushKey: options.brushKey,
	    brushAxis: options.brushAxis,
	    brushData: options.brushData,
	    brushArea: options.brushArea,
	    brushComponents: options.brushComponents,
	    brushScale: options.brushScale,
	    multiple: options.multiple,
	    isHorizontal: options.brushScale === 'measure' ? isChartHorizontal : !isChartHorizontal,
	    dock,
	    isRtl,
	    chartInstance: options.chartInstance
	  };
	  chartBuilder.addComponent('range-area', rangeMinorSettings, rangeMeasureOptions);
	}
	function getMeasureAxisOptions(options, measureDirection) {
	  return {
	    dock: options.measureAxisProperties && options.measureAxisProperties.dock,
	    direction: measureDirection,
	    isRtl: options.isRtl
	  };
	}
	function getMeasureAxisTitleOptions(options, measureDirection) {
	  return getMeasureAxisOptions(options, measureDirection);
	}
	function getDimensionAxisOptions(options, dimensionDirection) {
	  return {
	    dock: options.dimensionAxisProperties && options.dimensionAxisProperties.dock,
	    direction: dimensionDirection,
	    isRtl: options.isRtl
	  };
	}
	function getDimensionAxisTitleOptions(options, dimensionDirection) {
	  return getDimensionAxisOptions(options, dimensionDirection);
	}

	function ChartPresets(type, chartBuilder, options) {
	  switch (type) {
	    case 'dimension-measure-chart':
	      DimensionMeasureChart(chartBuilder, options);
	      break;
	    default:
	      throw Error('There is no chart preset with that type');
	  }
	}

	function scale(settings, opts) {
	  const options = opts || {};
	  const isHorizontal = !options.orientation || options.orientation === 'horizontal';
	  const isRtl = !!options.isRtl;
	  const defaultSettings = {
	    name: options.name || 'scale',
	    component: {
	      invert: isHorizontal && isRtl,
	      minorTicks: {
	        count: 1
	      },
	      range: options.range || undefined,
	      domain: options.domain || undefined,
	      trackBy: options.trackBy || 'id'
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}
	function measureScale(settings, opts) {
	  const options = opts || {};
	  let fields = options.source || [];
	  if (typeof fields === 'string') {
	    fields = [fields];
	  }
	  const defaultSettings = {
	    name: 'measure',
	    component: {
	      expand: 0.1,
	      data: {
	        fields: fields.map(f => ({
	          field: f
	        }))
	      }
	    }
	  };
	  const measureAxisProperties = opts && opts.measureAxisProperties;
	  if (measureAxisProperties && !measureAxisProperties.autoMinMax) {
	    // explicit min max measure scale range
	    if (['min', 'minMax'].includes(measureAxisProperties.minMax)) {
	      defaultSettings.component.min = measureAxisProperties.min;
	    }
	    if (['max', 'minMax'].includes(measureAxisProperties.minMax)) {
	      defaultSettings.component.max = measureAxisProperties.max;
	    }
	  }
	  const measureSettings = extend$1(true, defaultSettings, settings || {});
	  const scaleSettings = scale(measureSettings, opts);
	  const hasInvertSettings = settings && settings.component && typeof settings.component.invert !== 'undefined';
	  if (!hasInvertSettings && opts && opts.orientation === 'vertical') {
	    scaleSettings.component.invert = !scaleSettings.component.invert;
	  }
	  return scaleSettings;
	}
	function dimensionScale(settings, opts) {
	  const defaultSettings = {
	    name: 'dimension',
	    component: {
	      trackBy: 'id',
	      type: 'band',
	      data: {
	        extract: {
	          field: opts && opts.source || '',
	          props: {
	            label(v) {
	              return v.qText || '';
	            } // Map qText to handle both qElemNo and qElemNumber
	          }
	        }
	      },
	      label(v) {
	        return v.datum.label.value;
	      } // Set qText as value from the mapping on r.92
	    }
	  };
	  const dimensionSettings = extend$1(true, defaultSettings, settings || {});
	  return scale(dimensionSettings, opts);
	}
	scale.measureScale = measureScale;
	scale.dimensionScale = dimensionScale;

	function getTextRenderer() {
	  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? undefined : 'svg';
	}

	function axis(settings, options) {
	  const chartID = options && options.chartID; // Should we validate if the parameter exists?
	  const dock = options && options.dock;
	  const direction = options && options.direction;
	  const isRtl = options && options.isRtl;
	  const axisLineStroke = options.theme.getStyle(chartID, 'axis.line.major', 'color');
	  const titleFontSize = options.theme.getStyle(chartID, 'axis.title', 'fontSize');
	  const titleFill = options.theme.getStyle(chartID, 'axis.title', 'color');
	  const labelsFill = options.theme.getStyle(chartID, 'axis.label.name', 'color');
	  const labelsFontSize = options.theme.getStyle(chartID, 'axis.label.name', 'fontSize');
	  const titleFontFamily = options.theme.getStyle(chartID, 'axis.title', 'fontFamily');
	  const labelsFontFamily = options.theme.getStyle(chartID, 'axis.label.name', 'fontFamily');
	  const defaultSettings = {
	    key: 'axis',
	    type: 'axis',
	    renderer: getTextRenderer(),
	    dock: axisDockUtil.getAxisDock(direction, dock, isRtl),
	    brush: {
	      trigger: [],
	      consume: []
	    },
	    settings: {
	      title: {
	        fontSize: titleFontSize,
	        fontFamily: titleFontFamily,
	        fill: titleFill
	      },
	      line: {
	        show: true,
	        strokeWidth: 1,
	        stroke: axisLineStroke
	      },
	      labels: {
	        fill: labelsFill,
	        fontSize: labelsFontSize,
	        fontFamily: labelsFontFamily,
	        tiltAngle: isRtl ? -40 : 40,
	        maxEdgeBleed: 75,
	        maxSize: 150,
	        mode: 'auto'
	      },
	      ticks: {
	        stroke: axisLineStroke
	      },
	      minorTicks: {
	        stroke: axisLineStroke
	      }
	    }
	  };
	  const axisSettings = extend$1(true, {}, defaultSettings, settings || {});
	  axisSettings.brush.consume.forEach(consume => {
	    consume.style.active.strokeWidth = 0;
	  });
	  return axisSettings;
	}
	function xAxis(settings, options) {
	  const defaultSettings = {
	    key: 'x-axis',
	    scale: 'x'
	  };
	  const xAxisSettings = extend$1(true, defaultSettings, settings || {});
	  return axis(xAxisSettings, options);
	}
	function yAxis(settings, options) {
	  const dock = options && options.dock;
	  const isRtl = options && options.isRtl;
	  const defaultSettings = {
	    key: 'y-axis',
	    scale: 'y',
	    dock: axisDockUtil.getYAxisDock(dock, isRtl)
	  };
	  const yAxisSettings = extend$1(true, defaultSettings, settings || {});
	  return axis(yAxisSettings, options);
	}
	axis.xAxis = xAxis;
	axis.yAxis = yAxis;

	function boxMarker(settings) {
	  const defaultSettings = {
	    key: 'box-marker',
	    type: 'box-marker',
	    settings: {
	      minor: {
	        scale: 'x'
	      },
	      orientation: 'horizontal'
	    },
	    brush: {
	      trigger: [],
	      consume: []
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function eventArea(settings) {
	  const defaultSettings = {
	    type: 'event-area',
	    key: 'event-area'
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function gridLine(settings, options) {
	  const chartID = options && options.chartID;
	  const axisLineStroke = options.theme.getStyle(chartID, 'grid.line.major', 'color');
	  const defaultSettings = {
	    displayOrder: -1,
	    key: 'grid-line',
	    type: 'grid-line',
	    x: null,
	    y: null,
	    ticks: {
	      stroke: axisLineStroke
	    },
	    minorTicks: {
	      stroke: axisLineStroke
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function interaction(settings, options) {
	  const gestures = options && options.gestures || [];
	  const defaultSettings = {
	    type: 'hammer',
	    key: 'hammered',
	    gestures
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function pointMarker(settings) {
	  const defaultSettings = {
	    key: 'point-marker',
	    type: 'point-marker',
	    settings: {},
	    brush: {
	      trigger: [],
	      consume: []
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function scrollbar(settings, options) {
	  const isRtl = options && options.isRtl;
	  const chartID = options && options.chartID;
	  const isHorizontal = options && options.isHorizontal;
	  const defaultSettings = {
	    key: 'scrollbar',
	    type: 'scrollbar',
	    scroll: 'dimension',
	    dock: isHorizontal ? 'bottom' : isRtl ? 'left' : 'right',
	    settings: {
	      backgroundColor: options.theme.getStyle(chartID, '', 'backgroundColor'),
	      invert: isRtl && isHorizontal
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function text(settings, options) {
	  const chartID = options && options.chartID;
	  const dock = options && options.dock;
	  const direction = options && options.direction;
	  const isRtl = options && options.isRtl;
	  const titleFontSize = options.theme.getStyle(chartID, 'axis.title', 'fontSize');
	  const titleFill = options.theme.getStyle(chartID, 'axis.title', 'color');
	  const titleFontFamily = options.theme.getStyle(chartID, 'axis.title', 'fontFamily');
	  const defaultSettings = {
	    key: 'text',
	    type: 'text',
	    dock: axisDockUtil.getAxisDock(direction, dock, isRtl),
	    displayOrder: 0,
	    // TODO: This can be removed when picasso set displayOrder for text component to 0. Currently picasso set it to 99.
	    style: {
	      text: {
	        fontSize: titleFontSize,
	        fontFamily: titleFontFamily,
	        fill: titleFill
	      }
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}
	function xAxisTitle(settings, options) {
	  const defaultSettings = {
	    key: 'x-axis-title'
	  };
	  const xAxisTitleSettings = extend$1(true, defaultSettings, settings || {});
	  return text(xAxisTitleSettings, options);
	}
	function yAxisTitle(settings, options) {
	  const dock = options && options.dock;
	  const isRtl = options && options.isRtl;
	  const defaultSettings = {
	    key: 'y-axis-title',
	    dock: axisDockUtil.getYAxisDock(dock, isRtl) || 'left'
	  };
	  const yAxisTitleSettings = extend$1(true, defaultSettings, settings || {});
	  return text(yAxisTitleSettings, options);
	}
	text.xAxisTitle = xAxisTitle;
	text.yAxisTitle = yAxisTitle;

	function lasso(settings, options) {
	  const brushKey = options && options.brushKey;
	  const brushComponents = options && options.brushComponents ? options.brushComponents : [];
	  const brushData = options && options.brushData ? options.brushData : ['elemNo'];
	  const defaultSettings = {
	    type: 'brush-lasso',
	    key: 'lasso',
	    displayOrder: 99,
	    settings: {
	      brush: {
	        components: []
	      },
	      lasso: {
	        fill: 'rgba(0, 0, 0, 0)',
	        stroke: 'rgba(102,102,102,1)',
	        strokeWidth: 2,
	        opacity: 1,
	        strokeDasharray: null // '10, 4',
	      },
	      startPoint: {
	        r: 10,
	        fill: 'rgba(0, 152, 69, 1)',
	        strokeWidth: 0,
	        opacity: 1
	      }
	    }
	  };
	  brushComponents.forEach(comp => {
	    defaultSettings.settings.brush.components.push({
	      contexts: brushKey ? [brushKey] : undefined,
	      key: comp,
	      data: brushData
	    });
	  });
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function getBublesAlign(isHorizontal, dock, isRtl) {
	  let isAlignStart = isHorizontal && dock !== 'far' || !isHorizontal && dock === 'far';
	  if (!isHorizontal && isRtl) {
	    isAlignStart = !isAlignStart;
	  }
	  return isAlignStart ? 'start' : 'end';
	}
	function getDock(brushAxis, brushArea) {
	  const dockTargets = [];
	  let dockT;
	  if (brushAxis) {
	    dockTargets.push(`@${brushAxis}`);
	  }
	  if (brushArea) {
	    dockTargets.push(`@${brushArea}`);
	  }
	  if (dockTargets.length) {
	    dockT = dockTargets.join(',');
	  }
	  return dockT;
	}
	var rangeUtil = {
	  getBublesAlign,
	  getDock
	};

	function range(settings, options) {
	  const brushKey = options && options.brushKey;
	  const brushAxis = options && options.brushAxis;
	  const brushArea = options && options.brushArea;
	  const brushScale = options && options.brushScale;
	  const isHorizontal = options && options.isHorizontal;
	  const dock = options && options.dock;
	  const isRtl = options && options.isRtl;
	  const defaultSettings = {
	    type: 'brush-range',
	    key: 'range',
	    displayOrder: 99,
	    dock: rangeUtil.getDock(brushAxis, brushArea),
	    settings: {
	      brush: brushKey,
	      fill: 'rgba(0, 0, 0, 0)',
	      scale: brushScale,
	      multiple: options && options.multiple === false ? options.multiple : true,
	      direction: isHorizontal ? 'horizontal' : 'vertical',
	      target: {
	        component: brushAxis,
	        fill: 'rgba( 82, 204, 82, 0.2 )',
	        fillActive: 'rgba(82, 204, 82, 0.4)'
	      },
	      bubbles: {
	        align: rangeUtil.getBublesAlign(isHorizontal, dock, isRtl)
	      }
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function refLine(settings, options) {
	  const chartID = options && options.chartID; // Should we validate if the parameter exists?
	  const oobColor = options.theme.getStyle(chartID, 'referenceLine.outOfBounds', 'color');
	  const oobBackgroundColor = options.theme.getStyle(chartID, 'referenceLine.outOfBounds', 'backgroundColor');
	  const defaultSettings = {
	    key: 'ref-line',
	    type: 'ref-line',
	    dock: 'center',
	    prioOrder: -1,
	    lines: {
	      x: [],
	      y: []
	    },
	    style: {
	      oob: {
	        width: 7,
	        fill: oobBackgroundColor,
	        text: {
	          fill: oobColor
	        },
	        padding: {
	          x: 7,
	          y: 5
	        }
	      }
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	/* eslint-disable guard-for-in */
	/* eslint-disable no-restricted-syntax */
	const layoutModes = {
	  SPARK: {
	    width: 0,
	    height: 0
	  },
	  XSMALL: {
	    width: 150,
	    height: 75
	  },
	  SMALL: {
	    width: 300,
	    height: 150
	  },
	  MEDIUM: {
	    width: 400,
	    height: 220
	  },
	  FULL: {
	    width: 550,
	    height: 450
	  }
	};
	function LayoutModes() {
	  return layoutModes;
	}
	LayoutModes.getLayoutModeKeys = function () {
	  const layoutModeKeys = [];
	  let modeKey;
	  for (modeKey in layoutModes) {
	    layoutModeKeys.push(modeKey);
	  }
	  return layoutModeKeys;
	};

	function getLabel(context) {
	  const end = context.data.end;
	  const formatter = context.dataset(end.source.key).field(end.source.field).formatter();
	  return formatter(end.value);
	}
	function labels(settings, options) {
	  const chartID = options && options.chartID;
	  const labelsFill = options.theme.getStyle(chartID, 'label.value', 'color');
	  const labelsFontSize = options.theme.getStyle(chartID, 'label.value', 'fontSize');
	  const labelsFontFamily = options.theme.getStyle(chartID, 'label.value', 'fontFamily');
	  const defaultSettings = {
	    key: 'labels',
	    type: 'labels',
	    renderer: getTextRenderer(),
	    displayOrder: 1,
	    settings: {
	      sources: [{
	        component: 'box-marker',
	        // Connects with the matching "key:" attribute in the visualizations
	        selector: 'rect',
	        strategy: {
	          type: 'bar',
	          settings: {
	            direction: 'up',
	            fontFamily: labelsFontFamily,
	            fontSize: parseFloat(labelsFontSize),
	            align: 0.5,
	            labels: [{
	              placements: [{
	                position: 'outside',
	                fill: labelsFill,
	                justify: 0
	              }, {
	                position: 'inside',
	                fill: settings && settings.settings.sources[0].strategy.settings.labels[0].placements[1].fill,
	                justify: 1
	              }],
	              label: getLabel
	            }]
	          }
	        }
	      }]
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	const directions = {
	  left: 'left',
	  right: 'right',
	  up: 'top',
	  down: 'bottom'
	};
	function legend(settings, options) {
	  const chartID = options && options.chartID;
	  const isRtl = options && options.isRtl;
	  let dock = options && options.dock || 'auto';
	  const show = options && options.show;
	  if (dock === 'auto') {
	    dock = options.chartHeight / options.chartWidth < 1 ? isRtl ? 'left' : 'right' : 'bottom';
	  }
	  const titleFill = options.theme.getStyle(chartID, 'legend.title', 'color');
	  const titleFontSize = options.theme.getStyle(chartID, 'legend.title', 'fontSize');
	  const itemFill = options.theme.getStyle(chartID, 'legend.label', 'color');
	  const itemFontSize = options.theme.getStyle(chartID, 'legend.label', 'fontSize');
	  const titleFontFamily = options.theme.getStyle(chartID, 'legend.title', 'fontFamily');
	  const itemFontFamily = options.theme.getStyle(chartID, 'legend.label', 'fontFamily');
	  const defaultSettings = {
	    key: 'legend',
	    type: 'legend-cat',
	    renderer: getTextRenderer(),
	    dock,
	    show,
	    scale: {
	      type: 'color'
	    },
	    settings: {
	      title: {
	        anchor: 'middle'
	      },
	      layout: {
	        direction: isRtl ? 'rtl' : 'ltr',
	        size: dock === 'top' || dock === 'bottom' ? 2 : 1,
	        vertical: dock === 'top' || dock === 'bottom' ? 16 : 8
	      },
	      navigation: {
	        button: {
	          class: {
	            'lui-fade-button': true
	          },
	          content(h, state) {
	            const c = ['lui-button__icon', 'lui-icon', `lui-icon--triangle-${directions[state.direction]}`];
	            return h('span', {
	              style: {
	                pointerEvents: 'none'
	              },
	              class: c.join(' ')
	            });
	          }
	        }
	      }
	    },
	    style: {
	      item: {
	        label: {
	          fontSize: itemFontSize,
	          fontFamily: itemFontFamily,
	          fill: itemFill,
	          lineHeight: 1,
	          wordBreak: 'break-word'
	        },
	        margin: {
	          top: 5,
	          left: 10,
	          right: 10,
	          bottom: 10
	        },
	        shape: {
	          type: options.type ? options.type : 'square',
	          size: parseInt(itemFontSize, 10) * 3 / 4 // To make it consistent with non-picasso charts
	        }
	      },
	      title: {
	        show: options.showTitle,
	        fontSize: titleFontSize,
	        fontFamily: titleFontFamily,
	        fill: titleFill
	      }
	    }
	  };
	  return extend$1(true, {}, defaultSettings, settings);
	}

	function sequentialLegend(settings, options) {
	  const chartID = options && options.chartID;
	  const isRtl = options && options.isRtl;
	  let dock = options.dock || 'auto';
	  if (dock === 'auto') {
	    dock = options.chartHeight < options.chartWidth ? isRtl ? 'left' : 'right' : 'bottom';
	  }
	  const titleFill = options.theme.getStyle(chartID, 'legend.title', 'color');
	  const titleFontSize = options.theme.getStyle(chartID, 'legend.title', 'fontSize');
	  const titleFontFamily = options.theme.getStyle(chartID, 'legend.title', 'fontFamily');
	  const tickFill = options.theme.getStyle(chartID, 'legend.label', 'color');
	  const tickFontSize = options.theme.getStyle(chartID, 'legend.label', 'fontSize');
	  const tickFontFamily = options.theme.getStyle(chartID, 'legend.label', 'fontFamily');
	  function getAlignValue(word) {
	    switch (word) {
	      case 'left':
	        return 0;
	      case 'right':
	        return 1;
	      case 'middle':
	      default:
	        return 0.5;
	    }
	  }
	  const defaultSettings = {
	    key: 'seqlegend',
	    type: 'legend-seq',
	    dock,
	    // Settings to position the legend outside of the axis
	    displayOrder: 200,
	    minimumLayoutMode: 'MEDIUM',
	    prioOrder: 0,
	    settings: {
	      align: isRtl ? getAlignValue('right') : getAlignValue('left'),
	      major: {
	        invert: dock === 'left' || dock === 'right' || isRtl
	      },
	      title: {
	        show: options.showTitle,
	        fontSize: titleFontSize,
	        fontFamily: titleFontFamily,
	        fill: titleFill
	      },
	      tick: {
	        fill: tickFill,
	        fontSize: tickFontSize,
	        fontFamily: tickFontFamily
	      }
	    }
	  };
	  const finalSettings = extend$1(true, {}, defaultSettings, settings);
	  return finalSettings;
	}

	function rangeArea(settings, options) {
	  const brushKey = options && options.brushKey;
	  const brushAxis = options && options.brushAxis;
	  const brushComponents = options && options.brushComponents ? options.brushComponents : [];
	  const brushData = options && options.brushData ? options.brushData : ['elemNo'];
	  const brushArea = options && options.brushArea;
	  const isHorizontal = options && options.isHorizontal;
	  const dock = options && options.dock;
	  const isRtl = options && options.isRtl;
	  const chartInstance = options && options.chartInstance;
	  let isStartBorder = true;
	  const defaultSettings = {
	    type: 'brush-area-dir',
	    key: 'area',
	    displayOrder: 99,
	    dock: rangeUtil.getDock(brushAxis, brushArea),
	    settings: {
	      brush: {
	        components: []
	      },
	      direction: isHorizontal ? 'horizontal' : 'vertical',
	      target: {
	        component: brushAxis,
	        fill: 'rgba( 82, 204, 82, 0.2 )',
	        fillActive: 'rgba(82, 204, 82, 0.4)'
	      },
	      bubbles: {
	        align: rangeUtil.getBublesAlign(isHorizontal, dock, isRtl),
	        label(data) {
	          if (isStartBorder) {
	            isStartBorder = false;
	            const formattedStartValue = chartInstance.dataset(data.binStart.source.key).field(data.binStart.source.field).formatter()(data.binStart.value);
	            return formattedStartValue;
	          }
	          isStartBorder = true;
	          const formattedEndValue = chartInstance.dataset(data.binEnd.source.key).field(data.binEnd.source.field).formatter()(data.binEnd.value);
	          return formattedEndValue;
	        }
	      },
	      multiple: options && options.multiple === false ? options.multiple : true
	    }
	  };
	  brushComponents.forEach(comp => {
	    defaultSettings.settings.brush.components.push({
	      contexts: brushKey ? [brushKey] : undefined,
	      key: comp,
	      data: brushData,
	      action: 'add'
	    });
	  });
	  return extend$1(true, {}, defaultSettings, settings || {});
	}

	function createComponent(type, settings, options) {
	  switch (type) {
	    // Picasso components
	    case 'scale':
	      return scale(settings, options);
	    case 'measure-scale':
	      return scale.measureScale(settings, options);
	    case 'dimension-scale':
	      return scale.dimensionScale(settings, options);
	    case 'axis':
	      return axis(settings, options);
	    case 'box-marker':
	      return boxMarker(settings);
	    case 'point-marker':
	      return pointMarker(settings);
	    case 'scrollbar':
	      return scrollbar(settings, options);
	    case 'text':
	      return text(settings, options);
	    case 'lasso':
	      return lasso(settings, options);
	    case 'range':
	      return range(settings, options);
	    case 'range-area':
	      return rangeArea(settings, options);
	    case 'categorical-legend':
	      return legend(settings, options);
	    case 'sequential-legend':
	      return sequentialLegend(settings, options);
	    // Wrapepd picasso components
	    case 'x-axis':
	      return axis.xAxis(settings, options);
	    case 'y-axis':
	      return axis.yAxis(settings, options);
	    case 'x-axis-title':
	      return text.xAxisTitle(settings, options);
	    case 'y-axis-title':
	      return text.yAxisTitle(settings, options);
	    case 'grid-line':
	      return gridLine(settings, options);
	    case 'interaction':
	      return interaction(settings, options);
	    case 'ref-line':
	      return refLine(settings, options);
	    // Custom components
	    case 'event-area':
	      return eventArea(settings);
	    case 'labels':
	      return labels(settings, options);
	    default:
	      return undefined;
	  }
	}
	function ChartBuilder(options) {
	  this.options = options || {};
	  this.settings = {
	    dockLayout: {
	      layoutModes: LayoutModes()
	    },
	    components: [],
	    scales: {}
	  };
	}
	ChartBuilder.prototype.addComponent = function addComponent(type, settings, options) {
	  const extendedOptions = extend$1(true, {}, this.options, options || {});
	  const component = createComponent(type, settings, extendedOptions);
	  this.settings.components.push(component);
	  return component;
	};
	ChartBuilder.prototype.addInteraction = function addInteraction(settings, options) {
	  const extendedOptions = extend$1(true, {}, this.options, options || {});
	  const component = createComponent('interaction', settings, extendedOptions);
	  if (!this.settings.interactions) {
	    this.settings.interactions = [];
	  }
	  this.settings.interactions.push(component);
	  return component;
	};
	ChartBuilder.prototype.addScale = function addScale(type, settings, options) {
	  const extendedOptions = extend$1(true, {}, this.options, options || {});
	  const scale = createComponent(type, settings, extendedOptions);
	  this.settings.scales[scale.name] = scale.component;
	};
	ChartBuilder.prototype.getSettings = function getSettings() {
	  return this.settings;
	};
	ChartBuilder.prototype.getComponent = function getComponent(key) {
	  return this.settings.components.filter(component => component.key === key)[0];
	};
	ChartBuilder.prototype.addPreset = function addPreset(type, options) {
	  ChartPresets(type, this, options);
	};
	ChartBuilder.validateComponentKeys = function validateComponentKeys(components) {
	  const keys = {};
	  return components.map(component => {
	    const key = component.key;
	    if (!key) {
	      return `Missing key for component ${component.type}`;
	    }
	    if (keys[key]) {
	      return `Duplicate key for component ${component.type}`;
	    }
	    keys[key] = true;
	    return null;
	  }).filter(msg => !!msg);
	};

	/*
	 * Factory function
	 */
	ChartBuilder.create = function (options) {
	  return new ChartBuilder(options);
	};
	ChartBuilder.createComponent = createComponent;

	/**
	 * Configuration for disclaimers
	 *
	 */

	/**
	 * Placement on chart
	 */
	const ALIGNMENT = {
	  CENTER: 0,
	  BOTTOM: 1
	};

	/**
	 * Configuration of all disclaimers
	 *
	 * label - key for translation
	 * alignment - Placement on chart
	 * default - Supported by default. If 'false' the disclaimer needs to be set to 'true' in supportedDisclaimers to be valid
	 */
	const DISCLAIMERS = [{
	  label: 'NoDataExist',
	  alignment: ALIGNMENT.CENTER,
	  default: true
	}, {
	  label: 'RequireNumericDimension',
	  alignment: ALIGNMENT.CENTER,
	  default: false
	}, {
	  label: 'OnlyNanData',
	  alignment: ALIGNMENT.CENTER,
	  default: true
	}, {
	  label: 'OnlyNegativeOrZeroValues',
	  alignment: ALIGNMENT.CENTER,
	  default: false
	}, {
	  label: 'LimitedData',
	  alignment: ALIGNMENT.BOTTOM,
	  default: false
	}, {
	  label: 'OnlyNanColor',
	  alignment: ALIGNMENT.BOTTOM,
	  default: false
	}, {
	  label: 'NegativeOrZeroValues',
	  alignment: ALIGNMENT.BOTTOM,
	  default: false
	}, {
	  label: 'DataRangeIncludingZero',
	  alignment: ALIGNMENT.BOTTOM,
	  default: false
	}];
	var DisclaimersConfig = {
	  DISCLAIMERS,
	  ALIGNMENT
	};

	/**
	 * Disclaimer utility for setting attributes needed for the disclaimer component
	 *
	 * @exports objects.picasso/disclaimer/disclaimer-attributes-utils
	 */

	/**
	 * Checks if the data range in measures and axis spans over the value 0
	 * @ignore
	 * @param measureAxis
	 * @param measureInfo
	 * @returns {boolean} True if the data range in any measure or the given axis spans over 0
	 */
	function hasDataRangeIncludingZero(measureAxis, measureInfo) {
	  const len = measureInfo.length;
	  let i;
	  let explicitMinOn;
	  let explicitMaxOn;
	  let min;
	  let max;
	  if (measureAxis) {
	    explicitMinOn = !measureAxis.autoMinMax && (measureAxis.minMax === 'min' || measureAxis.minMax === 'minMax') && measureAxis.min !== null && !Number.isNaN(+measureAxis.min);
	    explicitMaxOn = !measureAxis.autoMinMax && (measureAxis.minMax === 'max' || measureAxis.minMax === 'minMax') && measureAxis.max !== null && !Number.isNaN(+measureAxis.max);
	  }
	  min = Number.MAX_VALUE;
	  max = -Number.MAX_VALUE;

	  // return true if data contains zero
	  for (i = 0; i < len; i++) {
	    min = Math.min(min, measureInfo[i].qMin);
	    max = Math.max(max, measureInfo[i].qMax);
	    if (min <= 0 && max >= 0) {
	      return true;
	    }
	  }

	  // return true if axis explicits contains zero
	  min = explicitMinOn ? measureAxis.min : min;
	  max = explicitMaxOn ? measureAxis.max : max;
	  return min <= 0 && max >= 0;
	}
	function hasSubNodes(stackedDataPages) {
	  return stackedDataPages && stackedDataPages[0] && stackedDataPages[0].qData[0] && stackedDataPages[0].qData[0].qSubNodes;
	}
	const util = {
	  getNoDataExistAttribute(qHyperCube) {
	    return qHyperCube.qSize.qcy * qHyperCube.qSize.qcx === 0;
	  },
	  getLimitedDataAttribute(qHyperCube, opts) {
	    let result = false;
	    let maxNbrOfDimensions;
	    if (!qHyperCube) {
	      result = opts.explicitLimitedData === true;
	    } else if (opts.explicitLimitedData !== undefined) {
	      result = opts.explicitLimitedData === true;
	    } else if (qHyperCube.qDataPages && qHyperCube.qDataPages[0]) {
	      result = !opts.paging && qHyperCube.qSize.qcy > qHyperCube.qDataPages[0].qMatrix.length;
	    } else if (hasSubNodes(qHyperCube.qStackedDataPages)) {
	      maxNbrOfDimensions = opts.maxNbrOfDimensions ? opts.maxNbrOfDimensions : 2;
	      if (qHyperCube.qDimensionInfo.length >= maxNbrOfDimensions) {
	        result = qHyperCube.qStackedDataPages[0].qData[0].qSubNodes.some(node => node.qDown > 0);
	      } else {
	        result = qHyperCube.qStackedDataPages[0].qData[0].qSubNodes.length < qHyperCube.qStackedDataPages[0].qArea.qHeight;
	      }
	    }
	    return result;
	  },
	  getNegativeOrZeroValuesAttribute(qHyperCube, opts) {
	    return !opts.supportNegative && qHyperCube.qMeasureInfo.some(measure => measure.qMin <= 0);
	  },
	  getOnlyNegativeOrZeroValuesAttribute(qHyperCube, opts) {
	    return !opts.supportNegative && qHyperCube.qMeasureInfo.every(measure => measure.qMax <= 0 && measure.qMax >= measure.qMin) || qHyperCube.qSize.qcy === 0;
	  },
	  getOnlyNanDataAttribute(qHyperCube, opts) {
	    if (opts.explicitOnlyNanData !== undefined) {
	      return opts.explicitOnlyNanData;
	    }
	    return qHyperCube.qMeasureInfo.every(measure => measure.qMax < measure.qMin || measure.qMax === 'NaN');
	  },
	  getDataRangeIncludingZeroAttribute(data, opts) {
	    return !opts.supportRangeOverZero && hasDataRangeIncludingZero(data.measureAxis, data.qHyperCube.qMeasureInfo);
	  },
	  /**
	   * Apply attributes that configures disclaimers for a charts
	   * @param {Object} options - Options
	   * @param {Object} data - Layout data
	   * @returns {Object}
	   */
	  applyAttributes(options, data) {
	    const opts = options || {};
	    const dataAttributes = {};
	    opts.supportNegative = opts.supportNegative === undefined ? true : opts.supportNegative;
	    opts.supportRangeOverZero = opts.supportRangeOverZero === undefined ? true : opts.supportRangeOverZero;
	    DisclaimersConfig.DISCLAIMERS.forEach(config => {
	      dataAttributes[config.label] = false;
	    });
	    if (!data || !data.qHyperCube) {
	      return dataAttributes;
	    }
	    dataAttributes.NoDataExist = this.getNoDataExistAttribute(data.qHyperCube);
	    if (dataAttributes.NoDataExist) {
	      return dataAttributes;
	    }
	    dataAttributes.RequireNumericDimension = opts.explicitRequireNumericDimension;
	    if (dataAttributes.RequireNumericDimension) {
	      return dataAttributes;
	    }
	    dataAttributes.LimitedData = this.getLimitedDataAttribute(data.qHyperCube, opts);
	    dataAttributes.NegativeOrZeroValues = this.getNegativeOrZeroValuesAttribute(data.qHyperCube, opts);
	    dataAttributes.OnlyNegativeOrZeroValues = this.getOnlyNegativeOrZeroValuesAttribute(data.qHyperCube, opts);
	    dataAttributes.OnlyNanData = this.getOnlyNanDataAttribute(data.qHyperCube, opts);
	    dataAttributes.DataRangeIncludingZero = this.getDataRangeIncludingZeroAttribute(data, opts);
	    return dataAttributes;
	  }
	};

	/**
	 * Helper for disclaimer component
	 *
	 */

	/**
	 * Create new Helper for disclaimer
	 * @param disclaimersConfig {Array} List of disclaimer config objects
	 * @param dataAttributes {Object} Config for which disclaimers that are valid to show
	 * @param supportedDisclaimers {Object} Config for which disclaimers that are supported
	 * @constructor
	 */
	function Helper(disclaimersConfig, dataAttributes, supportedDisclaimers) {
	  this.disclaimersConfig = disclaimersConfig;
	  this.dataAttributes = dataAttributes;
	  this.supportedDisclaimers = supportedDisclaimers;
	}
	function isValid(label, list) {
	  return label && list && list[label];
	}

	/**
	 * Returns true if disclaimer config is valid, supported and has an alignment
	 * @param disclaimer {Object} Configuration for a disclaimer
	 * @param alignment {Integer} Alignment value in disclaimers config
	 * @returns {Boolean}
	 */
	Helper.prototype.isValidAndSupported = function (disclaimer, alignment) {
	  return isValid(disclaimer.label, this.dataAttributes) && (disclaimer.default || isValid(disclaimer.label, this.supportedDisclaimers)) && alignment !== undefined && disclaimer.alignment === alignment;
	};

	/**
	 * Returns true if there are any valid disclaimers for an alignment
	 * @param alignment {Integer} Alignment value in disclaimers config
	 * @returns {Boolean}
	 */
	Helper.prototype.isAnyValidDisclaimer = function (alignment) {
	  let result = false;
	  const self = this;
	  this.disclaimersConfig.forEach(config => {
	    if (self.isValidAndSupported(config, alignment)) {
	      result = true;
	    }
	  });
	  return result;
	};

	/**
	 * Gets all translated disclaimer messages for an alignment
	 * @param alignment {Integer} Alignment value in disclaimers config
	 * @param translator {Object} Translator component
	 * @returns {string}
	 */
	Helper.prototype.getMessage = function (alignment, translator) {
	  let str = '';
	  const self = this;
	  if (translator) {
	    this.disclaimersConfig.forEach(config => {
	      if (self.isValidAndSupported(config, alignment)) {
	        str += `${translator.get(`Object.Disclaimer.${config.label}`)} `;
	      }
	    });
	  }
	  return str;
	};

	/**
	 * Disclaimer component for Picasso base charts
	 *
	 * @exports objects.picasso/disclaimer/disclaimer
	 */

	Disclaimer.ERRORS = {
	  SET: 'Calling Disclaimer.set() without attributes',
	  DISPLAY: 'Calling Disclaimer.display() before attributes are applied'
	};

	/**
	 * Create new disclaimer component
	 * @param {Object} options - A reference to chart options
	 * @constructor
	 */
	function Disclaimer(environment) {
	  this.environment = environment;
	  this.clear();
	}
	Disclaimer._applyDefaultSupport = function (supportedDisclaimers, disclaimersConfig) {
	  let supported = supportedDisclaimers;
	  if (!supported) {
	    supported = {};
	  }
	  disclaimersConfig.forEach(config => {
	    if (supported[config.label] === undefined) {
	      supported[config.label] = config.default;
	    }
	  });
	  return supported;
	};
	Disclaimer.prototype.getComponentSettings = function () {
	  const {
	    translator
	  } = this.environment;
	  const supportedDisclaimers = extend$1(true, {}, this.vizAttributes.supportedDisclaimers);
	  const helper = new Helper(DisclaimersConfig.DISCLAIMERS, this.dataAttributes, supportedDisclaimers);
	  let message;
	  let dock;
	  if (helper.isAnyValidDisclaimer(DisclaimersConfig.ALIGNMENT.CENTER)) {
	    message = helper.getMessage(DisclaimersConfig.ALIGNMENT.CENTER, translator);
	    dock = 'center';
	  } else if (helper.isAnyValidDisclaimer(DisclaimersConfig.ALIGNMENT.BOTTOM)) {
	    message = helper.getMessage(DisclaimersConfig.ALIGNMENT.BOTTOM, translator);
	    dock = 'bottom';
	  } else {
	    return undefined;
	  }
	  return {
	    key: 'disclaimer',
	    type: 'disclaimer',
	    layout: {
	      displayOrder: 1000,
	      dock
	    },
	    settings: {
	      label: message,
	      rtl: this.environment?.options?.direction === 'rtl'
	    }
	  };
	};

	/**
	 * Set attributes that configures disclaimers for a charts
	 * @param {Object} attributes - Disclaimer settings for a chart
	 */
	Disclaimer.prototype.set = function (attributes) {
	  this.clear();
	  if (attributes) {
	    this.vizAttributes = attributes;
	    this.dataAttributes = util.applyAttributes(this.vizAttributes.options, this.vizAttributes.data);
	  } else {
	    throw new Error(Disclaimer.ERRORS.SET);
	  }
	};

	/**
	 * Clears disclaimer settings
	 */
	Disclaimer.prototype.clear = function () {
	  this.vizAttributes = null;
	  this.dataAttributes = null;
	};

	function getData(backendApi, hyperCube, rect) {
	  let page = {
	    qTop: 0,
	    qLeft: 0,
	    qWidth: hyperCube.qSize.qcx,
	    qHeight: 10000 / hyperCube.qSize.qcx
	  };
	  let dataPagesPath;
	  if (rect) {
	    const width = rect.width || hyperCube.qSize.qcx;
	    const maxHeight = Math.floor(10000 / width);
	    page = {
	      qTop: rect.top || 0,
	      qLeft: rect.left || 0,
	      qWidth: width,
	      qHeight: rect.height ? Math.min(rect.height, maxHeight) : maxHeight
	    };
	  } else {
	    page = {
	      qTop: 0,
	      qLeft: 0,
	      qWidth: hyperCube.qSize.qcx,
	      qHeight: 10000 / hyperCube.qSize.qcx
	    };
	  }
	  switch (hyperCube.qMode) {
	    case 'K':
	      // Stacked mode
	      dataPagesPath = 'qStackedDataPages';
	      break;
	    case 'S': // Straight table mode
	    default:
	      dataPagesPath = 'qDataPages';
	      break;
	  }
	  return backendApi.getData([page], null, hyperCube).then(pages => {
	    hyperCube[dataPagesPath] = pages;
	  });
	}
	const ChartView = Class.extend({
	  init(picasso, $element, environment, backendApi, selectionsApi) {
	    this.$element = $element;
	    this.environment = environment;
	    this.backendApi = backendApi;
	    this._selectionsApi = selectionsApi;
	    this._on = false;
	    this._disclaimer = new Disclaimer(environment);
	    this._dataPaths = ['qHyperCube'];
	    const self = this;

	    // Set properties that should be available in subclasses

	    this.picassoElement = $element[0];
	    this.picassoElement.className += ' picasso-chart';

	    // Paint a visually empty Picasso chart containing an event-area component
	    this.chartInstance = picasso.chart({
	      element: this.picassoElement,
	      settings: {
	        components: [ChartBuilder.createComponent('event-area', {
	          mounted(element) {
	            // Mounted is run synchronously so this.dataAreaElem will be available in subclass constructors
	            self.dataAreaElem = element;
	          }
	        })]
	      }
	    });
	  },
	  updateEnvironment(environment) {
	    this.environment = environment;
	  },
	  isRtl() {
	    return this.environment.options?.direction === 'rtl';
	  },
	  setDataPaths(dataPaths) {
	    this._dataPaths = dataPaths;
	  },
	  getData(backendApi, hyperCube, rect) {
	    return getData(backendApi, hyperCube, rect);
	  },
	  hasValidData() {
	    return true;
	  },
	  paint() {
	    // Use this.layout
	    if (this.hasValidData()) {
	      this._disclaimer.set(this.getDisclaimerAttributes(this.layout));
	      const disclaimerComponent = this._disclaimer.getComponentSettings();
	      const isSuppressingDisc = disclaimerComponent?.layout?.dock === 'center';
	      const chartSettings = this.createChartSettings(this.layout);
	      if (isSuppressingDisc) {
	        chartSettings.components = [disclaimerComponent];
	      } else if (disclaimerComponent) {
	        chartSettings.components.push(disclaimerComponent);
	      }
	      ChartBuilder.validateComponentKeys(chartSettings.components).forEach(errorMsg => {
	        console.error(errorMsg);
	      });
	      this.updateChart(this.layout, chartSettings);
	      this._painted = true;
	    }
	    return Promise.resolve();
	  },
	  resize() {
	    // Use this.layout
	    if (!this.layout) {
	      // There are cases where resize is run before updateData, therefore layout is undefined
	      return undefined;
	    }
	    return this.paint();
	  },
	  createChartSettings() {
	    throw new Error('Subclass must implement "createChartSettings" function');
	  },
	  addSnapshotChartSettings(settings, layout) {
	    const {
	      freeResize
	    } = this.environment.options;
	    if (!freeResize && layout.snapshotData) {
	      settings.dockLayout.logicalSize = {
	        width: layout.snapshotData.content.size.w,
	        height: layout.snapshotData.content.size.h,
	        preserveAspectRatio: true
	      };
	    }
	  },
	  updateData(layout) {
	    // clone the layout so that updates ignored by suppressOnPaint does not affect it.
	    if (this._destroyed) {
	      return Promise.reject();
	    }
	    this.layout = extend$1(true, {}, layout);
	    this.layout.permissions = layout.permissions;
	    return Promise.resolve();
	  },
	  updateChart(layout, settings, isPartialData) {
	    const localeInfo = this.environment.appLayout?.qLocaleInfo ?? {};
	    const data = this._dataPaths.map(path => ({
	      type: 'q',
	      key: path,
	      config: {
	        localeInfo
	      },
	      data: Nn(layout, path.replace(/\//g, '.'))
	    }));
	    if (this.colorService) {
	      data.push(...this.colorService.getData());
	    }
	    this.chartInstance.update({
	      data,
	      settings,
	      partialData: isPartialData
	    });
	    const STATE_DATA_UPDATED = 2;
	    this.picassoElement.setAttribute('data-state', STATE_DATA_UPDATED); // For integration test
	  },
	  destroy() {
	    this._destroyed = true;
	    this.off();
	    this.chartInstance.destroy();
	  },
	  getViewState() {
	    return {};
	  },
	  isLassoDisabled() {
	    return true;
	  },
	  setSnapshotData(snapshotLayout) {
	    if (!snapshotLayout.snapshotData) {
	      snapshotLayout.snapshotData = {};
	    }
	    snapshotLayout.snapshotData.content = {
	      // eslint-disable-line no-param-reassign
	      chartData: {},
	      size: {
	        w: this.$element.width(),
	        h: this.$element.height()
	      }
	    };
	  },
	  getDisclaimerAttributes(layout) {
	    return {
	      data: layout
	    };
	  }
	});

	var picassoQ$1 = {exports: {}};

	/*
	* picasso-plugin-q v2.8.2
	* Copyright (c) 2025 QlikTech International AB
	* Released under the MIT license.
	*/
	var picassoQ = picassoQ$1.exports;
	var hasRequiredPicassoQ;
	function requirePicassoQ() {
	  if (hasRequiredPicassoQ) return picassoQ$1.exports;
	  hasRequiredPicassoQ = 1;
	  (function (module, exports$1) {
	    (function (global, factory) {
	      module.exports = factory() ;
	    })(picassoQ, function () {

	      function _defineProperty(e, r, t) {
	        return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
	          value: t,
	          enumerable: true,
	          configurable: true,
	          writable: true
	        }) : e[r] = t, e;
	      }
	      function ownKeys(e, r) {
	        var t = Object.keys(e);
	        if (Object.getOwnPropertySymbols) {
	          var o = Object.getOwnPropertySymbols(e);
	          r && (o = o.filter(function (r) {
	            return Object.getOwnPropertyDescriptor(e, r).enumerable;
	          })), t.push.apply(t, o);
	        }
	        return t;
	      }
	      function _objectSpread2(e) {
	        for (var r = 1; r < arguments.length; r++) {
	          var t = null != arguments[r] ? arguments[r] : {};
	          r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
	            _defineProperty(e, r, t[r]);
	          }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
	            Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
	          });
	        }
	        return e;
	      }
	      function _toPrimitive(t, r) {
	        if ("object" != typeof t || !t) return t;
	        var e = t[Symbol.toPrimitive];
	        if (void 0 !== e) {
	          var i = e.call(t, r);
	          if ("object" != typeof i) return i;
	          throw new TypeError("@@toPrimitive must return a primitive value.");
	        }
	        return ("string" === r ? String : Number)(t);
	      }
	      function _toPropertyKey(t) {
	        var i = _toPrimitive(t, "string");
	        return "symbol" == typeof i ? i : i + "";
	      }
	      var hasOwn = Object.prototype.hasOwnProperty;
	      var toStr = Object.prototype.toString;
	      var defineProperty = Object.defineProperty;
	      var gOPD = Object.getOwnPropertyDescriptor;
	      var isArray = function isArray(arr) {
	        if (typeof Array.isArray === 'function') {
	          return Array.isArray(arr);
	        }
	        return toStr.call(arr) === '[object Array]';
	      };
	      var isPlainObject = function isPlainObject(obj) {
	        if (!obj || toStr.call(obj) !== '[object Object]') {
	          return false;
	        }
	        var hasOwnConstructor = hasOwn.call(obj, 'constructor');
	        var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
	        // Not own constructor property must be Object
	        if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
	          return false;
	        }

	        // Own properties are enumerated firstly, so to speed up,
	        // if last one is own, then all properties are own.
	        var key;
	        for (key in obj) {/**/}
	        return typeof key === 'undefined' || hasOwn.call(obj, key);
	      };

	      // If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
	      var setProperty = function setProperty(target, options) {
	        if (defineProperty && options.name === '__proto__') {
	          defineProperty(target, options.name, {
	            enumerable: true,
	            configurable: true,
	            value: options.newValue,
	            writable: true
	          });
	        } else {
	          target[options.name] = options.newValue;
	        }
	      };

	      // Return undefined instead of __proto__ if '__proto__' is not an own property
	      var getProperty = function getProperty(obj, name) {
	        if (name === '__proto__') {
	          if (!hasOwn.call(obj, name)) {
	            return void 0;
	          } else if (gOPD) {
	            // In early versions of node, obj['__proto__'] is buggy when obj has
	            // __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
	            return gOPD(obj, name).value;
	          }
	        }
	        return obj[name];
	      };
	      var extend = function extend() {
	        var options, name, src, copy, copyIsArray, clone;
	        var target = arguments[0];
	        var i = 1;
	        var length = arguments.length;
	        var deep = false;

	        // Handle a deep copy situation
	        if (typeof target === 'boolean') {
	          deep = target;
	          target = arguments[1] || {};
	          // skip the boolean and the target
	          i = 2;
	        }
	        if (target == null || typeof target !== 'object' && typeof target !== 'function') {
	          target = {};
	        }
	        for (; i < length; ++i) {
	          options = arguments[i];
	          // Only deal with non-null/undefined values
	          if (options != null) {
	            // Extend the base object
	            for (name in options) {
	              src = getProperty(target, name);
	              copy = getProperty(options, name);

	              // Prevent never-ending loop
	              if (target !== copy) {
	                // Recurse if we're merging plain objects or arrays
	                if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
	                  if (copyIsArray) {
	                    copyIsArray = false;
	                    clone = src && isArray(src) ? src : [];
	                  } else {
	                    clone = src && isPlainObject(src) ? src : {};
	                  }

	                  // Never move original objects, clone them
	                  setProperty(target, {
	                    name: name,
	                    newValue: extend(deep, clone, copy)
	                  });

	                  // Don't bring in undefined values
	                } else if (typeof copy !== 'undefined') {
	                  setProperty(target, {
	                    name: name,
	                    newValue: copy
	                  });
	                }
	              }
	            }
	          }
	        }

	        // Return the modified object
	        return target;
	      };

	      /* eslint no-nested-ternary: 0 */
	      function getFieldAccessor$1(field, page, deps, columnOrder) {
	        if (!field) {
	          return -1;
	        }
	        const cache = deps.cache;
	        const origin = field.origin ? field.origin() : null;
	        if (origin) {
	          field = origin;
	        }
	        let fieldIdx = cache.fields.indexOf(field);
	        let attrIdx = -1;
	        let attrDimIdx = -1;
	        if (fieldIdx === -1) {
	          for (let i = 0; i < cache.wrappedFields.length; i++) {
	            attrDimIdx = cache.wrappedFields[i].attrDims.map(v => v.instance).indexOf(field);
	            attrIdx = cache.wrappedFields[i].attrExps.map(v => v.instance).indexOf(field);
	            if (attrDimIdx !== -1 || attrIdx !== -1) {
	              fieldIdx = i;
	              break;
	            }
	          }
	        }
	        if (Array.isArray(columnOrder) && columnOrder.some((el, i) => el !== i)) {
	          const correctIndex = columnOrder.indexOf(fieldIdx);
	          if (correctIndex !== -1) {
	            fieldIdx = correctIndex;
	          }
	        }
	        fieldIdx -= page.qArea.qLeft;
	        if (fieldIdx < 0 || fieldIdx >= page.qArea.qWidth) {
	          // throw new Error('Field out of range');
	          return -1;
	        }
	        if (attrDimIdx >= 0) {
	          return row => row[fieldIdx].qAttrDims.qValues[attrDimIdx];
	        }
	        if (attrIdx >= 0) {
	          return row => row[fieldIdx].qAttrExps.qValues[attrIdx];
	        }
	        return row => row[fieldIdx];
	      }

	      // TODO - handle 'other' value
	      // const specialTextValues = {
	      //   '-3': (meta) => {
	      //     if ('othersLabel' in meta) {
	      //       return meta.othersLabel;
	      //     }
	      //     return '';
	      //   }
	      // };

	      function datumExtract$1(propCfg, cell, _ref) {
	        let {
	          key
	        } = _ref;
	        const datum = {
	          value: typeof propCfg.value === 'function' ? propCfg.value(cell) : typeof propCfg.value !== 'undefined' ? propCfg.value : cell // eslint-disable-line no-nested-ternary
	        };
	        datum.label = typeof propCfg.label === 'function' ? propCfg.label(cell) : typeof propCfg.label !== 'undefined' ? String(propCfg.label) : String(datum.value); // eslint-disable-line no-nested-ternary

	        if (propCfg.field) {
	          datum.source = {
	            key,
	            field: propCfg.field.key()
	          };
	        }
	        return datum;
	      }
	      function cellToValue(_ref2) {
	        let {
	          cache,
	          f,
	          mainCell,
	          p,
	          page,
	          rowIdx,
	          row,
	          sourceKey,
	          target,
	          targetProp,
	          columnOrder
	        } = _ref2;
	        let propCell = mainCell;
	        if (p.field && p.field !== f) {
	          const propCellFn = getFieldAccessor$1(p.field, page, {
	            cache
	          }, columnOrder);
	          if (propCellFn === -1) {
	            return;
	          }
	          propCell = extend({
	            qRow: rowIdx
	          }, propCellFn(row));
	        }
	        target[targetProp] = datumExtract$1(p, propCell, {
	          key: sourceKey
	        });
	      }
	      function extract$1(config, dataset, cache, util) {
	        const cfgs = Array.isArray(config) ? config : [config];
	        let dataItems = [];
	        for (let i = 0; i < cfgs.length; i++) {
	          if (typeof cfgs[i].field !== 'undefined') {
	            const cube = dataset.raw();
	            const sourceKey = dataset.key();
	            const f = typeof cfgs[i].field === 'object' ? cfgs[i].field : dataset.field(cfgs[i].field);
	            const {
	              props,
	              main
	            } = util.normalizeConfig(cfgs[i], dataset);
	            const propsArr = Object.keys(props);
	            const track = !!cfgs[i].trackBy;
	            const trackType = typeof cfgs[i].trackBy;
	            const tracker = {};
	            const trackedItems = [];
	            const items = [];
	            for (let j = 0; j < cube.qDataPages.length; j++) {
	              const fn = getFieldAccessor$1(f, cube.qDataPages[j], {
	                cache
	              }, cube.qColumnOrder);
	              if (fn === -1) {
	                continue;
	              }
	              for (let k = 0; k < cube.qDataPages[j].qMatrix.length; k++) {
	                const rowIdx = cube.qDataPages[j].qArea.qTop + k;
	                const mainCell = extend({
	                  qRow: rowIdx
	                }, fn(cube.qDataPages[j].qMatrix[k]));
	                const ret = datumExtract$1(main, mainCell, {
	                  key: sourceKey
	                });
	                const exclude = main.filter && !main.filter(mainCell);
	                if (exclude) {
	                  continue;
	                }
	                for (let l = 0; l < propsArr.length; l++) {
	                  const p = props[propsArr[l]];
	                  let arr = p.fields || [p];
	                  if (p.fields) {
	                    ret[propsArr[l]] = [];
	                  }

	                  // loop through all props that need to be mapped and
	                  // assign 'value' and 'source' to each property
	                  for (let m = 0; m < arr.length; m++) {
	                    cellToValue({
	                      cache,
	                      f,
	                      mainCell,
	                      p: arr[m],
	                      prop: propsArr[l],
	                      page: cube.qDataPages[j],
	                      rowIdx,
	                      row: cube.qDataPages[j].qMatrix[k],
	                      sourceKey,
	                      target: p.fields ? ret[propsArr[l]] : ret,
	                      targetProp: p.fields ? m : propsArr[l],
	                      columnOrder: cube.qColumnOrder
	                    });
	                  }
	                  if (p.fields) {
	                    const fieldValues = ret[propsArr[l]].map(v => v.value);
	                    const fieldLabels = ret[propsArr[l]].map(v => v.label);
	                    ret[propsArr[l]] = {
	                      value: typeof p.value === 'function' ? p.value(fieldValues) : typeof p.value !== 'undefined' ? p.value : fieldValues,
	                      label: typeof p.label === 'function' ? p.label(fieldLabels) : typeof p.label !== 'undefined' ? String(p.label) : String(ret[propsArr[l]].value)
	                    };
	                  }
	                }

	                // collect items based on the trackBy value
	                // items with the same trackBy value are placed in an array and reduced later
	                if (track) {
	                  util.track({
	                    cfg: cfgs[i],
	                    itemData: mainCell,
	                    obj: ret,
	                    target: trackedItems,
	                    tracker,
	                    trackType
	                  });
	                }
	                items.push(ret);
	              }
	            }

	            // reduce if items have been grouped
	            const tmp = track ? util.collect(trackedItems, {
	              main,
	              propsArr,
	              props
	            }) : items;
	            dataItems = [...dataItems, ...tmp];
	          }
	        }
	        return dataItems;
	      }
	      function count(node) {
	        var sum = 0,
	          children = node.children,
	          i = children && children.length;
	        if (!i) sum = 1;else while (--i >= 0) sum += children[i].value;
	        node.value = sum;
	      }
	      function node_count() {
	        return this.eachAfter(count);
	      }
	      function node_each(callback, that) {
	        let index = -1;
	        for (const node of this) {
	          callback.call(that, node, ++index, this);
	        }
	        return this;
	      }
	      function node_eachBefore(callback, that) {
	        var node = this,
	          nodes = [node],
	          children,
	          i,
	          index = -1;
	        while (node = nodes.pop()) {
	          callback.call(that, node, ++index, this);
	          if (children = node.children) {
	            for (i = children.length - 1; i >= 0; --i) {
	              nodes.push(children[i]);
	            }
	          }
	        }
	        return this;
	      }
	      function node_eachAfter(callback, that) {
	        var node = this,
	          nodes = [node],
	          next = [],
	          children,
	          i,
	          n,
	          index = -1;
	        while (node = nodes.pop()) {
	          next.push(node);
	          if (children = node.children) {
	            for (i = 0, n = children.length; i < n; ++i) {
	              nodes.push(children[i]);
	            }
	          }
	        }
	        while (node = next.pop()) {
	          callback.call(that, node, ++index, this);
	        }
	        return this;
	      }
	      function node_find(callback, that) {
	        let index = -1;
	        for (const node of this) {
	          if (callback.call(that, node, ++index, this)) {
	            return node;
	          }
	        }
	      }
	      function node_sum(value) {
	        return this.eachAfter(function (node) {
	          var sum = +value(node.data) || 0,
	            children = node.children,
	            i = children && children.length;
	          while (--i >= 0) sum += children[i].value;
	          node.value = sum;
	        });
	      }
	      function node_sort(compare) {
	        return this.eachBefore(function (node) {
	          if (node.children) {
	            node.children.sort(compare);
	          }
	        });
	      }
	      function node_path(end) {
	        var start = this,
	          ancestor = leastCommonAncestor(start, end),
	          nodes = [start];
	        while (start !== ancestor) {
	          start = start.parent;
	          nodes.push(start);
	        }
	        var k = nodes.length;
	        while (end !== ancestor) {
	          nodes.splice(k, 0, end);
	          end = end.parent;
	        }
	        return nodes;
	      }
	      function leastCommonAncestor(a, b) {
	        if (a === b) return a;
	        var aNodes = a.ancestors(),
	          bNodes = b.ancestors(),
	          c = null;
	        a = aNodes.pop();
	        b = bNodes.pop();
	        while (a === b) {
	          c = a;
	          a = aNodes.pop();
	          b = bNodes.pop();
	        }
	        return c;
	      }
	      function node_ancestors() {
	        var node = this,
	          nodes = [node];
	        while (node = node.parent) {
	          nodes.push(node);
	        }
	        return nodes;
	      }
	      function node_descendants() {
	        return Array.from(this);
	      }
	      function node_leaves() {
	        var leaves = [];
	        this.eachBefore(function (node) {
	          if (!node.children) {
	            leaves.push(node);
	          }
	        });
	        return leaves;
	      }
	      function node_links() {
	        var root = this,
	          links = [];
	        root.each(function (node) {
	          if (node !== root) {
	            // Don’t include the root’s parent, if any.
	            links.push({
	              source: node.parent,
	              target: node
	            });
	          }
	        });
	        return links;
	      }
	      function* node_iterator() {
	        var node = this,
	          current,
	          next = [node],
	          children,
	          i,
	          n;
	        do {
	          current = next.reverse(), next = [];
	          while (node = current.pop()) {
	            yield node;
	            if (children = node.children) {
	              for (i = 0, n = children.length; i < n; ++i) {
	                next.push(children[i]);
	              }
	            }
	          }
	        } while (next.length);
	      }
	      function hierarchy(data, children) {
	        if (data instanceof Map) {
	          data = [undefined, data];
	          if (children === undefined) children = mapChildren;
	        } else if (children === undefined) {
	          children = objectChildren;
	        }
	        var root = new Node(data),
	          node,
	          nodes = [root],
	          child,
	          childs,
	          i,
	          n;
	        while (node = nodes.pop()) {
	          if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) {
	            node.children = childs;
	            for (i = n - 1; i >= 0; --i) {
	              nodes.push(child = childs[i] = new Node(childs[i]));
	              child.parent = node;
	              child.depth = node.depth + 1;
	            }
	          }
	        }
	        return root.eachBefore(computeHeight);
	      }
	      function node_copy() {
	        return hierarchy(this).eachBefore(copyData);
	      }
	      function objectChildren(d) {
	        return d.children;
	      }
	      function mapChildren(d) {
	        return Array.isArray(d) ? d[1] : null;
	      }
	      function copyData(node) {
	        if (node.data.value !== undefined) node.value = node.data.value;
	        node.data = node.data.data;
	      }
	      function computeHeight(node) {
	        var height = 0;
	        do node.height = height; while ((node = node.parent) && node.height < ++height);
	      }
	      function Node(data) {
	        this.data = data;
	        this.depth = this.height = 0;
	        this.parent = null;
	      }
	      Node.prototype = hierarchy.prototype = {
	        constructor: Node,
	        count: node_count,
	        each: node_each,
	        eachAfter: node_eachAfter,
	        eachBefore: node_eachBefore,
	        find: node_find,
	        sum: node_sum,
	        sort: node_sort,
	        path: node_path,
	        ancestors: node_ancestors,
	        descendants: node_descendants,
	        leaves: node_leaves,
	        links: node_links,
	        copy: node_copy,
	        [Symbol.iterator]: node_iterator
	      };
	      function optional(f) {
	        return f == null ? null : required(f);
	      }
	      function required(f) {
	        if (typeof f !== "function") throw new Error();
	        return f;
	      }
	      var preroot = {
	          depth: -1
	        },
	        ambiguous = {},
	        imputed = {};
	      function defaultId(d) {
	        return d.id;
	      }
	      function defaultParentId(d) {
	        return d.parentId;
	      }
	      function stratify() {
	        var id = defaultId,
	          parentId = defaultParentId,
	          path;
	        function stratify(data) {
	          var nodes = Array.from(data),
	            currentId = id,
	            currentParentId = parentId,
	            n,
	            d,
	            i,
	            root,
	            parent,
	            node,
	            nodeId,
	            nodeKey,
	            nodeByKey = new Map();
	          if (path != null) {
	            const I = nodes.map((d, i) => normalize(path(d, i, data)));
	            const P = I.map(parentof);
	            const S = new Set(I).add("");
	            for (const i of P) {
	              if (!S.has(i)) {
	                S.add(i);
	                I.push(i);
	                P.push(parentof(i));
	                nodes.push(imputed);
	              }
	            }
	            currentId = (_, i) => I[i];
	            currentParentId = (_, i) => P[i];
	          }
	          for (i = 0, n = nodes.length; i < n; ++i) {
	            d = nodes[i], node = nodes[i] = new Node(d);
	            if ((nodeId = currentId(d, i, data)) != null && (nodeId += "")) {
	              nodeKey = node.id = nodeId;
	              nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node);
	            }
	            if ((nodeId = currentParentId(d, i, data)) != null && (nodeId += "")) {
	              node.parent = nodeId;
	            }
	          }
	          for (i = 0; i < n; ++i) {
	            node = nodes[i];
	            if (nodeId = node.parent) {
	              parent = nodeByKey.get(nodeId);
	              if (!parent) throw new Error("missing: " + nodeId);
	              if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
	              if (parent.children) parent.children.push(node);else parent.children = [node];
	              node.parent = parent;
	            } else {
	              if (root) throw new Error("multiple roots");
	              root = node;
	            }
	          }
	          if (!root) throw new Error("no root");

	          // When imputing internal nodes, only introduce roots if needed.
	          // Then replace the imputed marker data with null.
	          if (path != null) {
	            while (root.data === imputed && root.children.length === 1) {
	              root = root.children[0], --n;
	            }
	            for (let i = nodes.length - 1; i >= 0; --i) {
	              node = nodes[i];
	              if (node.data !== imputed) break;
	              node.data = null;
	            }
	          }
	          root.parent = preroot;
	          root.eachBefore(function (node) {
	            node.depth = node.parent.depth + 1;
	            --n;
	          }).eachBefore(computeHeight);
	          root.parent = null;
	          if (n > 0) throw new Error("cycle");
	          return root;
	        }
	        stratify.id = function (x) {
	          return arguments.length ? (id = optional(x), stratify) : id;
	        };
	        stratify.parentId = function (x) {
	          return arguments.length ? (parentId = optional(x), stratify) : parentId;
	        };
	        stratify.path = function (x) {
	          return arguments.length ? (path = optional(x), stratify) : path;
	        };
	        return stratify;
	      }

	      // To normalize a path, we coerce to a string, strip the trailing slash if any
	      // (as long as the trailing slash is not immediately preceded by another slash),
	      // and add leading slash if missing.
	      function normalize(path) {
	        path = `${path}`;
	        let i = path.length;
	        if (slash(path, i - 1) && !slash(path, i - 2)) path = path.slice(0, -1);
	        return path[0] === "/" ? path : `/${path}`;
	      }

	      // Walk backwards to find the first slash that is not the leading slash, e.g.:
	      // "/foo/bar" ⇥ "/foo", "/foo" ⇥ "/", "/" ↦ "". (The root is special-cased
	      // because the id of the root must be a truthy value.)
	      function parentof(path) {
	        let i = path.length;
	        if (i < 2) return "";
	        while (--i > 1) if (slash(path, i)) break;
	        return path.slice(0, i);
	      }

	      // Slashes can be escaped; to determine whether a slash is a path delimiter, we
	      // count the number of preceding backslashes escaping the forward slash: an odd
	      // number indicates an escaped forward slash.
	      function slash(path, i) {
	        if (path[i] === "/") {
	          let k = 0;
	          while (i > 0 && path[--i] === "\\") ++k;
	          if ((k & 1) === 0) return true;
	        }
	        return false;
	      }

	      /**
	       * Resolves the value at the given JSON path
	       * @private
	       * @param  {String} path [description]
	       * @param  {Object} obj  [description]
	       * @return {Object}      [description]
	       *
	       * @example
	       * let path = "/path/to/paradise";
	       * let obj = {
	       *   path: {
	       *     to: { paradise: "heaven"},
	       *     from: {...}
	       *   }
	       * };
	       * resolve( path, obj ); // "heaven"
	       */
	      function resolve(path, obj) {
	        if (path.charAt(0) === '/') {
	          path = path.substring(1);
	        }
	        const arr = path.split('/');
	        let subpath;
	        let container = obj;
	        for (let i = 0; i < arr.length; i++) {
	          if (arr[i] === '*' && Array.isArray(container)) {
	            const carr = [];
	            subpath = arr.slice(i + 1).join('/');
	            for (let c = 0; c < container.length; c++) {
	              let v = resolve(subpath, container[c]);
	              // v.forEach(_ => _._parent = container[c]);
	              if (Array.isArray(v)) {
	                carr.push(...v);
	              } else {
	                carr.push(v);
	              }
	            }
	            return carr;
	            // return container.map(v => resolve(arr.slice(i + 1).join('/'), v));
	          }
	          if (!arr[i] && Array.isArray(container)) {
	            const carr = new Array(container.length);
	            subpath = arr.slice(i + 1).join('/');
	            for (let c = 0; c < container.length; c++) {
	              carr[c] = resolve(subpath, container[c]);
	            }
	            return carr;
	            // return container.map(v => resolve(arr.slice(i + 1).join('/'), v));
	          }
	          if (arr[i] in container) {
	            container = container[arr[i]];
	          }
	        }
	        return container;
	      }
	      function flattenTree(children, steps, arrIndexAtTargetDepth) {
	        let arr = [];
	        if (!children || !children.length) {
	          return arr;
	        }
	        if (steps <= 0) {
	          const nodes = arrIndexAtTargetDepth >= 0 ? [children[arrIndexAtTargetDepth]] : children;
	          arr = [...arr, ...nodes];
	        } else {
	          for (let i = 0; i < children.length; i++) {
	            if (children[i].children && children[i].children.length) {
	              arr = [...arr, ...flattenTree(children[i].children, steps - 1, arrIndexAtTargetDepth)];
	            }
	          }
	        }
	        return arr;
	      }
	      function treeAccessor(sourceDepth, targetDepth, arrIndexAtTargetDepth) {
	        if (sourceDepth === targetDepth) {
	          return d => d;
	        }
	        if (sourceDepth > targetDepth) {
	          // traverse upwards
	          const steps = Math.max(0, Math.min(100, sourceDepth - targetDepth));
	          return node => {
	            let n = node;
	            for (let i = 0; i < steps; ++i) {
	              n = n.parent;
	            }
	            return n;
	          };
	        }
	        if (targetDepth > sourceDepth) {
	          // flatten descendants
	          const steps = Math.max(0, Math.min(100, targetDepth - sourceDepth));
	          return node => flattenTree(node.children, steps - 1, arrIndexAtTargetDepth);
	        }
	        return false;
	      }
	      function findField(query, _ref) {
	        let {
	          cache
	        } = _ref;
	        if (typeof query === 'number') {
	          return cache.fields[query];
	        }
	        const allFields = cache.allFields;
	        if (typeof query === 'function') {
	          for (let i = 0; i < allFields.length; i++) {
	            if (query(allFields[i])) {
	              return allFields[i];
	            }
	          }
	          return false;
	        }
	        if (typeof query === 'string') {
	          for (let i = 0; i < allFields.length; i++) {
	            if (allFields[i].key() === query || allFields[i].title() === query) {
	              return allFields[i];
	            }
	          }
	        } else if (query && allFields.indexOf(query) !== -1) {
	          // assume 'query' is a field instance
	          return query;
	        }
	        throw Error("Field not found: ".concat(query));
	      }
	      const DIM_RX$1 = /^qDimensionInfo(?:\/(\d+))?/;
	      const M_RX$1 = /^\/?qMeasureInfo\/(\d+)/;
	      const ATTR_EXPR_RX$1 = /\/qAttrExprInfo\/(\d+)/;
	      const ATTR_DIM_RX$1 = /\/qAttrDimInfo\/(\d+)/;
	      function getColumnOrder(dataset) {
	        const qColumnOrder = dataset.raw().qColumnOrder;
	        const fields = dataset.fields();
	        return qColumnOrder && qColumnOrder.length === fields.length ? qColumnOrder : fields.map((f, i) => i);
	      }
	      function getDimensionColumnOrder(cube) {
	        const order = cube.qColumnOrder && cube.qColumnOrder.length ? cube.qColumnOrder : cube.qDimensionInfo.map((d, ii) => ii);
	        return order.filter(ii => ii < cube.qDimensionInfo.length);
	      }
	      function getFieldDepth(field, _ref) {
	        let {
	          cube
	        } = _ref;
	        if (!field) {
	          return -1;
	        }
	        let key = field.origin && field.origin() ? field.origin().key() : field.key();
	        let isFieldDimension = false;
	        let fieldIdx = -1; // cache.fields.indexOf(field);
	        let attrIdx = -1;
	        let attrDimIdx = -1;
	        let fieldDepth = -1;
	        let pseudoMeasureIndex = -1;
	        let measureIdx = -1;
	        let remainder = key;
	        const treeOrder = cube.qEffectiveInterColumnSortOrder;
	        const columnOrder = getDimensionColumnOrder(cube);
	        if (DIM_RX$1.test(remainder)) {
	          isFieldDimension = true;
	          fieldIdx = +DIM_RX$1.exec(remainder)[1];
	          remainder = key.replace(DIM_RX$1, '');
	        }
	        if (M_RX$1.test(remainder)) {
	          if (cube.qMode === 'K') {
	            pseudoMeasureIndex = +M_RX$1.exec(remainder)[1];
	          } else if (treeOrder && treeOrder.indexOf(-1) !== -1) {
	            pseudoMeasureIndex = +M_RX$1.exec(remainder)[1];
	            measureIdx = 0;
	          } else {
	            measureIdx = +M_RX$1.exec(remainder)[1];
	          }
	          remainder = remainder.replace(M_RX$1, '');
	        }
	        if (remainder) {
	          if (ATTR_DIM_RX$1.exec(remainder)) {
	            attrDimIdx = +ATTR_DIM_RX$1.exec(remainder)[1];
	          } else if (ATTR_EXPR_RX$1.exec(remainder)) {
	            attrIdx = +ATTR_EXPR_RX$1.exec(remainder)[1];
	          }
	        }
	        if (isFieldDimension) {
	          if (cube.qMode === 'S') {
	            fieldDepth = columnOrder[fieldIdx];
	          } else {
	            fieldDepth = treeOrder ? treeOrder.indexOf(fieldIdx) : fieldIdx;
	          }
	        } else if (treeOrder && treeOrder.indexOf(-1) !== -1) {
	          // if pseudo dimension exists in sort order
	          fieldDepth = treeOrder.indexOf(-1); // depth of pesudodimension
	        } else {
	          // assume measure is at the bottom of the tree
	          fieldDepth = cube.qDimensionInfo.length - (cube.qMode === 'K' ? 0 : 1);
	        }
	        return {
	          fieldDepth: fieldDepth + 1,
	          // +1 due to root node
	          pseudoMeasureIndex,
	          measureIdx,
	          attrDimIdx,
	          attrIdx
	        };
	      }
	      function getFieldAccessor(sourceDepthObject, targetDepthObject) {
	        let nodeFn = treeAccessor(sourceDepthObject.fieldDepth, targetDepthObject.fieldDepth, targetDepthObject.pseudoMeasureIndex);
	        let valueFn;
	        if (targetDepthObject.measureIdx >= 0) {
	          valueFn = node => node.data.qValues[targetDepthObject.measureIdx];
	        } else {
	          valueFn = node => node.data;
	        }
	        let attrFn;
	        if (targetDepthObject.attrDimIdx >= 0) {
	          attrFn = data => {
	            var _data$qAttrDims;
	            return data === null || data === void 0 || (_data$qAttrDims = data.qAttrDims) === null || _data$qAttrDims === void 0 ? void 0 : _data$qAttrDims.qValues[targetDepthObject.attrDimIdx];
	          };
	        } else if (targetDepthObject.attrIdx >= 0) {
	          attrFn = data => {
	            var _data$qAttrExps;
	            return data === null || data === void 0 || (_data$qAttrExps = data.qAttrExps) === null || _data$qAttrExps === void 0 ? void 0 : _data$qAttrExps.qValues[targetDepthObject.attrIdx];
	          };
	        }
	        return {
	          nodeFn,
	          attrFn,
	          valueFn
	        };
	      }
	      function datumExtract(propCfg, cell, _ref2) {
	        let {
	          key
	        } = _ref2;
	        const datum = {
	          value: typeof propCfg.value === 'function' ? propCfg.value(cell) : typeof propCfg.value !== 'undefined' ? propCfg.value : cell // eslint-disable-line no-nested-ternary
	        };
	        datum.label = typeof propCfg.label === 'function' ? propCfg.label(cell) : typeof propCfg.label !== 'undefined' ? String(propCfg.label) : String(datum.value); // eslint-disable-line no-nested-ternary

	        if (propCfg.field) {
	          datum.source = {
	            key,
	            field: propCfg.field.key()
	          };
	        }
	        return datum;
	      }
	      function doIt(_ref3) {
	        let {
	          propsArr,
	          props,
	          item,
	          itemData,
	          ret,
	          sourceKey
	        } = _ref3;
	        for (let i = 0; i < propsArr.length; i++) {
	          const pCfg = props[propsArr[i]];
	          const arr = pCfg.fields || [pCfg];
	          let coll;
	          let collStr;
	          if (pCfg.fields) {
	            coll = [];
	            collStr = [];
	          }
	          for (let j = 0; j < arr.length; j++) {
	            const p = arr[j];
	            let fn;
	            let str;
	            let value;
	            let nodes;
	            let cells;
	            let label;
	            if (p.type === 'primitive') {
	              value = p.value;
	              label = String(p.value);
	            } else {
	              if (typeof p.value === 'function') {
	                fn = v => p.value(v, item);
	              }
	              if (typeof p.label === 'function') {
	                str = v => p.label(v, item);
	              }
	              if (p.accessor) {
	                nodes = p.accessor(item);
	                if (Array.isArray(nodes)) {
	                  // propably descendants
	                  cells = nodes.map(p.valueAccessor);
	                  if (p.attrAccessor) {
	                    cells = cells.map(p.attrAccessor);
	                  }
	                  if (fn) {
	                    value = cells.map(fn);
	                    fn = null;
	                  }
	                  if (str) {
	                    label = cells.map(str);
	                    str = null;
	                  }
	                  value = p.reduce ? p.reduce(value) : value;
	                  label = p.reduceLabel ? p.reduceLabel(label, value) : String(value);
	                } else {
	                  value = p.attrAccessor ? p.attrAccessor(p.valueAccessor(nodes)) : p.valueAccessor(nodes);
	                  label = value;
	                }
	              } else {
	                value = itemData;
	                label = itemData;
	              }
	            }
	            if (pCfg.fields) {
	              const v = fn ? fn(value) : value;
	              coll.push(v);
	              collStr.push(str && label != null ? str(label) : label != null ? label : String(v));
	            } else {
	              const v = fn ? fn(value) : value;
	              ret[propsArr[i]] = {
	                value: v,
	                label: str ? str(label) : label != null ? label : String(v)
	              };
	              if (p.field) {
	                ret[propsArr[i]].source = {
	                  field: p.field.key(),
	                  key: sourceKey
	                };
	              }
	            }
	          }
	          if (coll) {
	            ret[propsArr[i]] = {
	              value: typeof pCfg.value === 'function' ? pCfg.value(coll, item) : coll,
	              label: typeof pCfg.label === 'function' ? pCfg.label(collStr, item) : collStr
	            };
	          }
	        }
	      }
	      const getHierarchy = (cube, cache, config) => {
	        const rootPath = cube.qMode === 'K' ? '/qStackedDataPages/*/qData' : '/qTreeDataPages/*';
	        const childNodes = cube.qMode === 'K' ? 'qSubNodes' : 'qNodes';
	        const root = resolve(rootPath, cube);
	        if (!root || !root[0]) {
	          return null;
	        }
	        cache.tree = hierarchy(root[0], config.children || (node => node[childNodes]));
	        return cache.tree;
	      };
	      function getHierarchyForSMode(dataset) {
	        const matrix = dataset.raw().qDataPages.length ? dataset.raw().qDataPages[0].qMatrix : [];
	        const order = getColumnOrder(dataset);
	        const fields = dataset.fields();
	        const dimensions = dataset.fields().filter(f => f.type() === 'dimension').map(f => order.indexOf(fields.indexOf(f)));
	        const measures = dataset.fields().filter(f => f.type() === 'measure').map(f => order.indexOf(fields.indexOf(f)));
	        const root = {
	          __id: '__root',
	          qValues: []
	        };
	        const keys = {
	          __root: root
	        };
	        for (let r = 0; r < matrix.length; r++) {
	          const row = matrix[r];
	          let id = '__root';
	          // let parent = root;
	          let isNew = false;
	          for (let c = 0; c < dimensions.length; c++) {
	            var _cell$qElemNumber;
	            const cell = row[dimensions[c]];
	            const key = "".concat(id, "__").concat((_cell$qElemNumber = cell.qElemNumber) !== null && _cell$qElemNumber !== void 0 ? _cell$qElemNumber : cell.qElemNo);
	            if (!keys[key]) {
	              keys[key] = _objectSpread2({
	                __id: key,
	                __parent: id,
	                qValues: []
	              }, cell);
	              isNew = true;
	            }
	            id = key;
	          }
	          if (isNew) {
	            for (let c = 0; c < measures.length; c++) {
	              const cell = row[measures[c]];
	              keys[id].qValues.push(cell);
	            }
	          }
	        }
	        const nodes = Object.keys(keys).map(key => keys[key]);
	        const h = stratify().id(d => d.__id).parentId(d => d.__parent)(nodes);
	        return h;
	      }
	      const attachPropsAccessors = _ref4 => {
	        let {
	          propsArr,
	          props,
	          cube,
	          cache,
	          itemDepthObject,
	          f
	        } = _ref4;
	        for (let i = 0; i < propsArr.length; i++) {
	          const pCfg = props[propsArr[i]];
	          const arr = pCfg.fields ? pCfg.fields : [pCfg];
	          for (let j = 0; j < arr.length; j++) {
	            const p = arr[j];
	            if (p.field !== f) {
	              const depthObject = getFieldDepth(p.field, {
	                cube});
	              const accessors = getFieldAccessor(itemDepthObject, depthObject);
	              p.accessor = accessors.nodeFn; // nodes accessor
	              p.valueAccessor = accessors.valueFn; // cell accessor
	              p.attrAccessor = accessors.attrFn; // attr cell accessor
	            }
	          }
	        }
	      };
	      function augment() {
	        let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	        let dataset = arguments.length > 1 ? arguments[1] : undefined;
	        let cache = arguments.length > 2 ? arguments[2] : undefined;
	        let util = arguments.length > 3 ? arguments[3] : undefined;
	        const cube = dataset.raw();
	        const sourceKey = dataset.key();
	        const h = cube.qMode === 'S' ? getHierarchyForSMode(dataset) : getHierarchy(cube, cache, config);
	        if (!h) {
	          return null;
	        }
	        const height = h.height;
	        const propDefs = [];
	        for (let i = 0; i <= height; i++) {
	          let f = null;
	          if (i > 0) {
	            if (cube.qMode === 'S') {
	              const order = getDimensionColumnOrder(cube);
	              let idx = order[i - 1];
	              f = cache.fields[idx];
	            } else {
	              let idx = cube.qEffectiveInterColumnSortOrder[i - 1];
	              // if (idx === -1) { // pseudo
	              //   let childIdx = node.parent.children.indexOf(node);
	              //   idx = cube.qDimensionInfo.length + childIdx; // measure field
	              // }
	              if (i > cube.qEffectiveInterColumnSortOrder.length) {
	                idx = cube.qDimensionInfo.length;
	              }
	              f = cache.fields[idx];
	            }
	          }
	          const {
	            props,
	            main
	          } = util.normalizeConfig(_objectSpread2(_objectSpread2({}, config), {}, {
	            field: f ? f.key() : undefined
	          }), dataset);
	          const propsArr = Object.keys(props);
	          propDefs[i] = {
	            propsArr,
	            props,
	            main
	          };
	          const itemDepthObject = f ? getFieldDepth(f, {
	            cube}) : {
	            fieldDepth: 0
	          };
	          attachPropsAccessors({
	            propsArr,
	            props,
	            cube,
	            cache,
	            itemDepthObject,
	            f
	          });
	        }
	        const replica = h.copy();
	        const replicaDescendants = replica.descendants();
	        const descendants = h.descendants();
	        for (let i = 0; i < descendants.length; i++) {
	          const propsArr = propDefs[descendants[i].depth].propsArr;
	          const props = propDefs[descendants[i].depth].props;
	          const main = propDefs[descendants[i].depth].main;
	          const item = replicaDescendants[i];
	          const itemData = item.data; // main.valueAccessor(currentOriginal);

	          const ret = datumExtract(main, itemData, {
	            key: sourceKey
	          });
	          doIt({
	            propsArr,
	            props,
	            item,
	            itemData,
	            ret,
	            sourceKey});
	          descendants[i].data = ret;
	        }
	        return h;
	      }
	      function extract(config, dataset, cache, util) {
	        const cfgs = Array.isArray(config) ? config : [config];
	        let dataItems = [];
	        for (let g = 0; g < cfgs.length; g++) {
	          if (typeof cfgs[g].field !== 'undefined') {
	            const cube = dataset.raw();
	            const sourceKey = dataset.key();
	            const h = getHierarchy(cube, cache, config);
	            if (!h) {
	              continue;
	            }
	            const f = typeof cfgs[g].field === 'object' ? cfgs[g].field : dataset.field(cfgs[g].field);
	            const {
	              props,
	              main
	            } = util.normalizeConfig(cfgs[g], dataset);
	            const propsArr = Object.keys(props);
	            const itemDepthObject = getFieldDepth(f, {
	              cube});
	            const {
	              nodeFn,
	              attrFn,
	              valueFn
	            } = getFieldAccessor({
	              fieldDepth: 0
	            }, itemDepthObject);
	            attachPropsAccessors({
	              propsArr,
	              props,
	              cube,
	              cache,
	              itemDepthObject,
	              f
	            });
	            const track = !!cfgs[g].trackBy;
	            const trackType = typeof cfgs[g].trackBy;
	            const tracker = {};
	            const trackedItems = [];
	            const items = nodeFn(cache.tree);
	            const mapped = [];
	            for (let i = 0; i < items.length; i++) {
	              const item = items[i];
	              const itemData = attrFn ? attrFn(valueFn(item)) : valueFn(item);
	              const exclude = main.filter && !main.filter(itemData);
	              if (exclude) {
	                continue;
	              }
	              const ret = datumExtract(main, itemData, {
	                key: sourceKey
	              });
	              doIt({
	                propsArr,
	                props,
	                item,
	                itemData,
	                ret,
	                sourceKey
	              });
	              // collect items based on the trackBy value
	              // items with the same trackBy value are placed in an array and reduced later
	              if (track) {
	                util.track({
	                  cfg: cfgs[g],
	                  itemData,
	                  obj: ret,
	                  target: trackedItems,
	                  tracker,
	                  trackType
	                });
	              }
	              mapped.push(ret);
	            }
	            // reduce if items have been grouped
	            const tmp = track ? util.collect(trackedItems, {
	              main,
	              propsArr,
	              props
	            }) : mapped;
	            dataItems = [...dataItems, ...tmp];
	          }
	        }
	        return dataItems;
	      }
	      var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof commonjsGlobal$1 !== 'undefined' ? commonjsGlobal$1 : typeof self !== 'undefined' ? self : {};
	      function createCommonjsModule(fn, module) {
	        return module = {
	          exports: {}
	        }, fn(module, module.exports), module.exports;
	      }
	      var format_min = createCommonjsModule(function (module) {
	        /*! javascript-number-formatter - v1.1.11 - http://mottie.github.com/javascript-number-formatter/ * © ecava */
	        !function (a, b) {
	          module.exports = b();
	        }(commonjsGlobal, function () {
	          return function (a, b) {
	            if (!a || isNaN(+b)) return b;
	            var c,
	              d,
	              e,
	              f,
	              g,
	              h,
	              i,
	              j,
	              k,
	              l,
	              m = a.length,
	              n = a.search(/[0-9\-\+#]/),
	              o = n > 0 ? a.substring(0, n) : "",
	              p = a.split("").reverse().join(""),
	              q = p.search(/[0-9\-\+#]/),
	              r = m - q,
	              s = a.substring(r, r + 1),
	              t = r + ("." === s || "," === s ? 1 : 0),
	              u = q > 0 ? a.substring(t, m) : "";
	            if (a = a.substring(n, t), b = "-" === a.charAt(0) ? -b : +b, c = b < 0 ? b = -b : 0, d = a.match(/[^\d\-\+#]/g), e = d && d[d.length - 1] || ".", f = d && d[1] && d[0] || ",", a = a.split(e), b = b.toFixed(a[1] && a[1].length), b = +b + "", h = a[1] && a[1].lastIndexOf("0"), j = b.split("."), (!j[1] || j[1] && j[1].length <= h) && (b = (+b).toFixed(h + 1)), k = a[0].split(f), a[0] = k.join(""), g = a[0] && a[0].indexOf("0"), g > -1) for (; j[0].length < a[0].length - g;) j[0] = "0" + j[0];else 0 === +j[0] && (j[0] = "");
	            if (b = b.split("."), b[0] = j[0], i = k[1] && k[k.length - 1].length) {
	              for (l = b[0], p = "", r = l.length % i, m = l.length, t = 0; t < m; t++) p += l.charAt(t), !((t - r + 1) % i) && t < m - i && (p += f);
	              b[0] = p;
	            }
	            return b[1] = a[1] && b[1] ? e + b[1] : "", d = b.join(""), "0" !== d && "" !== d || (c = false), o + ((c ? "-" : "") + d) + u;
	          };
	        });
	      });

	      // 1.95.toFixed(1) = 1.9
	      // 2.95.toFixed(1) = 3.0
	      const EPSILON = 1e-15; // To make sure toFixed always round up.

	      function escapeRegExp(str) {
	        return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
	      }
	      const SIprefixes = {
	          3: 'k',
	          6: 'M',
	          9: 'G',
	          12: 'T',
	          15: 'P',
	          18: 'E',
	          21: 'Z',
	          24: 'Y',
	          '-3': 'm',
	          '-6': 'μ',
	          '-9': 'n',
	          '-12': 'p',
	          '-15': 'f',
	          '-18': 'a',
	          '-21': 'z',
	          '-24': 'y'
	        },
	        percentage = /%\)?$/,
	        //    scientific = /e[\+\-][0-9]+/,
	        radix = /^\(r(0[2-9]|[12]\d|3[0-6])\)/i,
	        oct = /^\(oct\)/i,
	        dec = /^\(dec\)/i,
	        hex = /^\(hex\)/i,
	        bin = /^\(bin\)/i,
	        rom = /^\(rom\)/i,
	        functional = /^(\(rom\)|\(bin\)|\(hex\)|\(dec\)|\(oct\)|\(r(0[2-9]|[12]\d|3[0-6])\))/i,
	        prec = /#|0/g;
	      function formatRadix(value, fradix, pattern, decimal) {
	        value = value.toString(fradix);
	        if (pattern[1] === pattern[1].toUpperCase()) {
	          value = value.toUpperCase();
	        }
	        if (value.length - value.indexOf('.') > 10) {
	          // limit to 10 decimal places
	          value = value.slice(0, value.indexOf('.') + 11);
	        }
	        return value.replace('.', decimal || '.');
	      }

	      // value must be an integer
	      // value must not be in scientific notation
	      function formatRoman(value, pattern) {
	        let i,
	          s = '',
	          v = Number(String(value).slice(-3)),
	          nThousands = (value - v) / 1000,
	          decimal = [0, 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900].reverse(),
	          numeral = ['0', 'I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM'].reverse();
	        while (v > 0) {
	          for (i = 0; i < decimal.length; i++) {
	            if (decimal[i] <= v) {
	              s += numeral[i];
	              v -= decimal[i];
	              break;
	            }
	          }
	        }
	        for (i = 0; i < nThousands; i++) {
	          s = "M".concat(s);
	        }
	        if (pattern[1] !== pattern[1].toUpperCase()) {
	          s = s.toLowerCase();
	        }
	        return s;
	      }
	      function formatFunctional(value, pattern, d) {
	        let temp;
	        if (radix.test(pattern)) {
	          value = formatRadix(value, Number(/\d{2}/.exec(pattern)[0]), pattern, d);
	        } else if (oct.test(pattern)) {
	          value = formatRadix(value, 8, pattern, d);
	        } else if (dec.test(pattern)) {
	          value = formatRadix(value, 10, pattern, d);
	        } else if (hex.test(pattern)) {
	          value = formatRadix(value, 16, pattern, d);
	        } else if (bin.test(pattern)) {
	          value = formatRadix(value, 2, pattern, d);
	        } else if (rom.test(pattern)) {
	          temp = '';
	          if (value < 0) {
	            temp = '-';
	            value = -value;
	          }
	          value = Math.floor(value);
	          if (value === 0) {
	            value = '0';
	          } else if (value <= 500000) {
	            // limit in engine
	            value = formatRoman(value, pattern);
	            value = temp + value;
	          } else {
	            value = pattern + temp + value.toExponential(0); // to return same result as engine
	          }
	        }
	        return value;
	      }
	      function escape(value, flags, justStr) {
	        const str = escapeRegExp(value);
	        if (justStr) {
	          return str;
	        }
	        return new RegExp(str || '', flags);
	      }
	      function createRegExp(thousand, decimal) {
	        if (decimal) {
	          decimal = escapeRegExp(decimal);
	        }
	        if (thousand) {
	          thousand = escapeRegExp(thousand);
	        }
	        return new RegExp("(?:[#0]+".concat(thousand, ")?[#0]+(?:").concat(decimal, "[#0]+)?"));
	      }
	      function getAbbreviations(localeInfo, listSeparator) {
	        if (!localeInfo || !localeInfo.qNumericalAbbreviation) {
	          return SIprefixes;
	        }
	        const abbreviations = {};
	        let abbrs = localeInfo.qNumericalAbbreviation.split(listSeparator);
	        abbrs.forEach(abbreviation => {
	          let abbreviationTuple = abbreviation.split(':');
	          if (abbreviationTuple.length === 2) {
	            abbreviations[abbreviationTuple[0]] = abbreviationTuple[1];
	          }
	        });
	        return abbreviations;
	      }
	      function preparePattern(o, t, d, abbreviate) {
	        let parts,
	          lastPart,
	          pattern = o.pattern,
	          numericPattern,
	          prefix,
	          postfix,
	          groupTemp,
	          decTemp,
	          temp,
	          regex;
	        if (abbreviate) {
	          o.abbreviate = true;
	        }

	        // extract the numeric part from the pattern
	        regex = createRegExp(t, d);
	        numericPattern = pattern.match(regex);
	        numericPattern = numericPattern ? numericPattern[0] : '';
	        prefix = numericPattern ? pattern.substr(0, pattern.indexOf(numericPattern)) : pattern;
	        postfix = numericPattern ? pattern.substring(pattern.indexOf(numericPattern) + numericPattern.length) : '';
	        if (!numericPattern) {
	          numericPattern = pattern ? '#' : '##########';
	        }
	        if (t && t === d) {
	          // ignore grouping if grouping separator is same as decimal separator
	          // extract decimal part
	          parts = numericPattern.split(d);
	          lastPart = parts.pop();
	          numericPattern = parts.join('') + d + lastPart;
	          t = '';
	        }

	        // formatting library does not support multiple characters as separator (nor +-).
	        // do a temporary replacement
	        groupTemp = t;
	        t = /,/.test(d) ? '¤' : ',';
	        if (groupTemp) {
	          numericPattern = numericPattern.replace(escape(groupTemp, 'g'), t);
	        }
	        decTemp = d;
	        d = '.';
	        if (decTemp) {
	          numericPattern = numericPattern.replace(escape(decTemp, 'g'), d);
	        }
	        temp = numericPattern.match(/#/g);
	        temp = temp ? temp.length : 0;
	        const splitPattern = pattern.split(decTemp);
	        let matchPrecisionResult;
	        if (splitPattern[1]) {
	          matchPrecisionResult = splitPattern[1].match(prec);
	        }
	        o.prefix = prefix || '';
	        o.postfix = postfix || '';
	        o.pattern = pattern;
	        o.maxPrecision = matchPrecisionResult ? matchPrecisionResult.length : 2;
	        o.percentage = percentage.test(pattern);
	        o.numericPattern = numericPattern || '';
	        o.numericRegex = new RegExp("".concat(escape(t, null, true), "|").concat(escape(d, null, true)), 'g');
	        o.groupTemp = groupTemp;
	        o.decTemp = decTemp;
	        o.t = t;
	        o.d = d;
	        o.temp = temp;
	      }
	      class NumberFormatter {
	        /**
	         * @name NumberFormatter
	         * @constructs
	         * @param {Object} localeInfo
	         * @param {String} pattern
	         * @param {String} [thousand]
	         * @param {String} [decimal]
	         * @param {String} [type]
	         */
	        constructor(localeInfo, pattern, thousand, decimal, type) {
	          this.localeInfo = localeInfo;
	          this.pattern = pattern;
	          this.thousandDelimiter = thousand || ',';
	          this.decimalDelimiter = decimal || '.';
	          this.type = type || 'numeric';

	          // FIXME qListSep?
	          // this.patternSeparator = this.localeInfo && this.localeInfo.qListSep ? this.localeInfo.qListSep : ';';
	          this.patternSeparator = ';';
	          this.abbreviations = getAbbreviations(localeInfo, this.patternSeparator);
	          this.prepare();
	        }
	        clone() {
	          const n = new NumberFormatter(this.localeInfo, this.pattern, this.thousandDelimiter, this.decimalDelimiter, this.type);
	          n.subtype = this.subtype;
	          return n;
	        }

	        /**
	         * Formats a number according to a specific pattern.
	         * Use # for optional numbers and 0 for padding.
	         * @param {Number} value Number to format.
	         * @param {String} [pattern] The pattern to apply.
	         * @param {String} [t] Grouping separator.
	         * @param {String} [d] Decimal delimiter.
	         * @example
	         * format(10, "0") // 10;
	         * format(10, "#") // 10;
	         * format(10, "##.#") // 10;
	         * format(10, "##.0") // 10.0;
	         * format(10, "000") // 010;
	         * format(10.123, "0.0") // 10.1;
	         * format(10.123, "0.00##") // 10.123; // at least 2 decimals, never more than 4
	         * format(123456789, "#,###") // 123,456,789;
	         * format(123456789, "####-####", "-") // 1-2345-6789;
	         *
	         * format(0.257, "0.0%") // 25.7%; // will multiply by 100
	         * format(9876, "$#,###") // $9,876;
	         * format(-9876, "$#,###;$(#,###)") // $(9,876); // use ; for alternative formatting for negative values
	         * format(10, "(r16)") // a; // radix 16
	         * format(15, "(hex)") // f; // same as (r16)
	         * format(15, "(HEX)") // F;
	         * format(10, "(bin)") // 1010; // same as (r02)
	         * format(10, "(oct)") // 12; // same as (r08)
	         */
	        format(value, pattern, t, d) {
	          this.prepare(pattern, t, d);
	          return this.formatValue(value);
	        }
	        prepare(pattern, t, d) {
	          let prep;
	          if (typeof pattern === 'undefined') {
	            pattern = this.pattern;
	          }
	          if (typeof t === 'undefined') {
	            t = this.thousandDelimiter;
	          }
	          if (typeof d === 'undefined') {
	            d = this.decimalDelimiter;
	          }
	          if (!pattern) {
	            this._prepared = {
	              pattern: false
	            };
	            return;
	          }
	          this._prepared = {
	            positive: {
	              d,
	              t,
	              abbreviate: false,
	              isFunctional: false,
	              prefix: '',
	              postfix: ''
	            },
	            negative: {
	              d,
	              t,
	              abbreviate: false,
	              isFunctional: false,
	              prefix: '',
	              postfix: ''
	            },
	            zero: {
	              d,
	              t,
	              abbreviate: false,
	              isFunctional: false,
	              prefix: '',
	              postfix: ''
	            }
	          };
	          prep = this._prepared;
	          pattern = pattern.split(this.patternSeparator);
	          prep.positive.pattern = pattern[0];
	          prep.negative.pattern = pattern[1];
	          prep.zero.pattern = pattern[2];
	          if (functional.test(pattern[0])) {
	            prep.positive.isFunctional = true;
	          }
	          if (!pattern[1]) {
	            prep.negative = false;
	          } else if (functional.test(pattern[1])) {
	            prep.negative.isFunctional = true;
	          }
	          if (!pattern[2]) {
	            prep.zero = false;
	          } else if (functional.test(pattern[2])) {
	            prep.zero.isFunctional = true;
	          }
	          const abbreviate = this.type === 'U';
	          if (!prep.positive.isFunctional) {
	            preparePattern(prep.positive, t, d, abbreviate);
	          }
	          if (prep.negative && !prep.negative.isFunctional) {
	            preparePattern(prep.negative, t, d, abbreviate);
	          }
	          if (prep.zero && !prep.zero.isFunctional) {
	            preparePattern(prep.zero, t, d, abbreviate);
	          }
	        }
	        formatValue(value) {
	          let prep = this._prepared,
	            temp,
	            exponent,
	            abbr = '',
	            absValue,
	            num,
	            sciValue = '',
	            d,
	            t,
	            i,
	            numericPattern,
	            decimalPartPattern,
	            original = value;
	          if (isNaN(value)) {
	            return "".concat(original);
	          }
	          value = +value;
	          if (prep.pattern === false) {
	            return value.toString();
	          }
	          if (value === 0 && prep.zero) {
	            prep = prep.zero;
	            return prep.pattern;
	          }
	          if (value < 0 && prep.negative) {
	            prep = prep.negative;
	            value = -value;
	          } else {
	            prep = prep.positive;
	          }
	          d = prep.d;
	          t = prep.t;
	          if (prep.isFunctional) {
	            value = formatFunctional(value, prep.pattern, d);
	          } else {
	            if (prep.percentage) {
	              value *= 100;
	            }
	            if (prep.abbreviate) {
	              const abbrArray = Object.keys(this.abbreviations).map(key => parseInt(key, 10)).sort((a, b) => a - b);
	              let lowerAbbreviation;
	              let upperAbbreviation = abbrArray[0];
	              i = 0;
	              exponent = Number(Number(value).toExponential().split('e')[1]);
	              while (upperAbbreviation <= exponent && i < abbrArray.length) {
	                i++;
	                upperAbbreviation = abbrArray[i];
	              }
	              if (i > 0) {
	                lowerAbbreviation = abbrArray[i - 1];
	              }
	              let suggestedAbbrExponent;

	              // value and lower abbreviation is for values above 10, use the lower (move to the left <==)
	              if (lowerAbbreviation && exponent > 0 && lowerAbbreviation > 0) {
	                suggestedAbbrExponent = lowerAbbreviation;
	                // value and lower abbreviation is for values below 0.1 (move to the right ==>)
	              } else if (exponent < 0 && lowerAbbreviation < 0 || !lowerAbbreviation) {
	                // upper abbreviation is also for values below 0.1 and precision allows for using the upper abbreviation(move to the right ==>)
	                if (upperAbbreviation < 0 && upperAbbreviation - exponent <= prep.maxPrecision) {
	                  suggestedAbbrExponent = upperAbbreviation;
	                  // lower abbrevaition is smaller than exponent and we can't get away with not abbreviating
	                } else if (lowerAbbreviation <= exponent && !(upperAbbreviation > 0 && -exponent <= prep.maxPrecision)) {
	                  // (move to left <==)
	                  suggestedAbbrExponent = lowerAbbreviation;
	                }
	              }
	              if (suggestedAbbrExponent) {
	                abbr = this.abbreviations[suggestedAbbrExponent];
	                value /= 10 ** suggestedAbbrExponent;
	              }
	            }
	            absValue = Math.abs(value);
	            temp = prep.temp;
	            numericPattern = prep.numericPattern;
	            decimalPartPattern = numericPattern.split(d)[1];
	            if (this.type === 'I') {
	              value = Math.round(value);
	            }
	            num = value;
	            if (!decimalPartPattern && numericPattern.slice(-1)[0] === '#') {
	              if (absValue >= 10 ** temp || absValue < 1 || absValue < 1e-4) {
	                if (value === 0) {
	                  value = '0';
	                } else if (absValue < 1e-4 || absValue >= 1e20) {
	                  // engine always formats values < 1e-4 in scientific form, values >= 1e20 can only be represented in scientific form
	                  value = num.toExponential(Math.max(1, Math.min(14, temp)) - 1);
	                  value = value.replace(/\.?0+(?=e)/, '');
	                  sciValue = '';
	                } else {
	                  value = value.toPrecision(Math.max(1, Math.min(14, temp)));
	                  if (value.indexOf('.') >= 0) {
	                    value = value.replace(value.indexOf('e') < 0 ? /0+$/ : /\.?0+(?=e)/, '');
	                    value = value.replace('.', d);
	                  }
	                }
	              } else {
	                numericPattern += d;
	                temp = Math.max(0, Math.min(20, temp - Math.ceil(Math.log(absValue) / Math.log(10))));
	                for (i = 0; i < temp; i++) {
	                  numericPattern += '#';
	                }
	                value = format_min(numericPattern, value);
	              }
	            } else if (absValue >= 1e15 || absValue > 0 && absValue <= 1e-14) {
	              value = absValue ? absValue.toExponential(15).replace(/\.?0+(?=e)/, '') : '0';
	            } else {
	              const sign = value < 0 ? -1 : 1;
	              const wholePart = Number((value + EPSILON * sign).toFixed(Math.min(20, decimalPartPattern ? decimalPartPattern.length : 0)).split('.')[0]);
	              let wholePartPattern = numericPattern.split(d)[0];
	              wholePartPattern += d;
	              value = format_min(wholePartPattern, wholePart) || '0';
	              if (decimalPartPattern) {
	                const nDecimals = Math.max(0, Math.min(14, decimalPartPattern.length)); // the length of e.g. 0000#####
	                const nZeroes = decimalPartPattern.replace(/#+$/, '').length;
	                let decimalPart = (this.type === 'I' ? 0 : absValue % 1 + EPSILON).toFixed(nDecimals).slice(2).replace(/0+$/, ''); // remove trailing zeroes

	                for (i = decimalPart.length; i < nZeroes; i++) {
	                  decimalPart += '0';
	                }
	                if (decimalPart) {
	                  value += d + decimalPart;
	                }
	              } else if (wholePart === 0) {
	                // to avoid "-" being prefixed to value
	                num = 0;
	              }
	            }
	            value = value.replace(prep.numericRegex, m => {
	              if (m === t) {
	                return prep.groupTemp;
	              }
	              if (m === d) {
	                return prep.decTemp;
	              }
	              return '';
	            });
	            if (num < 0 && !/^-/.test(value)) {
	              value = "-".concat(value);
	            }
	          }
	          return prep.prefix + value + sciValue + abbr + prep.postfix;
	        }
	        static getStaticFormatter() {
	          return {
	            prepare() {},
	            formatValue(v) {
	              return "".concat(v);
	            }
	          };
	        }
	      }
	      function numberFormatFactory() {
	        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
	          args[_key] = arguments[_key];
	        }
	        return new NumberFormatter(...args);
	      }
	      function memoize(func) {
	        let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	        const {
	          size = 5000,
	          multipleArguments = false,
	          toKey = arg => arg
	        } = opts;
	        let cache = Object.create(null);
	        let index = Object.create(null);
	        let counter = 0;
	        let fifo = 0; // First-In-First-Out index
	        let cacher;
	        let k;
	        if (multipleArguments) {
	          cacher = function () {
	            k = toKey(...arguments);
	            if (cacher.has(k)) {
	              return cacher.get(k);
	            }
	            return cacher.set(k, func(...arguments));
	          };
	        } else {
	          cacher = arg => {
	            k = toKey(arg);
	            if (cacher.has(k)) {
	              return cacher.get(k);
	            }
	            return cacher.set(k, func(arg));
	          };
	        }
	        cacher.set = (key, val) => {
	          if (counter >= size) {
	            delete cache[index[fifo]];
	            delete index[fifo];
	            counter--;
	            fifo++;
	          }
	          cache[key] = val;
	          index[counter] = key;
	          counter++;
	          return val;
	        };
	        cacher.get = key => cache[key];
	        cacher.has = key => key in cache;
	        cacher.clear = () => {
	          cache = Object.create(null);
	          index = Object.create(null);
	          counter = 0;
	          fifo = 0;
	        };
	        cacher.size = () => counter;
	        return cacher;
	      }
	      function formatter$1(pattern, thousand, decimal, qType, localeInfo) {
	        const qformat = numberFormatFactory(localeInfo, pattern, thousand, decimal, qType);
	        const memoized = memoize(qformat.formatValue.bind(qformat), {
	          // Handle NaN and cases where toString yields different result than +operator. Ex. a Date.
	          toKey: value => isNaN(value) ? value : +value
	        });

	        /**
	         * Format a value according to the specified pattern created at construct
	         *
	         * @param  {Number} value   The number to be formatted
	         * @return {String}         [description]
	         */
	        function format(value) {
	          return memoized(value);
	        }

	        /**
	         * Format a value according to a specific pattern
	         * that is not the one specified in the constructor
	         *
	         * @param  {String} p   Pattern
	         * @param  {Number} v   Value
	         * @param  {String} t   Thousand
	         * @param  {String} d   Decimal
	         * @return {String}     Formatted value
	         */
	        format.format = function formatFn(p, v, t, d) {
	          memoized.clear();
	          return qformat.format(v, p, t, d);
	        };

	        /**
	         * Change the pattern on existing formatter
	         *
	         * @param  {String} p     Pattern (optional)
	         * @return {String}       Returns the pattern
	         */
	        format.pattern = function patternFn(p) {
	          if (p) {
	            memoized.clear();
	            qformat.pattern = p;
	            qformat.prepare();
	          }
	          return qformat.pattern;
	        };

	        /**
	         * Set the locale for the formatter
	         *
	         * @param  {Object} args   Locale object for formatting
	         * @return {Undefined}      Returns nothing
	         */
	        /* format.locale = function( ...args ) {
	          locale = formatLocale( ...args );
	          d3format = locale.format( pattern );
	           return this;
	        }; */

	        return format;
	      }

	      /* eslint import/prefer-default-export: 0 */

	      const TYPES = {
	        DATE: 'D',
	        TIME: 'T',
	        DATE_TIME: 'TS',
	        INTERVAL: 'IV'
	      };
	      const DAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
	      const DAYS_ABBR = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
	      const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
	      const MONTHS_ABBR = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
	      const SECONDS_PER_DAY = 86400;
	      function pad(s, n) {
	        for (let i = s.length; i < n; i++) {
	          s = "0".concat(s);
	        }
	        return s;
	      }
	      function parseDate(d, twelveFormat) {
	        let h = d.getUTCHours();
	        let day = d.getUTCDay() - 1;
	        if (twelveFormat) {
	          h %= 12;
	          if (!h) {
	            // h == 0 -> 12
	            h = 12;
	          }
	        }
	        if (day < 0) {
	          day = 6;
	        }
	        return {
	          year: d.getUTCFullYear(),
	          month: d.getUTCMonth(),
	          day,
	          date: d.getUTCDate(),
	          h,
	          m: d.getUTCMinutes(),
	          s: d.getUTCSeconds(),
	          f: d.getUTCMilliseconds(),
	          t: d.getUTCHours() >= 12 ? 'pm' : 'am'
	        };
	      }
	      function getRemainder(value) {
	        let s = value.toString().split('.');
	        if (s[1]) {
	          s = Number("0.".concat(s[1]));
	        } else {
	          return 0;
	        }
	        return s;
	      }
	      function parseIntervalDays(days) {
	        const d = days;
	        const h = 24 * getRemainder(d);
	        const m = 60 * getRemainder(h);
	        const s = 60 * getRemainder(m);
	        const ms = 1000 * getRemainder(s);
	        return {
	          d: Math.floor(d),
	          h: Math.floor(h),
	          m: Math.floor(m),
	          s: Math.floor(s),
	          f: Math.round(ms)
	        };
	      }
	      function parseInterval(days, pattern) {
	        let units = parseIntervalDays(days),
	          d = units.d,
	          h = units.h,
	          m = units.m,
	          s = units.s,
	          f = units.f,
	          w = 0,
	          date;
	        if (/w+|t+/gi.test(pattern)) {
	          date = new Date(Date.UTC(1899, 11, 30 + Math.floor(days), 0, 0, Math.round(SECONDS_PER_DAY * (days - Math.floor(days)))));
	          if (isNaN(date.getTime())) {
	            date = null;
	          }
	        }
	        if (!/D+/gi.test(pattern)) {
	          h += d * 24;
	        }
	        if (!/h+/gi.test(pattern)) {
	          m += h * 60;
	        }
	        if (!/m+/gi.test(pattern)) {
	          s += m * 60;
	        }
	        if (/w+/gi.test(pattern)) {
	          w = date ? date.getDay() - 1 : 0;
	          if (w < 0) {
	            w = 6;
	          }
	        }
	        let someT = '';
	        if (date) {
	          someT = date.getUTCHours() >= 12 ? 'pm' : 'am';
	        }
	        return {
	          year: 0,
	          month: 0,
	          day: w,
	          date: d,
	          h,
	          m,
	          s,
	          f,
	          t: someT
	        };
	      }
	      function getMasks(inst, d) {
	        return {
	          'Y+|y+': {
	            Y: "".concat(Number("".concat(d.year).slice(-2))),
	            YY: pad("".concat(d.year).slice(-2), 2),
	            YYY: pad("".concat(d.year).slice(-3), 3),
	            def(m) {
	              // default
	              return pad("".concat(d.year), m.length);
	            }
	          },
	          'M+': {
	            M: d.month + 1,
	            MM: pad("".concat(d.month + 1), 2),
	            MMM: inst.locale_months_abbr[d.month],
	            def: inst.locale_months[d.month]
	          },
	          'W+|w+': {
	            W: d.day,
	            WW: pad("".concat(d.day), 2),
	            WWW: inst.locale_days_abbr[d.day],
	            def: inst.locale_days[d.day]
	          },
	          'D+|d+': {
	            D: d.date,
	            def(m) {
	              return pad("".concat(d.date), m.length);
	            }
	          },
	          'h+|H+': {
	            h: d.h,
	            def(m) {
	              return pad("".concat(d.h), m.length);
	            }
	          },
	          'm+': {
	            m: d.m,
	            def(m) {
	              return pad("".concat(d.m), m.length);
	            }
	          },
	          's+|S+': {
	            s: d.s,
	            def(m) {
	              return pad("".concat(d.s), m.length);
	            }
	          },
	          'f+|F+': {
	            def(m) {
	              let f = "".concat(d.f),
	                n = m.length - f.length;
	              if (n > 0) {
	                for (let i = 0; i < n; i++) {
	                  f += '0';
	                }
	              } else if (n < 0) {
	                f = f.slice(0, m.length);
	              }
	              return f;
	            }
	          },
	          't{1,2}|T{1,2}': {
	            def(m) {
	              let t = d.t;
	              if (m[0].toUpperCase() === m[0]) {
	                t = t.toUpperCase();
	              }
	              t = t.slice(0, m.length);
	              return t;
	            }
	          }
	        };
	      }
	      class DateFormatter {
	        /**
	         * @name DateFormatter
	         * @constructs
	         * @param {Object} localeInfo
	         * @param {String} pattern
	         */
	        constructor(localeInfo, pattern, qtype) {
	          const info = localeInfo || {};
	          if (!info.qCalendarStrings) {
	            info.qCalendarStrings = {
	              qLongDayNames: DAYS,
	              qDayNames: DAYS_ABBR,
	              qLongMonthNames: MONTHS,
	              qMonthNames: MONTHS_ABBR
	            };
	          }
	          this.localeInfo = info;
	          this.locale_days = info.qCalendarStrings.qLongDayNames.slice();
	          this.locale_days_abbr = info.qCalendarStrings.qDayNames.slice();
	          this.locale_months = info.qCalendarStrings.qLongMonthNames.slice();
	          this.locale_months_abbr = info.qCalendarStrings.qMonthNames.slice();
	          if (!pattern) {
	            const patternMap = {
	              [TYPES.TIME]: info.qTimeFmt || 'hh:mm:ss',
	              [TYPES.DATE]: info.qDateFmt || 'YYYY-MM-DD',
	              [TYPES.DATE_TIME]: info.qTimestampFmt || 'YYYY-MM-DD hh:mm:ss'
	            };
	            pattern = patternMap[qtype];
	          }
	          this.pattern = pattern;
	        }
	        clone() {
	          const n = new DateFormatter(this.localeInfo, this.pattern);
	          n.subtype = this.subtype;
	          return n;
	        }

	        /**
	         * Formats a date according to given pattern
	         * @param {Date} date The date to format.
	         * @param {String} pattern The desired format of the date
	         * var d = new Date(2013, 8, 15, 13, 55, 40, 987);
	         * var n = new DateFormatter();
	         * @example
	         * m.format( d, 'YYYY-MM-DD hh:mm:ss.ffff') // 2013-08-15 13:55:40.9870
	         * m.format( d, 'h:m:s tt') // 1:55:40 pm
	         * m.format( d, 'h:m:s TT') // 1:55:40 PM
	         * m.format( d, 'M/D/YYYY') // 8/15/2013
	         * m.format( d, 'WWWW DD MMM') // Thursday 15 Aug
	         * m.format( d, 'WWW DD MMMM @ hh:mm:ss') // Thu 15 August @ 13:55:40
	         */
	        format(date, pattern) {
	          // Fallback pattern is set in constructor
	          if (!pattern) {
	            pattern = this.pattern ? this.pattern : 'YYYY-MM-DD hh:mm:ss';
	          }
	          pattern = pattern.replace(/\[.+]|\[|]/g, '');
	          const hasTwelveFlag = /t+/gi.test(pattern);
	          let parsedDate;
	          if (date instanceof Date) {
	            parsedDate = parseDate(date, hasTwelveFlag);
	          } else {
	            if (date < 0) {
	              // parseInterval don't support for negative values
	              date = -date;
	              pattern = "-".concat(pattern);
	            }
	            parsedDate = parseInterval(date, pattern);
	          }
	          // remove [] and everything inside it

	          const masks = getMasks(this, parsedDate);
	          const masksArr = [];
	          for (const mask in masks) {
	            if (Object.prototype.hasOwnProperty.call(masks, mask)) {
	              masksArr.push(mask);
	            }
	          }
	          const dateTimeRegex = new RegExp(masksArr.join('|'), 'g');
	          const result = pattern.replace(dateTimeRegex, m => {
	            let r;
	            let mask;
	            for (mask in masks) {
	              if (Object.prototype.hasOwnProperty.call(masks, mask)) {
	                r = new RegExp(mask);
	                if (r.test(m)) {
	                  break;
	                }
	              }
	            }
	            if (!r) {
	              return '';
	            }
	            let value;
	            for (const submask in masks[mask]) {
	              if (submask === m || submask.toLowerCase() === m) {
	                value = masks[mask][submask];
	                if (typeof value === 'undefined') {
	                  value = masks[mask][submask.toLowerCase()];
	                }
	                break;
	              }
	            }
	            if (typeof value === 'undefined') {
	              value = masks[mask].def;
	            }
	            if (typeof value === 'function') {
	              value = value(m);
	            }
	            return value;
	          });
	          return result;
	        }
	      }
	      function dateFormatFactory() {
	        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
	          args[_key] = arguments[_key];
	        }
	        return new DateFormatter(...args);
	      }
	      const MS_PER_DAY = 86400000;
	      function QlikTimeToDate(value) {
	        return new Date(Date.UTC(1899, 11, 30 + Math.floor(value), 0, 0, 0, Math.round(MS_PER_DAY * (value - Math.floor(value)))));
	      }
	      function formatter(pattern) {
	        let qtype = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'TS';
	        let localeInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
	        let qformat = dateFormatFactory(localeInfo, pattern, qtype);
	        let memoized = memoize(qformat.format.bind(qformat), {
	          toKey: date => typeof date === 'object' && typeof date.getTime === 'function' ? date.getTime() : date
	        });

	        /**
	         * Prepare a value according to the specified qtype
	         *
	         * @param  {Number} value The value to be formatted
	         * @return {Number}       The converted value (if applied)
	         */
	        function prepare(value) {
	          if (qtype !== TYPES.INTERVAL) {
	            return QlikTimeToDate(value);
	          }
	          return value;
	        }

	        /**
	         * Format a value according to the specified pattern created at construct
	         *
	         * @param  {Date} value   The number to be formatted
	         * @return {String}         [description]
	         */
	        function format(value) {
	          value = prepare(value);
	          return memoized(value);
	        }

	        /**
	         * Format a value according to a specific pattern
	         * that is not the one specified in the constructor
	         *
	         * @param  {String} p   Pattern
	         * @param  {Date} v   Value
	         * @return {String}     Formatted value
	         */
	        format.format = function formatFn(p, v) {
	          memoized.clear();
	          v = prepare(v);
	          return qformat.format(v, p);
	        };

	        /**
	         * Set the locale for the formatter
	         *
	         * @param  {Object} args   Locale object for formatting
	         * @return {Undefined}      Returns nothing
	         */
	        format.locale = function locale(li) {
	          qformat = dateFormatFactory(li, pattern, qtype);
	          memoized = memoize(qformat.format.bind(qformat), {
	            toKey: date => typeof date === 'object' ? date.getTime() : date
	          });
	          return this;
	        };

	        /**
	         * Get or set the QType
	         *
	         * @param  {String} nqt New qType (optional)
	         * @return {String}     Current qtype
	         */
	        format.qtype = function qtypeFn(nqt) {
	          if (nqt !== undefined) {
	            qtype = nqt;
	            memoized.clear();
	          }
	          return qtype;
	        };
	        return format;
	      }
	      function createFromMetaInfo(meta, localeInfo) {
	        if (meta && meta.qNumFormat && ['D', 'T', 'TS', 'IV'].indexOf(meta.qNumFormat.qType) !== -1) {
	          return formatter(meta.qNumFormat.qFmt, meta.qNumFormat.qType, localeInfo);
	        }
	        let pattern = '#';
	        let thousand = localeInfo && typeof localeInfo.qThousandSep !== 'undefined' ? localeInfo.qThousandSep : ',';
	        let decimal = localeInfo && typeof localeInfo.qDecimalSep !== 'undefined' ? localeInfo.qDecimalSep : '.';
	        let type = 'U';
	        let isAuto = meta && !!meta.qIsAutoFormat;
	        if (meta && meta.qNumFormat) {
	          pattern = meta.qNumFormat.qFmt || pattern;
	          thousand = meta.qNumFormat.qThou || thousand;
	          decimal = meta.qNumFormat.qDec || decimal;
	          type = meta.qNumFormat.qType || type;
	          isAuto = isAuto && ['M'].indexOf(meta.qNumFormat.qType) === -1;
	        } else {
	          isAuto = true;
	        }
	        if (isAuto || type === 'U') {
	          pattern = "#".concat(decimal, "##");
	          type = 'U';
	        }
	        return formatter$1(pattern, thousand, decimal, type, localeInfo);
	      }
	      function qField() {
	        let {
	          meta,
	          id,
	          key,
	          localeInfo,
	          fieldExtractor,
	          value,
	          type,
	          sourceField
	        } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	        let values;
	        const valueFn = value || (type === 'dimension' ? d => d === null || d === void 0 ? void 0 : d.qElemNo : d => d === null || d === void 0 ? void 0 : d.qValue);
	        const labelFn = d => (d === null || d === void 0 ? void 0 : d.qText) || '';
	        const reduce = type === 'dimension' ? 'first' : 'avg';
	        const formatter = createFromMetaInfo(meta, localeInfo);
	        const reduceLabel = type === 'dimension' ? 'first' : (labels, v) => formatter(v);
	        const f = {
	          id: () => id,
	          key: () => key,
	          raw: () => meta,
	          title: () => meta.qFallbackTitle || meta.label,
	          type: () => type,
	          origin: () => sourceField,
	          items: () => {
	            if (!values) {
	              values = fieldExtractor(f);
	            }
	            return values;
	          },
	          min: () => meta.qMin,
	          max: () => meta.qMax,
	          value: valueFn,
	          label: labelFn,
	          reduce,
	          reduceLabel,
	          formatter: () => formatter,
	          tags: () => meta.qTags
	        };
	        return f;
	      }
	      function createFields(path, obj, prefix, parentKey, opts) {
	        return (obj[path] || []).map((meta, i) => {
	          const fieldKey = "".concat(parentKey ? "".concat(parentKey, "/") : '').concat(path, "/").concat(i);
	          const f = {
	            instance: qField(extend({
	              id: "".concat(prefix ? "".concat(prefix, "/") : '').concat(fieldKey),
	              key: fieldKey,
	              meta
	            }, opts))
	          };
	          f.attrDims = createFields('qAttrDimInfo', meta, prefix, fieldKey, extend({}, opts, {
	            value: v => v === null || v === void 0 ? void 0 : v.qElemNo,
	            type: 'dimension'
	          }));
	          f.attrExps = createFields('qAttrExprInfo', meta, prefix, fieldKey, extend({}, opts, {
	            value: v => v === null || v === void 0 ? void 0 : v.qNum,
	            type: 'measure'
	          }));
	          f.measures = createFields('qMeasureInfo', meta, prefix, fieldKey, extend({}, opts, {
	            value: v => v === null || v === void 0 ? void 0 : v.qValue,
	            type: 'measure'
	          }));
	          return f;
	        });
	      }
	      function q() {
	        let {
	          key,
	          data,
	          config = {}
	        } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	        const cache = {
	          fields: [],
	          wrappedFields: [],
	          allFields: [],
	          virtualFields: []
	        };
	        const cube = data;
	        if (!cube) {
	          throw new Error('Missing "data" input');
	        }
	        if (!cube.qDimensionInfo) {
	          throw new Error('The "data" input is not recognized as a hypercube');
	        }
	        const deps = q.util;
	        const opts = {
	          cache,
	          cube,
	          localeInfo: config.localeInfo,
	          fieldExtractor: null,
	          pages: null,
	          hierarchy: () => null,
	          virtualFields: config.virtualFields
	        };
	        const dataset = {
	          key: () => key,
	          raw: () => cube,
	          field: query => findField(query, opts),
	          fields: () => cache.fields.slice(),
	          extract: extractionConfig => opts.extractor(extractionConfig, dataset, cache, deps),
	          hierarchy: hierarchyConfig => opts.hierarchy(hierarchyConfig, dataset, cache, deps),
	          _cache: () => cache
	        };
	        if (cube.qMode === 'K' || cube.qMode === 'T' || !cube.qMode && cube.qNodesOnDim) {
	          opts.extractor = extract;
	          opts.hierarchy = augment;
	          opts.pages = cube.qMode === 'K' ? cube.qStackedDataPages : cube.qTreeDataPages;
	        } else if (cube.qMode === 'S') {
	          opts.extractor = extract$1;
	          opts.pages = cube.qDataPages;
	          opts.hierarchy = augment;
	        } else {
	          opts.extractor = () => []; // TODO - throw unsupported error?
	        }
	        opts.fieldExtractor = f => opts.extractor({
	          field: f
	        }, dataset, cache, deps);
	        const dimAcc = cube.qMode === 'S' ? d => d.qElemNumber : undefined;
	        const measAcc = cube.qMode === 'S' ? d => d.qNum : undefined;
	        cache.wrappedFields.push(...createFields('qDimensionInfo', cube, key, '', extend({}, opts, {
	          value: dimAcc,
	          type: 'dimension'
	        })));
	        cache.wrappedFields.push(...createFields('qMeasureInfo', cube, key, '', extend({}, opts, {
	          value: measAcc,
	          type: 'measure'
	        })));
	        cache.fields = cache.wrappedFields.map(f => f.instance);
	        const traverse = arr => {
	          arr.forEach(f => {
	            cache.allFields.push(f.instance);
	            traverse(f.measures);
	            traverse(f.attrDims);
	            traverse(f.attrExps);
	          });
	        };
	        traverse(cache.wrappedFields);
	        (config.virtualFields || []).forEach(v => {
	          // key: 'temporal',
	          // from: 'qDimensionInfo/0',
	          // override: {
	          //   value: v => v.qNum,
	          // },
	          const sourceField = dataset.field(v.from);
	          const f = qField(_objectSpread2({
	            meta: sourceField.raw(),
	            id: "".concat(key, "/").concat(v.key),
	            sourceField,
	            fieldExtractor: ff => opts.extractor({
	              field: ff
	            }, dataset, cache, deps),
	            key: v.key,
	            type: sourceField.type(),
	            localeInfo: opts.localeInfo,
	            value: sourceField.value
	          }, v.override || {}));
	          cache.virtualFields.push(f);
	        });
	        cache.allFields.push(...cache.virtualFields);
	        return dataset;
	      }
	      const LAYOUT_TO_PROP = [['qHyperCube', 'qHyperCubeDef'], ['qTreeData', 'qTreeDataDef'], ['qDimensionInfo', 'qDimensions'], ['qMeasureInfo', 'qMeasures'], ['qAttrDimInfo', 'qAttributeDimensions'], ['qAttrExprInfo', 'qAttributeExpressions']];
	      const DIM_RX = /\/qDimensionInfo(?:\/(\d+))?/;
	      const M_RX = /\/qMeasureInfo\/(\d+)/;
	      const ATTR_DIM_RX = /\/qAttrDimInfo\/(\d+)(?:\/(\d+))?/;
	      const ATTR_EXPR_RX = /\/qAttrExprInfo\/(\d+)/;
	      const HC_RX = /\/?qHyperCube/;
	      const TD_RX = /\/?qTreeData/;
	      const SHORTEN_HC = path => "".concat(path.substr(0, path.indexOf('/qHyperCubeDef') + 14)); // 14 = length of '/qHyperCubeDef'
	      const SHORTEN_TD = path => "".concat(path.substr(0, path.indexOf('/qTreeDataDef') + 13)); // 13 = length of '/qTreeDataDef'

	      function extractFieldFromId(id, layout) {
	        let path = id;
	        let dimensionIdx = -1;
	        let measureIdx = -1;
	        let pathToCube = '';
	        let shortenizer = p => p;
	        if (HC_RX.test(id)) {
	          pathToCube = "".concat(path.substr(0, path.indexOf('qHyperCube') + 10)); // 10 = length of 'qHyperCube'
	          shortenizer = SHORTEN_HC;
	        } else if (TD_RX.test(id)) {
	          pathToCube = "".concat(path.substr(0, path.indexOf('qTreeData') + 9)); // 9 = length of 'qTreeData'
	          shortenizer = SHORTEN_TD;
	        }
	        let shortenPath = true;
	        if (DIM_RX.test(id)) {
	          dimensionIdx = +DIM_RX.exec(id)[1];
	        }
	        if (M_RX.test(id)) {
	          measureIdx = +M_RX.exec(id)[1];
	        }
	        if (ATTR_DIM_RX.test(id)) {
	          measureIdx = -1;
	          dimensionIdx = 0;
	          const attrCol = +ATTR_DIM_RX.exec(path)[2];
	          if (!isNaN(attrCol)) {
	            dimensionIdx = attrCol;
	            path = path.replace(/\/\d+$/, '');
	          }
	          shortenPath = false;
	        }
	        if (ATTR_EXPR_RX.test(id)) {
	          // depends on number of measures + number of attr expressions
	          // in dimensions and measures before this one
	          const offset = measureIdx;
	          if (layout) {
	            measureIdx = 0;
	            const hc = resolve(pathToCube, layout);

	            // offset by number of measures
	            measureIdx += (hc.qMeasureInfo || []).length;

	            // offset by total number of attr expr in dimensions
	            // (assuming attr expr in dimensions are ordered first)
	            if (dimensionIdx > -1) {
	              measureIdx = hc.qDimensionInfo.slice(0, dimensionIdx).reduce((v, dim) => v + dim.qAttrExprInfo.length, measureIdx);
	              dimensionIdx = -1;
	            } else {
	              measureIdx = hc.qDimensionInfo.reduce((v, dim) => v + dim.qAttrExprInfo.length, measureIdx);
	              // offset by total number of attr expr in measures before 'index'
	              measureIdx = hc.qMeasureInfo.slice(0, offset).reduce((v, meas) => v + meas.qAttrExprInfo.length, measureIdx);
	            }

	            // offset by the actual column value for the attribute expression itself
	            measureIdx += +ATTR_EXPR_RX.exec(path)[1];
	          } else if (dimensionIdx > -1) {
	            dimensionIdx = -1;
	            measureIdx = +ATTR_EXPR_RX.exec(path)[1];
	          } else {
	            measureIdx += +ATTR_EXPR_RX.exec(path)[1] + 1;
	          }
	        }
	        LAYOUT_TO_PROP.forEach(_ref => {
	          let [v, prop] = _ref;
	          path = path.replace(v, prop);
	        });
	        if (shortenPath) {
	          path = shortenizer(path);
	        }
	        if (path && path[0] !== '/') {
	          path = "/".concat(path);
	        }
	        return {
	          measureIdx,
	          dimensionIdx,
	          path
	        };
	      }

	      /**
	       * Helper method to generate suitable QIX selection methods and parameters based on a brush instance.
	       * @alias brush
	       * @memberof picasso.q
	       * @param {Brush} brush A brush instance
	       * @param {object} [opts]
	       * @param {boolean} [opts.byCells=false] Whether to prefer selection by row index.
	       * @param {string} [opts.primarySource] Field source to extract row indices from. If not specified, indices from first source are used.
	       * @param {boolean} [opts.orMode=true] If false, combine measure range selections.
	       * @param {object} [layout] QIX data layout. Needed only when brushing on attribute expressions, to be able to calculate the measure index.
	       * @return {object[]} An array of relevant selections
	       */
	      function qBrush(brush) {
	        let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	        let layout = arguments.length > 2 ? arguments[2] : undefined;
	        const byCells = opts.byCells;
	        const primarySource = opts.primarySource;
	        const selections = [];
	        const methods = {};
	        const isActive = brush.isActive();
	        let hasValues = false;
	        brush.brushes().forEach(b => {
	          const info = extractFieldFromId(b.id, layout);
	          if (b.type === 'range' && info.measureIdx > -1 && info.dimensionIdx > -1) {
	            const ranges = b.brush.ranges();
	            if (ranges.length) {
	              hasValues = true;
	              if (!methods.multiRangeSelectTreeDataValues) {
	                methods.multiRangeSelectTreeDataValues = {
	                  path: info.path,
	                  ranges: []
	                };
	              }
	              ranges.forEach(range => methods.multiRangeSelectTreeDataValues.ranges.push({
	                qMeasureIx: info.measureIdx,
	                qDimensionIx: info.dimensionIdx,
	                qRange: {
	                  qMin: range.min,
	                  qMax: range.max,
	                  qMinInclEq: true,
	                  qMaxInclEq: true
	                }
	              }));
	            }
	          } else {
	            if (b.type === 'range' && info.measureIdx > -1) {
	              const ranges = b.brush.ranges();
	              if (ranges.length) {
	                hasValues = true;
	                if (!methods.rangeSelectHyperCubeValues) {
	                  methods.rangeSelectHyperCubeValues = {
	                    path: info.path,
	                    ranges: []
	                  };
	                }
	                ranges.forEach(range => methods.rangeSelectHyperCubeValues.ranges.push({
	                  qMeasureIx: info.measureIdx,
	                  qRange: {
	                    qMin: range.min,
	                    qMax: range.max,
	                    qMinInclEq: true,
	                    qMaxInclEq: true
	                  }
	                }));
	              }
	            }
	            if (b.type === 'range' && info.dimensionIdx > -1) {
	              const ranges = b.brush.ranges();
	              if (ranges.length) {
	                hasValues = true;
	                if (!methods.selectHyperCubeContinuousRange) {
	                  methods.selectHyperCubeContinuousRange = {
	                    path: info.path,
	                    ranges: []
	                  };
	                }
	                ranges.forEach(range => methods.selectHyperCubeContinuousRange.ranges.push({
	                  qDimIx: info.dimensionIdx,
	                  qRange: {
	                    qMin: range.min,
	                    qMax: range.max,
	                    qMinInclEq: true,
	                    qMaxInclEq: false
	                  }
	                }));
	              }
	            }
	            if (b.type === 'value' && info.dimensionIdx > -1) {
	              if (byCells) {
	                if (layout && layout.qHyperCube && (layout.qHyperCube.qMode === 'P' || layout.qHyperCube.qMode === 'T' || layout.qHyperCube.qMode === 'K')) {
	                  const hyperCube = layout.qHyperCube;
	                  const noOfLeftDims = hyperCube.qNoOfLeftDims;
	                  const dimInterColSortIdx = hyperCube.qEffectiveInterColumnSortOrder.indexOf(info.dimensionIdx);
	                  if (!methods.selectPivotCells) {
	                    methods.selectPivotCells = {
	                      path: info.path,
	                      cells: []
	                    };
	                  }
	                  if (b.id === primarySource || !primarySource) {
	                    const validValues = b.brush.values().map(s => +s).filter(v => !isNaN(v));
	                    if ((noOfLeftDims === 0 || dimInterColSortIdx >= noOfLeftDims) && noOfLeftDims > -1) {
	                      validValues.forEach(val => {
	                        methods.selectPivotCells.cells.push({
	                          qType: 'T',
	                          qCol: val,
	                          qRow: dimInterColSortIdx - noOfLeftDims
	                        });
	                      });
	                    } else {
	                      validValues.forEach(val => {
	                        methods.selectPivotCells.cells.push({
	                          qType: 'L',
	                          qCol: info.dimensionIdx,
	                          qRow: val
	                        });
	                      });
	                    }
	                    hasValues = !!methods.selectPivotCells.cells.length;
	                  }
	                } else {
	                  if (!methods.selectHyperCubeCells) {
	                    methods.selectHyperCubeCells = {
	                      path: info.path,
	                      cols: []
	                    };
	                  }
	                  methods.selectHyperCubeCells.cols.push(info.dimensionIdx);
	                  if (b.id === primarySource || !primarySource && !methods.selectHyperCubeCells.values) {
	                    methods.selectHyperCubeCells.values = b.brush.values().map(s => +s).filter(v => !isNaN(v));
	                    hasValues = !!methods.selectHyperCubeCells.values.length;
	                  }
	                }
	              } else {
	                const values = b.brush.values().map(s => +s).filter(v => !isNaN(v));
	                hasValues = !!values.length;
	                selections.push({
	                  params: [info.path, info.dimensionIdx, values, false],
	                  method: 'selectHyperCubeValues'
	                });
	              }
	            }
	          }
	        });
	        if (!hasValues && isActive) {
	          return [{
	            method: 'resetMadeSelections',
	            params: []
	          }];
	        }
	        if (methods.rangeSelectHyperCubeValues) {
	          var _opts$orMode;
	          selections.push({
	            method: 'rangeSelectHyperCubeValues',
	            params: [methods.rangeSelectHyperCubeValues.path, methods.rangeSelectHyperCubeValues.ranges, [], (_opts$orMode = opts.orMode) !== null && _opts$orMode !== void 0 ? _opts$orMode : true]
	          });
	        }
	        if (methods.selectHyperCubeContinuousRange) {
	          selections.push({
	            method: 'selectHyperCubeContinuousRange',
	            params: [methods.selectHyperCubeContinuousRange.path, methods.selectHyperCubeContinuousRange.ranges]
	          });
	        }
	        if (methods.selectHyperCubeCells) {
	          selections.push({
	            method: 'selectHyperCubeCells',
	            params: [methods.selectHyperCubeCells.path, methods.selectHyperCubeCells.values, methods.selectHyperCubeCells.cols]
	          });
	        }
	        if (methods.selectPivotCells) {
	          selections.push({
	            method: 'selectPivotCells',
	            params: [methods.selectPivotCells.path, methods.selectPivotCells.cells]
	          });
	        }
	        if (methods.multiRangeSelectTreeDataValues) {
	          selections.push({
	            method: 'multiRangeSelectTreeDataValues',
	            params: [methods.multiRangeSelectTreeDataValues.path, methods.multiRangeSelectTreeDataValues.ranges]
	          });
	        }
	        return selections;
	      }
	      function initialize(picasso) {
	        q.util = picasso.data('matrix').util;
	        picasso.data('q', q);
	        picasso.formatter('q-number', formatter$1);
	        picasso.formatter('q-time', formatter);
	      }
	      initialize.qBrushHelper = qBrush; // deprecated
	      initialize.selections = qBrush;
	      return initialize;
	    });
	  })(picassoQ$1);
	  return picassoQ$1.exports;
	}

	var picassoQExports = requirePicassoQ();
	var PicassoQ = /*@__PURE__*/getDefaultExportFromCjs(picassoQExports);

	const selectionUtils = {
	  brushInterceptors: {
	    DIM_VALUE_NULL: -2,
	    DIM_VALUE_TOTAL: -3,
	    brushOnlyOne,
	    filterValues
	  }
	};

	/**
	 * Implementation details
	 */

	/**
	 * Brush interception filter func - Brush ONE single value
	 * @param selectBrush
	 * @param items
	 * @returns {*}
	 */
	function brushOnlyOne(brush, items) {
	  const activeBrushes = brush.brushes().filter(b => b.type === 'value');
	  let toggleOff = [];
	  if (activeBrushes.length) {
	    activeBrushes.forEach(b => {
	      toggleOff = toggleOff.concat(b.brush.values().map(v => ({
	        key: b.id,
	        value: v
	      })));
	    });
	  }
	  return toggleOff.concat(items);
	}
	function findField(chartInstance, item) {
	  const splitIndex = item.key.indexOf('qHyperCube') + 'qHyperCube'.length;
	  const datasetName = item.key.substr(0, splitIndex);
	  const fieldName = item.key.substr(splitIndex + 1);
	  return chartInstance.dataset(datasetName).field(fieldName);
	}

	/**
	 * Brush interception filter function
	 * Do not allow selections on null value
	 * Do not allow selections in locked dimension
	 * @param chartInstance
	 * @param items
	 * @returns Object { items: {Array}, itemsAreLocked: {Boolean} }
	 */
	function filterValues(chartInstance, items) {
	  const self = this;
	  let meta;
	  let field;
	  const lockedFields = [];
	  let lockedItems = 0;
	  const brushItems = [];
	  items.forEach(item => {
	    if (item.value === self.DIM_VALUE_NULL || item.value === self.DIM_VALUE_TOTAL) {
	      return;
	    }
	    field = findField(chartInstance, item);
	    meta = field && field.raw();
	    if (!meta.qLocked) {
	      brushItems.push({
	        key: item.key,
	        value: item.value
	      });
	    } else {
	      lockedFields.push(meta);
	      lockedItems++;
	    }
	  });
	  return {
	    items: brushItems,
	    itemsAreLocked: lockedItems > 0 && lockedItems === items.length,
	    lockedFields
	  };
	}

	function SelectionActions(chartInstance, selectionsApi, paths) {
	  function fn() {}
	  function update(added, removed, brush) {
	    if (!selectionsApi.isActive()) {
	      selectionsApi.begin(paths);
	    }
	    const selections = PicassoQ.qBrushHelper(brush);
	    selections.forEach(s => {
	      selectionsApi.select(s);
	    });
	  }
	  function toggleValues(items, brush, startOnEmptySelection) {
	    const filterResult = selectionUtils.brushInterceptors.filterValues(chartInstance, items);
	    const itms = filterResult.items;
	    if (!selectionsApi.isActive() && !filterResult.itemsAreLocked && (startOnEmptySelection || itms.length > 0)) {
	      selectionsApi.begin(paths);
	      brush.start();
	      brush.emit('update', [], []); // and activate our brush
	    }
	    return itms;
	  }
	  fn.update = update;
	  fn.toggleValues = toggleValues;
	  return fn;
	}

	/* eslint-disable no-shadow */
	/* eslint-disable func-names */
	const DEFAULT_OPTIONS$1 = {
	  data: ['elemNo'],
	  contexts: ['select'],
	  startOnEmptySelection: true,
	  style: {
	    active: {
	      strokeWidth: 2,
	      stroke: '#333' // To make it consistent with other charts
	    },
	    inactive: {
	      opacity: 0.3
	    }
	  }
	};
	const ESCAPE = 27;
	const ENTER = 13;
	const SHIFT = 16;

	/**
	 * Create a new Selections handler
	 *
	 * @param {Object} options
	 * @param {Object} options.model The backend model for the chart
	 * @param {Object} options.chartInstance Picasso chart instance
	 * @param {Object} options.selectionsApi Object selectionsApi
	 * @returns {Object} The selections handler instance
	 */
	function Selections(options) {
	  if (!options || !options.chartInstance || !options.selectionsApi) {
	    throw Error('Selections-handler: Missing input');
	  }
	  const chartInstance = options.chartInstance;
	  const selectionsApi = options.selectionsApi;
	  const dataPaths = options.dataPaths || [''];
	  const selectPaths = options.selectPaths;
	  const lasso = options.lasso;
	  let selectionContexts = [];
	  const selectionsApiRestoreHelper = {
	    propertiesToRestore: {}
	  };
	  let on = false;
	  const actions = SelectionActions(chartInstance, selectionsApi, selectPaths);

	  // Not need for a function, so turned it into an object
	  const fn = {};
	  let lastShift = false;
	  function shiftToggle(e) {
	    if (e.keyCode === SHIFT && e.shiftKey !== lastShift) {
	      lastShift = e.shiftKey;
	      lasso.toggle();
	    }
	  }
	  function confirmOrCancelSelection(event) {
	    const key = event.keyCode;
	    if (key === ESCAPE) {
	      selectionsApi.cancel();
	    } else if (key === ENTER) {
	      selectionsApi.confirm();
	    }
	  }

	  // If a single field in a single table is not locked, this function returns false
	  function areAllFieldsLocked() {
	    let dimFields = dataPaths.map(dataPath => chartInstance.dataset(dataPath).fields().filter(field => field.type() === 'dimension'));

	    // flattern list
	    // eslint-disable-next-line prefer-spread
	    dimFields = [].concat.apply([], dimFields);
	    return dimFields.length && dimFields.every(field => field.raw().qLocked);
	  }

	  // If a single field in a single table is not locked, this function returns false
	  function getFieldsLocked() {
	    const lockedFields = [];
	    let dimFields = dataPaths.map(dataPath => chartInstance.dataset(dataPath).fields().filter(field => field.type() === 'dimension'));

	    // flattern list
	    // eslint-disable-next-line prefer-spread
	    dimFields = [].concat.apply([], dimFields);
	    for (let i = 0; i < dimFields.length; i++) {
	      if (dimFields[i].raw().qLocked) {
	        lockedFields.push(dimFields[i].raw());
	      }
	    }
	    return {
	      fields: lockedFields,
	      areAllFieldsLocked: lockedFields.length && lockedFields.length === dimFields.length
	    };
	  }
	  function isLassoDisabled() {
	    return options.isLassoDisabled && options.isLassoDisabled();
	  }
	  selectionsApi.on('cleared', () => {
	    selectionContexts.forEach(context => {
	      context.brush.clear();
	      // Clear dependent components
	      context.dependentComponents.forEach(comp => {
	        const instance = chartInstance.component(comp.id);
	        if (instance) {
	          instance.emit(comp.clear);
	        }
	      });
	    });
	  });

	  // Setup a selection context
	  /*
	        builder - instance of chart-builder
	        componentKeys = []
	        options = {
	            contexts: [],
	            data: [],
	            style: {}
	        }
	    */
	  /**
	   * Setup a selection context
	   * @param {Object} options Selection context options
	   * @returns {Object} The selections handler instance
	   */
	  fn.setUp = function (options) {
	    fn.tearDown();
	    const result = this.setUpBrush(options);
	    if (on) {
	      register();
	    }
	    return result;
	  };
	  fn.setUpBrush = function (options) {
	    const opts = extend$1(true, {}, DEFAULT_OPTIONS$1, options);
	    const selectionTrigger = {
	      on: 'tap',
	      action(e) {
	        return e.ctrlKey || options.isSingleSelect ? 'set' : 'toggle';
	      },
	      contexts: opts.contexts,
	      data: opts.data,
	      globalPropagation: 'stop'
	    };
	    const selectionConsumer = {
	      context: opts.contexts[0],
	      data: opts.data,
	      style: opts.style
	    };

	    // eslint-disable-next-line @eslint-react/naming-convention/context-name
	    const context = createContext$1(opts, chartInstance);
	    // Do this here instead of in register to be able to catch the consumer
	    context.listeners.toggle = function (items) {
	      if (!on) {
	        return [];
	      }
	      const fieldsLocked = getFieldsLocked();
	      if (opts.startOnEmptySelection && items.length === 0 && fieldsLocked.areAllFieldsLocked) {
	        return [];
	      }
	      return actions.toggleValues(items, context.brush, opts.startOnEmptySelection);
	    };

	    // Add all three to cover tap, brush range and lasso
	    context.brush.intercept('toggle-values', context.listeners.toggle);
	    context.brush.intercept('add-values', context.listeners.toggle);
	    context.brush.intercept('remove-values', context.listeners.toggle);
	    context.brush.intercept('set-values', context.listeners.toggle);
	    context.listeners.start = function () {
	      if (selectionContexts.length > 1) {
	        selectionContexts.forEach(c => {
	          if (c !== context) {
	            c.brush.end();
	          }
	        });

	        // something may still be needed but can not call selectionsApi.clear() that would cause a infinite loop
	        // if (!selectionsApi.canClear || selectionsApi.canClear()) {
	        //   selectionsApi.clear();
	        // }
	      }
	    };
	    selectionContexts.push(context);
	    return {
	      trigger: selectionTrigger,
	      consume: selectionConsumer
	    };
	  };
	  fn.setUpStart = function () {
	    fn.tearDown();
	  };
	  fn.setUpDone = function () {
	    if (on) {
	      register();
	    }
	  };
	  fn.tearDown = function () {
	    if (on) {
	      deregister();
	    }
	    selectionContexts.forEach(context => {
	      context.brush.removeInterceptor('toggle-values', context.listeners.toggle);
	      context.brush.removeInterceptor('add-values', context.listeners.toggle);
	      context.brush.removeInterceptor('remove-values', context.listeners.toggle);
	      context.brush.removeInterceptor('set-values', context.listeners.toggle);
	    });
	    selectionContexts = [];
	  };
	  function register() {
	    selectionContexts.forEach(context => {
	      context.listeners.update = function (added, removed) {
	        // On tap end, picaso will run rendering in the same frame, and if this is a heavy job then long tap end will happen before tap end finish. This can trigger the radial context menu.
	        // So we prevent long tap end here.
	        if (!context.sleep) {
	          actions.update(added, removed, context.brush);
	        }
	      };
	      context.brush.on('update', context.listeners.update);
	      context.brush.on('start', context.listeners.start);
	    });
	  }
	  function deregister() {
	    selectionContexts.forEach(context => {
	      context.brush.removeListener('update', context.listeners.update);
	      context.brush.removeListener('start', context.listeners.start);
	    });
	  }
	  fn.pauseEngineCalls = function (id) {
	    selectionContexts.forEach(context => {
	      if (context.id === id) {
	        context.sleep = true;
	      }
	    });
	  };
	  fn.resumeEngineCalls = function (id, run) {
	    selectionContexts.forEach(context => {
	      if (context.id === id) {
	        context.sleep = false;
	        if (run) {
	          context.listeners.update([], []);
	        }
	      }
	    });
	  };
	  fn.addComponent = function (id, comp) {
	    selectionContexts.forEach(context => {
	      if (context.id === id) {
	        context.dependentComponents.push(comp);
	      }
	    });
	  };
	  fn.on = function () {
	    if (on) {
	      return;
	    }
	    on = true;
	    register();
	    document.addEventListener('keydown', shiftToggle);
	    document.addEventListener('keyup', shiftToggle);
	    const onDeactivated = () => {
	      selectionContexts.forEach(context => {
	        context.brush.end();
	      });
	      document.removeEventListener('keyup', confirmOrCancelSelection);
	      if (lasso.active()) {
	        lasso.toggle();
	      }
	    };
	    selectionsApi.on('deactivated', onDeactivated);
	    selectionsApiRestoreHelper.unbindDeactivated = () => {
	      selectionsApi.removeListener('deactivated', onDeactivated);
	    };
	    const onActivated = () => {
	      document.addEventListener('keyup', confirmOrCancelSelection);
	    };
	    selectionsApi.on('activated', onActivated);
	    selectionsApiRestoreHelper.unbindActivated = () => {
	      selectionsApi.removeListener('activated', onActivated);
	    };
	  };
	  fn.isOn = () => on;
	  fn.off = function () {
	    if (!on) {
	      return;
	    }
	    on = false;
	    deregister();
	    document.removeEventListener('keydown', shiftToggle);
	    document.removeEventListener('keyup', shiftToggle);
	    document.removeEventListener('keyup', confirmOrCancelSelection);
	    selectionsApiRestoreHelper.unbindActivated();
	    selectionsApiRestoreHelper.unbindDeactivated();
	  };
	  fn.lassoState = function () {
	    return lasso.active() && !isLassoDisabled();
	  };
	  fn.allFieldsLocked = function () {
	    return areAllFieldsLocked();
	  };
	  return fn;
	}
	class NoSelections {
	  // eslint-disable-next-line class-methods-use-this
	  isOn() {
	    return false;
	  }

	  // eslint-disable-next-line class-methods-use-this
	  on() {
	    // eslint-disable-next-line no-console
	    console.warn('Can not turn on selections on this object');
	  }

	  // eslint-disable-next-line class-methods-use-this
	  off() {}
	}
	var SelectionHandler = {
	  create(options) {
	    if (!options.selectionsApi) {
	      return new NoSelections();
	    }
	    return Selections(options);
	  }
	};
	function createContext$1(options, chartInstance) {
	  return {
	    brush: chartInstance.brush(options.contexts[0]),
	    listeners: {},
	    dependentComponents: [],
	    id: options.contexts[0]
	  };
	}

	/**
	 * Create a new tooltip action context
	 *
	 * @param {Object} chartInstance Picasso chart instance
	 * @returns {Object} The tooltip actions handler instance
	 */
	function TooltipActions(chartInstance, componentKey, data, context, tooltipKey) {
	  let hasOpen = false;
	  context = context || 'tooltip';
	  data = data || ['self'];
	  const brush = chartInstance.brush(context);
	  const fn = {};

	  // Exposed here for test stub purposes
	  fn.isOpen = function () {
	    return hasOpen;
	  };
	  function closeTooltip() {
	    if (hasOpen) {
	      const tooltip = chartInstance.component(tooltipKey);
	      tooltip.emit('hide');
	    }
	    hasOpen = false;
	  }
	  function openTooltip(shapes) {
	    hasOpen = true;
	    const tooltip = chartInstance.component(tooltipKey);
	    const e = {};
	    const data = {
	      nodes: shapes
	    };
	    tooltip.emit('show', e, data);
	  }
	  fn.closeTooltip = closeTooltip;

	  /**
	   * Updates the contents in tooltip. Requires an array of tooltipInfo.labelData and
	   * an array of tooltipInfo.measureRows for the tooltip to display content, otherwise
	   * it will show nothing. These key value mappings should be sent in from the charts.
	   */
	  function update() {
	    const brushes = brush.brushes();

	    // Fetches only the shapes that we are hovering over
	    const shapes = chartInstance.getAffectedShapes(context, 'and', data, componentKey);
	    if (brushes.length >= 1) {
	      hasOpen = true;
	      openTooltip(shapes);
	    } else {
	      closeTooltip();
	    }
	  }
	  function toggleInterceptor(items) {
	    // Remove duplicates if we have multiple dimensions to aoivd a toggle
	    // ex: set(2006 ) ->2006 is on, followed by set(2006 ) ->2006 is off
	    if (data.length > 1) {
	      const check = {};
	      const ret = [];
	      items.forEach(item => {
	        if (!check[item.key]) {
	          check[item.key] = {};
	        }
	        if (!check[item.key][item.value]) {
	          check[item.key][item.value] = true;
	          ret.push(item);
	        }
	      });
	      return ret;
	    }
	    return items;
	  }
	  fn.update = update;
	  fn.toggleInterceptor = toggleInterceptor;
	  return fn;
	}
	var TooltipAction = {
	  create(...args) {
	    return TooltipActions(...args);
	  }
	};

	var formatting = {
	  formatMeasureValue
	};
	function formatMeasureValue(field, measureContent) {
	  if (field.raw().isCustomFormatted) {
	    return field.formatter()(measureContent.value.qText);
	  }
	  const value = measureContent.value.qNum !== undefined ? measureContent.value.qNum : measureContent.value.qValue;
	  return field.formatter()(value);
	}

	const MAX_VISIBLE_ITEMS = 5;
	const OTHERS_ELEMNO = -3;
	const NULL_ELEMNO = -2;

	// TODO: The function getAffectedShapes returns duplicate shapes.
	// Remove when this is fixed on picasso
	function filterDuplicateShapes(shapes) {
	  const uniques = [];
	  shapes.forEach(shape => {
	    if (uniques.indexOf(shape) === -1 && shape.type !== 'container') {
	      uniques.push(shape);
	    }
	  });
	  return uniques;
	}
	const createFilter = filterShapes => shapes => filterShapes ? filterShapes(shapes) : filterDuplicateShapes(shapes);
	const createContent = context => ({
	  h,
	  data,
	  style
	}) => {
	  const content = extractContent(context, data);
	  const renderSettings = {
	    h,
	    style,
	    rtl: context.direction === 'rtl',
	    translator: context.translator
	  };
	  return context.renderer(renderSettings, content);
	};
	function extractContent(tooltipInfo, uniqueShapes) {
	  const dataset = tooltipInfo.chartInstance.dataset(tooltipInfo.dataPath);

	  // Create content + header
	  const content = [];
	  const numberInExcess = uniqueShapes.length - MAX_VISIBLE_ITEMS;
	  const numItems = Math.min(MAX_VISIBLE_ITEMS, uniqueShapes.length);
	  for (let j = 0; j < numItems; j++) {
	    const shape = uniqueShapes[j];
	    const localContent = {
	      rows: []
	    };
	    if (tooltipInfo.labelData) {
	      const labels = [];
	      const refPaths = tooltipInfo.labelData;
	      let isNullValue = false;
	      for (let i = 0; i < refPaths.length; i++) {
	        const currentNode = shape.data[refPaths[i]].value;
	        if (currentNode.qElemNo === NULL_ELEMNO || currentNode.qElemNumber === NULL_ELEMNO) {
	          // The node is null
	          isNullValue = true;
	          break;
	        }
	        labels.push(shape.data[refPaths[i]].value.qText);
	      }
	      if (isNullValue) {
	        return undefined;
	      }
	      localContent.header = tooltipInfo.headerResolver(labels);
	      localContent.rows = tooltipInfo.measureRows.map(measureRow => {
	        const rowData = shape.data;
	        return tooltipInfo.rowResolver(dataset.field(rowData[measureRow].source.field), rowData[measureRow], rowData);
	      }).filter(row => !!row);
	      const colorByData = getColorByDimData(tooltipInfo, shape);
	      if (colorByData) {
	        localContent.rows.unshift(colorByData);
	      }
	      content.push(localContent);
	    }
	  }
	  if (numberInExcess > 0) {
	    content.numberInExcess = numberInExcess;
	  }
	  content.rowCount = content[0] ? content.length * content[0].rows.length : 0;
	  return content;
	}
	function getOthersIndex(values) {
	  let index = -1;
	  for (let i = 0; i < values.length; i++) {
	    if (values[i] === OTHERS_ELEMNO) {
	      index = i;
	    }
	  }
	  return index;
	}

	/**
	 * Get the information of how the color by row should look like.
	 * The data for color by is fetched directly from the shape and it's key value mapping called
	 * colorByDim, which contains the label and the elemNo
	 * @param tooltipInfo - an object containing the chart view
	 * @param shape - an object representing the shape currently hovered upon
	 * @returns {{label: string - legendTitle, value: (*|String) - color by value, template: string - html template}}
	 */
	function getColorByDimData(tooltipInfo, shape) {
	  const colorData = shape.data.color;
	  const colorSettings = tooltipInfo.colorService?.getSettings?.();
	  if (!colorSettings || colorSettings.type === 'color' || !colorData || !colorSettings.fieldType) {
	    return undefined;
	  }
	  const ids = [];
	  tooltipInfo.data.forEach(mapping => {
	    const elemNoObj = shape.data[mapping];
	    if (elemNoObj) {
	      ids.push(elemNoObj.value);
	    }
	  });
	  const othersIndex = getOthersIndex(ids);
	  const {
	    translator
	  } = tooltipInfo;
	  const label = colorSettings.label;
	  const color = shape.attrs?.fill;
	  const value = othersIndex !== -1 ? translator.get('properties.dimensionLimits.others') : colorData.label;
	  return {
	    color,
	    label,
	    value
	  };
	}

	/* eslint no-underscore-dangle: 0 */
	const TOOLTIP_CONTAINER_ID = 'dist-flow-tooltip';
	const TOOLTIP_CONTAINER_SELECTOR = `#${TOOLTIP_CONTAINER_ID}`;
	function appendTooltipContainer() {
	  if (!document.querySelector(TOOLTIP_CONTAINER_SELECTOR)) {
	    const container = document.createElement('div');
	    container.id = TOOLTIP_CONTAINER_ID;
	    container.style.overflow = 'hidden';
	    container.style.position = 'fixed';
	    container.style.pointerEvents = 'none';
	    container.style.left = '0px';
	    container.style.top = '0px';
	    container.style.width = '100%';
	    container.style.height = '100%';
	    container.style.zIndex = 1020;
	    document.body.appendChild(container);
	  }
	}
	function destroyTooltipContainer() {
	  const elm = document.querySelector(TOOLTIP_CONTAINER_SELECTOR);
	  if (elm && elm.parentElement && elm.childElementCount < 1) {
	    elm.parentElement.removeChild(elm);
	  }
	}

	/**
	 * Base tooltip definition
	 */
	function tooltip({
	  key = 'tooltip',
	  rtl,
	  fontFamily,
	  filter,
	  content
	}) {
	  return {
	    show: true,
	    key,
	    type: 'tooltip',
	    layout: {
	      displayOrder: 3
	    },
	    beforeMount() {
	      appendTooltipContainer();
	    },
	    beforeUpdate() {
	      appendTooltipContainer();
	    },
	    destroyed() {
	      destroyTooltipContainer();
	    },
	    settings: {
	      appendTo: () => document.querySelector(TOOLTIP_CONTAINER_SELECTOR),
	      content,
	      filter,
	      extract: context => context.node,
	      direction: rtl ? 'rtl' : 'ltr',
	      placement: 'bounds'
	    },
	    style: {
	      arrow: {
	        color: '#404040'
	      },
	      content: {
	        display: 'table',
	        'border-spacing': '4px',
	        background: 'rgba(64, 64, 64, 0.9)',
	        opacity: '1',
	        fontSize: '13px',
	        fontFamily,
	        'empty-cells': 'show'
	      },
	      cell: {
	        'max-width': '180px',
	        'word-break': 'break-word',
	        'word-wrap': 'break-word',
	        'overflow-wrap': 'break-word',
	        hyphens: 'auto'
	      }
	    }
	  };
	}

	/** @jsxRuntime classic */
	/** @jsx h */
	const {
	  detectTextDirection: getDirection
	} = rtlUtils;
	function render(settings, content) {
	  // eslint-disable-next-line no-unused-vars
	  const {
	    h,
	    style,
	    translator,
	    rtl
	  } = settings;
	  const result = [];
	  const labelTextAlign = rtl ? 'right' : 'left';
	  content.forEach(item => {
	    if (item.header) {
	      const headerStyle = {
	        ...style.cell,
	        textAlign: labelTextAlign,
	        fontWeight: 'bold',
	        direction: getDirection(item.header)
	      };
	      result.push(h("tr", null, h("td", {
	        style: headerStyle,
	        colSpan: 2
	      }, item.header)));
	    }
	    item.rows.forEach(row => {
	      let valueContent = row.value;
	      if (row.color) {
	        const symbolStyle = {
	          display: 'inline-block',
	          width: 10,
	          height: 10,
	          'background-color': row.color,
	          margin: '0 8px'
	        };
	        const symbol = h("div", {
	          style: symbolStyle
	        });
	        valueContent = rtl ? [row.value, symbol] : [symbol, row.value];
	      }
	      const label = rtl ? [':', row.label] : [row.label, ':'];
	      const labelStyle = {
	        ...style.cell,
	        textAlign: labelTextAlign,
	        direction: getDirection(row.label)
	      };
	      const valueStyle = {
	        ...style.cell,
	        textAlign: rtl ? 'left' : 'right',
	        direction: getDirection(row.value)
	      };
	      result.push(h("tr", null, h("td", {
	        style: labelStyle
	      }, label), h("td", {
	        style: valueStyle
	      }, valueContent)));
	    });
	  });
	  if (content.numberInExcess) {
	    const moreText = translator.get('Object.ChartTooltip.NMore', content.numberInExcess);
	    const moreStyle = {
	      ...style.cell,
	      textAlign: labelTextAlign,
	      direction: getDirection(moreText)
	    };
	    result.push(h("tr", null, h("td", {
	      style: moreStyle,
	      colSpan: 2
	    }, moreText)));
	  }
	  return result;
	}

	/* eslint-disable @eslint-react/naming-convention/context-name */
	/* eslint-disable func-names */
	/* eslint-disable import-x/extensions */
	/* eslint-disable import-x/no-unresolved */
	const DEFAULT_OPTIONS = {
	  tooltipKey: 'tooltip',
	  data: [''],
	  contexts: ['tooltip'],
	  headerResolver(values) {
	    return values.join(', ');
	  },
	  rowResolver(field, measureContent) {
	    return {
	      value: formatting.formatMeasureValue(field, measureContent),
	      label: field.title()
	    };
	  },
	  direction: 'ltr',
	  renderer: render
	};

	/**
	 * Create a new Tooltips handler
	 *
	 * @param {Object} model The backend model for the chart
	 * @param {Object} chartInstance Picasso chart instance
	 * @returns {Object} The selections handler instance
	 */
	function Tooltips(chartInstance, $element, chartType) {
	  if (!chartInstance) {
	    throw Error('Tooltips-handler: Missing input');
	  }
	  let tooltipContexts = {};
	  let on = false;

	  // Not need for a function, so turned it into an object
	  const fn = {};

	  /**
	   * Setup a tooltips context
	   * @param {Object} options Tooltip context options
	   * @returns {Object} The selections handler instance
	   */
	  fn.setUp = function (options) {
	    const opts = extend$1(true, {}, DEFAULT_OPTIONS, options);
	    if (!opts.componentKey) {
	      throw Error('Tooltips-handler.setUp: Missing required input');
	    }
	    if (tooltipContexts[opts.contexts[0]] && on) {
	      deRegContext(tooltipContexts[opts.contexts[0]]);
	    }
	    const context = createContext(opts, chartInstance);
	    tooltipContexts[opts.contexts[0]] = context;
	    if (on) {
	      registerContext(context);
	    }
	    const component = tooltip({
	      key: opts.tooltipKey,
	      rtl: context.direction === 'rtl',
	      fontFamily: context.theme.getStyle(chartType, 'tooltip', 'fontFamily'),
	      filter: createFilter(context.filterShapes),
	      content: createContent(context, opts.dataPath)
	    });
	    const settings = opts.chartBuilder.getSettings();
	    settings.components.push(component);
	    return {
	      trigger: {
	        on: context.treatAsDesktop ? 'over' : 'tap',
	        action: 'set',
	        contexts: opts.contexts,
	        data: opts.data,
	        globalPropagation: 'stop'
	      },
	      consume: opts.contexts.map(c => ({
	        context: c
	      })),
	      component
	    };
	  };
	  fn.tearDown = function () {
	    if (on) {
	      deregister();
	    }
	    tooltipContexts = [];
	  };
	  function register() {
	    Object.keys(tooltipContexts).forEach(key => {
	      registerContext(tooltipContexts[key]);
	    });
	  }
	  function registerContext(context) {
	    context.listeners.update = function (added, removed) {
	      context.action.update(added, removed, context);
	    };
	    context.listeners.end = function () {
	      context.action.closeTooltip();
	    };
	    context.brush.on(context.treatAsDesktop ? 'update' : 'set-values', context.listeners.update);
	    context.brush.on('end', context.listeners.end);
	    // Intecept the set-values call to avoid a toggle in the second dimension.
	    context.brush.intercept('set-values', context.action.toggleInterceptor);
	  }
	  function deregister() {
	    Object.keys(tooltipContexts).forEach(key => {
	      deRegContext(tooltipContexts[key]);
	    });
	  }
	  function deRegContext(context) {
	    context.brush.removeListener(context.treatAsDesktop ? 'update' : 'set-values', context.listeners.update);
	    context.brush.removeListener('end', context.listeners.end);
	    context.brush.removeInterceptor('set-values', context.action.toggleInterceptor);
	  }
	  function closeTooltip() {
	    Object.keys(tooltipContexts).forEach(key => {
	      tooltipContexts[key].action.closeTooltip();
	    });
	  }
	  function mouseLeave() {
	    closeTooltip();
	    for (const prop in tooltipContexts) {
	      tooltipContexts[prop].brush.clear();
	    }
	  }
	  fn.closeTooltip = closeTooltip;
	  fn.isOn = () => on;
	  fn.on = function () {
	    if (on) {
	      return;
	    }
	    on = true;
	    register();
	    if ($element) {
	      $element.on('mouseleave', mouseLeave);
	    }
	  };
	  fn.off = function () {
	    if (!on) {
	      return;
	    }
	    on = false;
	    deregister();
	    if ($element) {
	      $element.off('mouseleave', mouseLeave);
	    }
	    closeTooltip();
	  };
	  return fn;
	}
	var TooltipHandler = {
	  create(chartInstance, $element, chartType) {
	    return Tooltips(chartInstance, $element, chartType);
	  }
	};
	function createContext(options, chartInstance) {
	  return {
	    brush: chartInstance.brush(options.contexts[0]),
	    action: TooltipAction.create(chartInstance, options.componentKey, options.data, options.contexts[0], options.tooltipKey),
	    listeners: {},
	    chartInstance,
	    dataPath: options.dataPath,
	    renderer: options.renderer,
	    data: options.data,
	    headerResolver: options.headerResolver,
	    rowResolver: options.rowResolver,
	    colorService: options.colorService,
	    attrDimPath: options.attrDimPath,
	    measureRows: options.measureRows,
	    labelData: options.labelData,
	    filterShapes: options.filterShapes,
	    direction: options.environment.options.direction,
	    theme: options.environment.theme,
	    translator: options.environment.translator,
	    treatAsDesktop: options.environment.deviceType !== 'touch'
	  };
	}

	/**
	 * Generate a 32 bit integer hash code from a string
	 */
	function hashFromString(str) {
	  let hash = 0;
	  if (!str || !str.length) {
	    return hash;
	  }
	  for (let i = 0; i < str.length; i++) {
	    const chr = str.charCodeAt(i);
	    /* eslint-disable no-bitwise */
	    hash = (hash << 5) - hash + chr;
	    hash &= hash;
	    /* eslint-enable no-bitwise */
	  }
	  return hash;
	}

	const hash = {
	  generateHash,
	  updateHash
	};

	/**
	 * Implementation details
	 */

	function generateHash(hashData) {
	  return hashFromString(JSON.stringify(hashData));
	}
	function updateHash(properties, hashData) {
	  if (!properties.qUndoExclude) {
	    properties.qUndoExclude = {};
	  }
	  properties.qUndoExclude.hashCode = hash.generateHash(hashData);
	}

	const hashBuilder = {
	  getDefaultHashDataForHyperCube
	};

	/**
	 * Implementation details
	 */

	function getDefaultHashDataForHyperCube(hyperCubeDef, hyperCube, app) {
	  return getMeasureExpressions(hyperCubeDef, app).then(measureExpressions => ({
	    drillLevel: getDrillIndices(hyperCube),
	    dimensionExpressions: getDimensionExpressions(hyperCube),
	    measureExpressions
	  }));
	}
	function getMeasureExpressions(hyperCubeDef, app) {
	  const dfds = [];
	  if (!hyperCubeDef.qMeasures) {
	    return Promise.resolve(dfds);
	  }
	  hyperCubeDef.qMeasures.forEach(measure => {
	    if (measure.qLibraryId) {
	      dfds.push(getMeasureDataFromLibraryItem(measure.qLibraryId, app));
	    } else {
	      dfds.push(Promise.resolve());
	    }
	  });
	  return Promise.all(dfds);
	}
	function getMeasureDataFromLibraryItem(libraryId, app) {
	  return app.getMeasure(libraryId).then(item => item.getProperties().then(props => props.qMeasure.qDef));
	}
	function getDimensionExpressions(hyperCube) {
	  return hyperCube.qDimensionInfo.map(dimensionInfo => dimensionInfo.qGroupFieldDefs);
	}
	function getDrillIndices(hyperCube) {
	  const dimensions = getDimensions(hyperCube);
	  return dimensions.map(dim => dim.qGroupPos);
	}
	function getDimensions(hyperCube) {
	  return Nn(hyperCube, 'qDimensionInfo', []);
	}

	/* eslint-disable no-shadow */
	/* eslint-disable no-nested-ternary */
	/* eslint-disable no-param-reassign */
	/* eslint-disable func-names */
	const JSONPatch = {};
	const extend = extend$1.bind(null, true);
	function isObject(v) {
	  return v != null && !Array.isArray(v) && typeof v === 'object';
	}
	const isArray = Array.isArray;
	const isUndef = function (v) {
	  return typeof v === 'undefined';
	};
	const isFunction = function (v) {
	  return typeof v === 'function';
	};

	/**
	 * Generate an exact duplicate (with no references) of a specific value.
	 *
	 * @private
	 * @param {Object} The value to duplicate
	 * @returns {Object} a unique, duplicated value
	 */
	function generateValue(val) {
	  if (val) {
	    val = extend({}, {
	      val
	    }).val;
	  }
	  return val;
	}

	/**
	 * An additional type checker used to determine if the property is of internal
	 * use or not a type that can be translated into JSON (like functions).
	 *
	 * @private
	 * @param {Object} obj The object which has the property to check
	 * @param {String} The property name to check
	 * @returns {Boolean} Whether the property is deemed special or not
	 */
	function isSpecialProperty(obj, key) {
	  return isFunction(obj[key]) || key.substring(0, 2) === '$$' || key.substring(0, 1) === '_';
	}

	/**
	 * Finds the parent object from a JSON-Pointer ("/foo/bar/baz" = "bar" is "baz" parent),
	 * also creates the object structure needed.
	 *
	 * @private
	 * @param {Object} data The root object to traverse through
	 * @param {String} The JSON-Pointer string to use when traversing
	 * @returns {Object} The parent object
	 */
	function getParent(data, str) {
	  const seperator = '/';
	  const parts = str.substring(1).split(seperator).slice(0, -1);
	  let numPart;
	  parts.forEach((part, i) => {
	    if (i === parts.length) {
	      return;
	    }
	    numPart = +part;
	    data[numPart || part] = isUndef(data[numPart || part]) ? !Number.isNaN(+numPart) ? [] : {} : data[part];
	    data = data[numPart || part];
	  });
	  return data;
	}

	/**
	 * Cleans an object of all its properties, unless they're deemed special or
	 * cannot be removed by configuration.
	 *
	 * @private
	 * @param {Object} obj The object to clean
	 */
	function emptyObject(obj) {
	  Object.keys(obj).forEach(key => {
	    const config = Object.getOwnPropertyDescriptor(obj, key);
	    if (config.configurable && !isSpecialProperty(obj, key)) {
	      delete obj[key];
	    }
	  });
	}

	/**
	 * Compare an object with another, could be object, array, number, string, bool.
	 *
	 * @param {Object} a The first object to compare
	 * @param {Object} b The second object to compare
	 * @returns {Boolean} Whether the objects are identical
	 */
	function compare(a, b) {
	  if (isObject(a) && isObject(b)) {
	    if (Object.keys(a).length !== Object.keys(b).length) {
	      return false;
	    }
	    for (const key of Object.keys(a)) {
	      if (!compare(a[key], b[key])) {
	        return false;
	      }
	    }
	    return true;
	  }
	  if (isArray(a) && isArray(b)) {
	    if (a.length !== b.length) {
	      return false;
	    }
	    for (let i = 0, l = a.length; i < l; i++) {
	      if (!compare(a[i], b[i])) {
	        return false;
	      }
	    }
	    return true;
	  }
	  return a === b;
	}

	/**
	 * Generates patches by comparing two arrays.
	 *
	 * @private
	 * @param {Array} oldA The old (original) array, which will be patched
	 * @param {Array} newA The new array, which will be used to compare against
	 * @returns {Array} An array of patches (if any)
	 */
	function patchArray(original, newA, basePath) {
	  let patches = [];
	  const oldA = original.slice();
	  let i;
	  let l;
	  let tmpIdx = -1;
	  function findIndex(a, id, idx) {
	    if (a[idx] && isUndef(a[idx].qInfo)) {
	      return null;
	    }
	    if (a[idx] && a[idx].qInfo.qId === id) {
	      // shortcut if identical
	      return idx;
	    }
	    for (let i = 0, l = a.length; i < l; i++) {
	      if (a[i] && a[i].qInfo.qId === id) {
	        return i;
	      }
	    }
	    return -1;
	  }
	  if (compare(newA, oldA)) {
	    // array is unchanged
	    return patches;
	  }
	  if (newA[0] === null || !isUndef(newA[0]) && isUndef(newA[0].qInfo)) {
	    // we cannot create patches without unique identifiers, replace array...
	    patches.push({
	      op: 'replace',
	      path: basePath,
	      value: newA
	    });
	    return patches;
	  }
	  for (i = oldA.length - 1; i >= 0; --i) {
	    tmpIdx = findIndex(newA, oldA[i] && oldA[i].qInfo && oldA[i].qInfo.qId, i);
	    if (tmpIdx === -1) {
	      patches.push({
	        op: 'remove',
	        path: `${basePath}/${i}`
	      });
	      oldA.splice(i, 1);
	    } else {
	      patches = patches.concat(JSONPatch.generate(oldA[i], newA[tmpIdx], `${basePath}/${i}`));
	    }
	  }
	  for (i = 0, l = newA.length; i < l; ++i) {
	    tmpIdx = findIndex(oldA, newA[i] && newA[i].qInfo && newA[i].qInfo.qId);
	    if (tmpIdx === -1) {
	      patches.push({
	        op: 'add',
	        path: `${basePath}/${i}`,
	        value: newA[i]
	      });
	      oldA.splice(i, 0, newA[i]);
	    } else if (tmpIdx !== i) {
	      patches.push({
	        op: 'move',
	        path: `${basePath}/${i}`,
	        from: `${basePath}/${tmpIdx}`
	      });
	      oldA.splice(i, 0, oldA.splice(tmpIdx, 1)[0]);
	    }
	  }
	  return patches;
	}

	/**
	 * Generate an array of JSON-Patch:es following the JSON-Patch Specification Draft.
	 *
	 * See [specification draft](http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-10)
	 *
	 * Does NOT currently generate patches for arrays (will replace them)
	 *
	 * @param {Object} original The object to patch to
	 * @param {Object} newData The object to patch from
	 * @param {String} [basePath] The base path to use when generating the paths for the patches (normally not used)
	 * @returns {Array} An array of patches
	 */
	JSONPatch.generate = function (original, newData, basePath) {
	  basePath = basePath || '';
	  let patches = [];
	  Object.keys(newData).forEach(key => {
	    const val = generateValue(newData[key]);
	    const oldVal = original[key];
	    const tmpPath = `${basePath}/${key}`;
	    if (compare(val, oldVal) || isSpecialProperty(newData, key)) {
	      return;
	    }
	    if (isUndef(oldVal)) {
	      // property does not previously exist
	      patches.push({
	        op: 'add',
	        path: tmpPath,
	        value: val
	      });
	    } else if (isObject(val) && isObject(oldVal)) {
	      // we need to generate sub-patches for this, since it already exist
	      patches = patches.concat(JSONPatch.generate(oldVal, val, tmpPath));
	    } else if (isArray(val) && isArray(oldVal)) {
	      patches = patches.concat(patchArray(oldVal, val, tmpPath));
	    } else {
	      // it's a simple property (bool, string, number)
	      patches.push({
	        op: 'replace',
	        path: `${basePath}/${key}`,
	        value: val
	      });
	    }
	  });
	  Object.keys(original).forEach(key => {
	    if (isUndef(newData[key]) && !isSpecialProperty(original, key)) {
	      // this property does not exist anymore
	      patches.push({
	        op: 'remove',
	        path: `${basePath}/${key}`
	      });
	    }
	  });
	  return patches;
	};

	/**
	 * Apply a list of patches to an object.
	 *
	 * @param {Object} original The object to patch
	 * @param {Array} patches The list of patches to apply
	 */
	JSONPatch.apply = function (original, patches) {
	  patches.forEach(patch => {
	    const parent = getParent(original, patch.path);
	    let key = patch.path.split('/').splice(-1)[0];
	    const target = key && Number.isNaN(+key) ? parent[key] : parent[+key] || parent;
	    const from = patch.from ? patch.from.split('/').splice(-1)[0] : null;
	    if (patch.op === 'add' || patch.op === 'replace') {
	      if (isArray(parent)) {
	        // trust indexes from patches, so don't replace the index if it's an add
	        if (key === '-') {
	          key = parent.length;
	        }
	        parent.splice(+key, patch.op === 'add' ? 0 : 1, patch.value);
	      } else if (isArray(target) && isArray(patch.value)) {
	        const newValues = patch.value.slice();
	        // keep array reference if possible...
	        target.length = 0;
	        // eslint-disable-next-line prefer-spread
	        target.push.apply(target, newValues);
	      } else if (isObject(target) && isObject(patch.value)) {
	        // keep object reference if possible...
	        emptyObject(target);
	        extend(target, patch.value);
	      } else {
	        // simple value
	        parent[key] = patch.value;
	      }
	    } else if (patch.op === 'move') {
	      const oldParent = getParent(original, patch.from);
	      if (isArray(parent)) {
	        parent.splice(+key, 0, oldParent.splice(+from, 1)[0]);
	      } else {
	        parent[key] = oldParent[from];
	        delete oldParent[from];
	      }
	    } else if (patch.op === 'remove') {
	      if (isArray(parent)) {
	        parent.splice(+key, 1);
	      } else {
	        delete parent[key];
	      }
	    }
	  });
	};

	/**
	 * Deep clone an object.
	 *
	 * @param {Object} obj The object to clone
	 * @returns {Object} A new object identical to the `obj`
	 */
	JSONPatch.clone = function (obj) {
	  return extend({}, obj);
	};

	/**
	 * Creates a JSON-patch.
	 *
	 * @param {String} op The operation of the patch. Available values: "add", "remove", "move"
	 * @param {Object} [val] The value to set the `path` to. If `op` is `move`, `val` is the "from JSON-path" path
	 * @param {String} path The JSON-path for the property to change (e.g. "/qHyperCubeDef/columnOrder")
	 * @returns {Object} A patch following the JSON-patch specification
	 */
	JSONPatch.createPatch = function (op, val, path) {
	  const patch = {
	    op: op.toLowerCase(),
	    path
	  };
	  if (patch.op === 'move') {
	    patch.from = val;
	  } else if (typeof val !== 'undefined') {
	    patch.value = val;
	  }
	  return patch;
	};

	/**
	 * Apply the differences of two objects (keeping references if possible).
	 * Identical to running `JSONPatch.apply(original, JSONPatch.generate(original, newData));`
	 *
	 * @param {Object} original The object to update/patch
	 * @param {Object} newData the object to diff against
	 *
	 * @example
	 * var obj1 = { foo: [1,2,3], bar: { baz: true, qux: 1 } };
	 * var obj2 = { foo: [4,5,6], bar: { baz: false } };
	 * JSONPatch.updateObject(obj1, obj2);
	 * // => { foo: [4,5,6], bar: { baz: false } };
	 */
	JSONPatch.updateObject = function (original, newData) {
	  if (!Object.keys(original).length) {
	    extend(original, newData);
	    return;
	  }
	  JSONPatch.apply(original, JSONPatch.generate(original, newData));
	};

	class SoftPropertyHandler {
	  constructor(model) {
	    this._model = model;
	  }
	  setModel(model) {
	    this._model = model;
	  }
	  saveSoftProperties(prevEffectiveProperties, effectiveProperties) {
	    if (!this._model) {
	      return Promise.resolve(false);
	    }
	    let patches = JSONPatch.generate(prevEffectiveProperties, effectiveProperties);
	    extend$1(true, prevEffectiveProperties, effectiveProperties);
	    if (patches && patches.length) {
	      patches = patches.map(p => ({
	        qOp: p.op,
	        qValue: JSON.stringify(p.value),
	        qPath: p.path
	      }));
	      return this._model.applyPatches(patches, true).then(() => true);
	    }
	    return Promise.resolve(false);
	  }
	  async mergeSoftPatches() {
	    if (!this._model) {
	      return;
	    }
	    const propertiesPromise = this._model.getProperties();
	    const effectivePromise = this._model.getEffectiveProperties();
	    const properties = await propertiesPromise;
	    const effective = await effectivePromise;
	    if (properties.qExtendsId) {
	      return;
	    }
	    const patches = JSONPatch.generate(properties, effective);
	    JSONPatch.apply(properties, patches);
	    const self = this;
	    self._model.setProperties(properties).then(() => {
	      self._model.clearSoftPatches();
	    });
	  }
	}

	var hardPropertiesChecker = {
	  canModifyHardProperties
	};
	function canModifyHardProperties(layout) {
	  if (layout.qHasSoftPatches || layout.qExtendsId) {
	    return false;
	  }
	  if (layout.permissions) {
	    return layout.permissions.update;
	  }
	  return layout.qMeta.privileges.indexOf('update') !== -1;
	}

	var Save = {
	  saveDerivedProperties
	};

	/**
	 * Implementation details
	 */

	function saveDerivedProperties(model, layout, properties, prevProperties) {
	  // Can't set new properties on a master item (SUI-1363)

	  if (hardPropertiesChecker.canModifyHardProperties(layout)) {
	    return model.setProperties(properties);
	  }
	  const softPropertyHandler = new SoftPropertyHandler(model);
	  return softPropertyHandler.saveSoftProperties(prevProperties, properties);
	}

	var InputValidator = {
	  validate
	};

	/**
	 * Implementation details
	 */

	function validate(settings) {
	  if (!settings || !settings.layout || !settings.properties || !settings.model || !settings.hashData || !settings.generateDerivedProperties) {
	    throw Error('Derived-properties: Missing input');
	  }
	}

	function DerivedProperties() {
	  this._generationInProgress = false;
	}
	DerivedProperties.prototype.isDerivedUpToDate = isDerivedUpToDate;
	DerivedProperties.prototype.updateDerivedProperties = updateDerivedProperties;
	DerivedProperties.prototype.addDefaultHyperCubeHash = addDefaultHyperCubeHash;
	function isDerivedUpToDate(settings) {
	  InputValidator.validate(settings);
	  const properties = settings.properties;
	  const hash$1 = hash.generateHash(settings.hashData);
	  if (!properties.qUndoExclude || properties.qUndoExclude.hashCode !== hash$1) {
	    return false;
	  }
	  return true;
	}

	// Returns a boolean flag if properties actually are being updated or not
	function updateDerivedProperties(settings) {
	  InputValidator.validate(settings);
	  if (this._generationInProgress) {
	    return Promise.resolve(true);
	  }
	  if (isDerivedUpToDate(settings)) {
	    const layoutIsUpdated = settings.layout.qUndoExclude && settings.layout.qUndoExclude.hashCode === settings.properties.qUndoExclude.hashCode;
	    return Promise.resolve(!layoutIsUpdated);
	  }
	  const self = this;
	  const model = settings.model;
	  const layout = settings.layout;
	  const properties = extend$1(true, {}, settings.properties);
	  const prevProperties = extend$1(true, {}, properties);
	  this._generationInProgress = true;
	  hash.updateHash(properties, settings.hashData);
	  return settings.generateDerivedProperties(layout, properties).then(() => Save.saveDerivedProperties(model, layout, properties, prevProperties).then(() => {
	    self._generationInProgress = false;
	    return Promise.resolve(true);
	  }));
	}
	function addDefaultHyperCubeHash(hyperCubeDef, hyperCube, app, settings) {
	  return hashBuilder.getDefaultHashDataForHyperCube(hyperCubeDef, hyperCube, app).then(defaultSettings => extend$1(true, settings, defaultSettings));
	}

	const ExpressionWrapper = {
	  wrapExpression
	};
	function wrapExpression(expression) {
	  const result = expression.replace(/\]/g, ']]');
	  return result ? `[${result}]` : '';
	}

	/* eslint-disable no-restricted-syntax */
	/* eslint-disable guard-for-in */
	const ExpressionReplacer = {
	  replaceExpressionTokens,
	  createRegExp
	};
	function replaceExpressionTokens(expression, tokenMappings, tokenIdentifiers) {
	  const identifiers = {
	    start: tokenIdentifiers && tokenIdentifiers.start || '{{',
	    end: tokenIdentifiers && tokenIdentifiers.end || '}}'
	  };
	  let returnExpression = expression;
	  let tokenExpression;
	  let tokenString;
	  for (const key in tokenMappings) {
	    tokenExpression = tokenMappings[key];
	    tokenString = identifiers.start + key + identifiers.end;
	    returnExpression = returnExpression.replace(createRegExp(tokenString, true), tokenExpression);
	  }
	  return returnExpression;
	}
	function createRegExp(string, isGlobal, isGrouped) {
	  const escapedString = escapeRegExp(string);
	  const regexpString = isGrouped ? `(${escapedString})` : escapedString;
	  return isGlobal ? new RegExp(regexpString, 'g') : new RegExp(regexpString);
	}
	function escapeRegExp(str) {
	  return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
	}

	/* eslint-disable guard-for-in */
	/* eslint-disable no-restricted-syntax */
	const ExpressionGenerator = {
	  generateExpression
	};

	// builds up mappings for the dimensions and measures and wraps the dimensions
	// mappings = { mapping }
	// mapping = {
	// 	value: (string) the expression value to replace the key with,
	// 	wrap: (boolean) if the expression should be cleaned and wrapped or not (usually if field)
	//  variations: (Array) array of strings with variations on the same key that if the value is empty should also be empty
	function generateExpression(template, mappings) {
	  const explicitMappings = {};
	  if (mappings) {
	    for (const key in mappings) {
	      const mapping = mappings[key];
	      const expression = mapping.wrap ? ExpressionWrapper.wrapExpression(mapping.value) : mapping.value;
	      explicitMappings[key] = expression;
	      const variations = mapping.variations || [];
	      variations.forEach(variation => {
	        const variationExpressions = assembleVariation(variation, expression, key);
	        explicitMappings[variation] = variationExpressions;
	      });
	    }
	  }
	  return ExpressionReplacer.replaceExpressionTokens(template, explicitMappings);
	}

	// Internal functions

	function assembleVariation(variation, value, key) {
	  if (value === '') {
	    return '';
	  }
	  const regExp = ExpressionReplacer.createRegExp(key, true, true);
	  const stringArray = variation.split(regExp);
	  let expression = '';
	  stringArray.forEach(substring => {
	    expression += substring !== key ? substring : value;
	  });
	  return expression;
	}

	const HyperCubeGenerator = {
	  generateHyperCubeDef,
	  getAllHyperCubeExpressions
	};

	// builds up a hyper cube using a hyper cube def and the hyper cube result, needs the app as well
	// also supports additional mappings that allows generation of more advanced expressions
	function generateHyperCubeDef(template, hyperCubeDef, hyperCube, app, mappings) {
	  // hyper cube knows about {{Dim[n]}} {{Mea[n]}} mappings.
	  return getKnownMappings(template.dimensions.concat(template.measures), hyperCubeDef, hyperCube, app).then(knownMappings => {
	    const allMappings = extend$1({}, knownMappings, mappings);
	    const generatedHyperCubeDef = extend$1(true, {}, hyperCubeDef);
	    // clean the dimensions and measures
	    generatedHyperCubeDef.qDimensions = [];
	    generatedHyperCubeDef.qMeasures = [];
	    template.dimensions.forEach(dimensionTemplate => {
	      generatedHyperCubeDef.qDimensions.push({
	        qDef: {
	          qFieldDefs: [`=${ExpressionGenerator.generateExpression(dimensionTemplate, allMappings)}`]
	        }
	      });
	    });
	    template.measures.forEach(measureTemplate => {
	      generatedHyperCubeDef.qMeasures.push({
	        qDef: {
	          qDef: ExpressionGenerator.generateExpression(measureTemplate, allMappings)
	        }
	      });
	    });
	    return generatedHyperCubeDef;
	  });
	}
	async function getAllHyperCubeExpressions(hyperCubeDef, hyperCube, app) {
	  const dimensions = hyperCubeDef.qDimensions.map((dimension, index) => getExpressionFromDimension(dimension, app, index, hyperCube));
	  const measures = hyperCubeDef.qMeasures.map(measure => getExpressionFromMeasure(measure, app));
	  return {
	    dimensions: await Promise.all(dimensions),
	    measures: await Promise.all(measures)
	  };
	}
	function getExpressionFromDimension(dimension, app, index, hyperCube) {
	  if (dimension.qLibraryId) {
	    return getExpressionFromLibraryItem(dimension.qLibraryId, 'dimension', app, index, hyperCube);
	  }
	  const drillIndex = hyperCube.qDimensionInfo[index].qGroupPos;
	  return Promise.resolve(dimension.qDef.qFieldDefs[drillIndex]);
	}
	async function getExpressionFromMeasure(measure, app) {
	  const expression = measure.qLibraryId ? await getExpressionFromLibraryItem(measure.qLibraryId, 'measure', app) : measure.qDef.qDef;
	  return lineCommentProtection(expression);
	}

	// Internal functions
	function lineCommentProtection(expression) {
	  const commentIndex = expression.lastIndexOf('//');
	  const lineIndex = expression.lastIndexOf('\n');
	  if (commentIndex > lineIndex) {
	    return `${expression}\n`;
	  }
	  return expression;
	}
	function getExpressionFromLibraryItem(id, type, app, index, hyperCube) {
	  if (!app) {
	    console.warn('No app provided, returning library id');
	    return id;
	  }
	  const getFn = type === 'dimension' ? 'getDimension' : 'getMeasure';
	  return app[getFn](id).then(item => item.getProperties().then(props => {
	    if (type === 'dimension') {
	      return props.qDim.qFieldDefs[hyperCube.qDimensionInfo[index].qGroupPos];
	    }
	    return props.qMeasure.qDef;
	  }));
	}

	// identifies {{Dim[x]}} {{Mea[x]}} mappings and returns the distinct instances of them
	function getKnownMappings(mappings, hyperCubeDef, hyperCube, app) {
	  const knownMappings = {};
	  let dimensionIndices;
	  let measureIndices;
	  const dfds = [];
	  mappings.forEach(mapping => {
	    dimensionIndices = spliceIdentifiedMatches(mapping.match(getMappingRegExp('Dim')));
	    dimensionIndices.forEach(index => {
	      dfds.push(getExpressionFromDimension(hyperCubeDef.qDimensions[index], app, index, hyperCube).then(expression => {
	        knownMappings[`Dim[${index}]`] = {
	          value: expression,
	          wrap: true
	        };
	      }));
	    });
	    measureIndices = spliceIdentifiedMatches(mapping.match(getMappingRegExp('Mea')));
	    measureIndices.forEach(index => {
	      dfds.push(getExpressionFromMeasure(hyperCubeDef.qMeasures[index], app).then(expression => {
	        knownMappings[`Mea[${index}]`] = {
	          value: expression
	        };
	      }));
	    });
	  });
	  let returnPromise;
	  if (dfds.length) {
	    returnPromise = Promise.all(dfds).then(() => Promise.resolve(knownMappings));
	  } else {
	    returnPromise = Promise.resolve(knownMappings);
	  }
	  return returnPromise;
	}
	function getMappingRegExp(string) {
	  return new RegExp(`\\{\\{${string}\\[\\d\\]\\}\\}`, 'g');
	}
	function spliceIdentifiedMatches(matches) {
	  if (!matches) {
	    return [];
	  }
	  return matches.map(match => match.substr(6, 1));
	}

	function isNumeric(v) {
	  return !Number.isNaN(parseFloat(v)) && Number.isFinite(+v);
	}

	function isInteger(v) {
	  return !Number.isNaN(parseInt(v, 10)) && parseFloat(v, 10) === parseInt(v, 10);
	}

	/**
	 * Implementation details
	 */

	function getBinMode(layout) {
	  return vr(layout, 'bins.binMode', BINNING_DEFAULTS.BIN_MODE);
	}
	function getBinSize(layout) {
	  return vr(layout, 'bins.binSize', BINNING_DEFAULTS.BIN_SIZE);
	}
	function getDerivedBinSize(layout) {
	  return vr(layout, 'qUndoExclude.bins.binSize', BINNING_DEFAULTS.BIN_SIZE);
	}
	function getDerivedBinOffset(layout) {
	  return vr(layout, 'qUndoExclude.bins.offset', BINNING_DEFAULTS.OFFSET);
	}
	function getDerivedBinCount(layout) {
	  const binCount = vr(layout, 'qUndoExclude.bins.binCount', BINNING_DEFAULTS.BIN_COUNT);
	  if (!isNumeric(binCount)) {
	    return BINNING_DEFAULTS.BIN_COUNT;
	  }
	  if (binCount < 1) {
	    return 1;
	  }

	  // The numbers of bins needs to be an integer, round it with Math.ceil
	  if (!isInteger(binCount)) {
	    return Math.ceil(binCount);
	  }
	  return binCount;
	}
	function getBinCount$1(layout) {
	  return vr(layout, 'bins.binCount', undefined);
	}
	function getBinOffset(layout) {
	  return vr(layout, 'bins.offset', BINNING_DEFAULTS.OFFSET);
	}
	function isAutoBin(layout) {
	  return vr(layout, 'bins.auto', BINNING_DEFAULTS.AUTO);
	}
	function isCountDistinct(layout) {
	  return vr(layout, 'bins.countDistinct', BINNING_DEFAULTS.COUNT_DISTINCT);
	}
	function isEmpty(v) {
	  return v === undefined || v === null || v === '';
	}
	const histogramUtils = {
	  getBinSize,
	  getDerivedBinSize,
	  getDerivedBinOffset,
	  getDerivedBinCount,
	  getBinCount: getBinCount$1,
	  getBinOffset,
	  isAutoBin,
	  isCountDistinct,
	  getBinMode,
	  isEmpty
	};

	/* eslint-disable no-param-reassign */
	const LOG10 = Math.log(10);
	const EPSILON = 1e-9;
	const NICE_NUMBERS1 = [1, 1.5, 2, 3, 4, 5, 6, 10];
	const NICE_NUMBERS2 = [1, 2, 4, 5, 6, 8, 10];
	const LOOP_CONTROL_NUMBERS = [2, 4, 5, 10];

	/**
	 * Implementation details
	 */

	function validateInput(min, max, binCount) {
	  if (!isNumeric(min) || !isNumeric(max) || !isNumeric(binCount)) {
	    throw Error('binSizeCalculator: One of the inputs is NOT numeric');
	  }
	  if (min > max) {
	    throw Error("binSizeCalculator: The 'min' parameter is bigger than the 'max' parameter");
	  }
	}
	function getBinCount(binCount) {
	  // The smallest number of bins possible is 1
	  if (binCount < 1) {
	    return 1;
	  }

	  // The numbers of bins needs to be an integer, round it with Math.ceil
	  if (!isInteger(binCount)) {
	    return Math.ceil(binCount);
	  }
	  return binCount;
	}
	function getGoodNumber(value, niceNumbers) {
	  if (value === 0) {
	    return 0;
	  }
	  let roundedFraction;
	  const magnitude = Math.floor(Math.log(Math.abs(value)) / LOG10);
	  const fraction = value / 10 ** magnitude;
	  for (let i = 0; i < niceNumbers.length; i++) {
	    if (fraction <= niceNumbers[i]) {
	      roundedFraction = niceNumbers[i];
	      break;
	    }
	  }

	  // Fix floating error
	  return (magnitude >= 0 ? roundedFraction * 10 ** magnitude : roundedFraction / 10 ** -magnitude) * (value < 0 ? -1 : 1);
	}
	function calculateNumEmptyBins(min, max, nbrOfBins, binSize, newMin, newMax) {
	  return Math.floor(Math.abs(min - newMin) / binSize) + Math.floor(Math.abs(newMax - max) / binSize);
	}
	function calculateBinSize(min, max, nbrOfBins) {
	  let newMin;
	  let newMax;
	  let range;
	  let binSize;
	  let niceBinSize;
	  let magnitude;
	  let f;
	  let k;
	  let i = -1;
	  let delta;
	  let n;
	  let loop;
	  let t;
	  let niceNumbers = NICE_NUMBERS1;
	  nbrOfBins = Math.max(1, nbrOfBins);
	  if (max === min) {
	    if (max === 0) {
	      binSize = 1;
	      if (nbrOfBins === 1) {
	        return {
	          min,
	          max,
	          nbrOfBins,
	          rawBinSize: range / nbrOfBins,
	          offset: -0.5,
	          // new min
	          newMax: 0.5,
	          binSize: 1,
	          numEmptyBins: 0
	        };
	      }
	    } else if (nbrOfBins === 1) {
	      binSize = max + EPSILON;
	      niceNumbers = NICE_NUMBERS2;
	    } else {
	      binSize = Math.abs(max / nbrOfBins);
	    }
	  } else {
	    max += EPSILON;
	    range = max - min;
	    binSize = range / nbrOfBins;
	  }
	  do {
	    k = 1;
	    loop = 0;
	    if (i >= 0) {
	      delta = 1 / LOOP_CONTROL_NUMBERS[i];
	      n = 1;
	      niceNumbers = [];
	      while (n <= 10) {
	        niceNumbers.push(Math.round(n * 1000) / 1000);
	        n += delta;
	      }
	    }
	    niceBinSize = binSize;
	    do {
	      niceBinSize = getGoodNumber(niceBinSize * k, niceNumbers);
	      magnitude = Math.floor(Math.log(niceBinSize) / LOG10);
	      f = 10 ** magnitude;
	      if (max === min) {
	        newMax = (Math.ceil(max / niceBinSize) + Math.floor(nbrOfBins / 2)) * niceBinSize;
	      } else {
	        newMax = Math.ceil(max / niceBinSize) * niceBinSize;
	      }
	      newMin = newMax - nbrOfBins * niceBinSize;
	      let j = 0;
	      t = f;
	      while ((newMin > min || newMax < max) && j < LOOP_CONTROL_NUMBERS.length) {
	        newMin = Math.floor(min / t) * t;
	        newMax = newMin + nbrOfBins * niceBinSize;
	        t = f / LOOP_CONTROL_NUMBERS[j++];
	      }

	      // Fix floating error
	      if (magnitude < 1) {
	        f = 10 ** (Math.abs(magnitude) + 1);
	        newMax = Math.round(newMax * f) / f;
	        newMin = Math.round(newMin * f) / f;
	      }
	      k = 1.1;
	      loop++;
	    } while ((newMin > min || newMax < max) && loop < 10); // Bin size should be increased to cover the min-max range
	    i++;
	  } while (calculateNumEmptyBins(min, max, nbrOfBins, binSize, newMin, newMax) > 0 && i < LOOP_CONTROL_NUMBERS.length);
	  return {
	    binCount: nbrOfBins,
	    offset: newMin,
	    // new min
	    binSize: niceBinSize
	  };
	}
	function preCalculateBinSize(min, max, binCount) {
	  // General input validation
	  validateInput(min, max, binCount);

	  // Makes sure binCount is an integer bigger than 0
	  binCount = getBinCount(binCount);
	  return calculateBinSize(min, max, binCount);
	}
	const binSizeCalculator = {
	  calculateBinSize: preCalculateBinSize
	};

	/**
	 * Implementation details
	 */

	function getMappings(values) {
	  const mappings = {};
	  mappings.BinSize = {
	    value: `,${values.binSize}`
	  };
	  mappings.Label = {
	    value: values.binOffset === 0 ? '' : ",'x'"
	  };
	  mappings.Offset = {
	    value: values.binOffset === 0 ? '' : `,${values.binOffset}`
	  };
	  mappings.Distinct = {
	    value: values.distinct ? 'Distinct ' : ''
	  };
	  return mappings;
	}
	function getBinInfo(layout) {
	  const dimInfo = vr(layout, 'qHyperCube.qDimensionInfo.0', {});
	  let qMin = dimInfo.qMin;
	  let qMax = dimInfo.qMax;
	  qMin = isNumeric(qMin) ? qMin : 1;
	  qMax = isNumeric(qMax) ? qMax : 1;
	  const binCount = histogramUtils.getDerivedBinCount(layout);
	  return binSizeCalculator.calculateBinSize(qMin, qMax, binCount);
	}
	function getMappingValues(layout) {
	  const auto = histogramUtils.isAutoBin(layout);
	  const binMode = histogramUtils.getBinMode(layout);
	  let binSize;
	  let binOffset;
	  let binCount;
	  let binInfo;
	  const distinct = histogramUtils.isCountDistinct(layout);
	  if (auto || binMode === 'maxCount') {
	    binInfo = getBinInfo(layout);
	    binSize = binInfo.binSize;
	    binOffset = binInfo.offset;
	    binCount = binInfo.binCount;
	  } else {
	    binSize = histogramUtils.getBinSize(layout);
	    binOffset = histogramUtils.getBinOffset(layout);
	  }
	  return {
	    binSize,
	    binOffset,
	    binCount,
	    distinct
	  };
	}
	const histogramMappings = {
	  getMappingValues,
	  getMappings
	};

	async function generateHyperCubes(layout, properties, environment) {
	  const {
	    app,
	    translator
	  } = environment;
	  const mappingValues = histogramMappings.getMappingValues(layout);
	  const mappings = histogramMappings.getMappings(mappingValues);
	  const hyperCubeTemplate = {
	    dimensions: ['Class(aggr({{Dim[0]}},{{Dim[0]}}){{BinSize}}{{Label}}{{Offset}})'],
	    measures: ['Count({{Distinct}}{{Dim[0]}})']
	  };

	  // Sturges' formula - https://en.wikipedia.org/wiki/Histogram#Number_of_bins_and_width
	  const binCountTemplate = '=Ceil(Log10(Count({{Dim[0]}})) / Log10(2)) + 1';
	  const expressionsPromise = HyperCubeGenerator.getAllHyperCubeExpressions(properties.qHyperCubeDef, layout.qHyperCube, app);
	  const boxCubeDefPromise = HyperCubeGenerator.generateHyperCubeDef(hyperCubeTemplate, properties.qHyperCubeDef, layout.qHyperCube, app, mappings);
	  const expressions = await expressionsPromise;
	  const boxCubeDef = await boxCubeDefPromise;
	  let binCountExpr;
	  if (histogramUtils.isAutoBin(layout)) {
	    binCountExpr = {
	      qValueExpression: {
	        qExpr: ExpressionGenerator.generateExpression(binCountTemplate, {
	          'Dim[0]': {
	            value: expressions.dimensions[0],
	            wrap: true
	          }
	        })
	      }
	    };
	  } else if (histogramUtils.getBinMode(layout) === 'maxCount' && histogramUtils.isEmpty(properties.bins.binCount)) {
	    // When the user have not provided any binCount we use the derived value which will be the output of the auto algorithm in most cases
	    binCountExpr = histogramUtils.getDerivedBinCount(layout);
	  } else {
	    binCountExpr = properties.bins.binCount;
	  }

	  // Dimension should be sorted numeric ascending
	  br(boxCubeDef, 'qDimensions.0.qDef.qSortCriterias', [{
	    qSortByNumeric: 1
	  }]);

	  // Store the data labels, used when object is flipped to table
	  br(boxCubeDef, 'qDimensions.0.qDef.qFieldLabels', [layout.qHyperCube.qDimensionInfo[0].qFallbackTitle]);
	  br(boxCubeDef, 'qMeasures.0.qDef.qLabel', layout.measureAxis.label || translator.get('Visualization.Histogram.MeasureAxisLabel'));

	  // Store the generated hyperCube on properties
	  br(properties, 'qUndoExclude.box.qHyperCubeDef', boxCubeDef);

	  // Store the binSize (which in auto mode will be dynamically calculated)
	  br(properties, 'qUndoExclude.bins.binSize', mappingValues.binSize);
	  br(properties, 'qUndoExclude.bins.offset', mappingValues.binOffset);
	  br(properties, 'qUndoExclude.bins.binCount', binCountExpr);
	}
	const cubesGenerator = {
	  generateHyperCubes
	};

	/**
	 * Checks whether a collision has occurred for range selection
	 * @param e - event, in this case a mouse event
	 * @param targets - the target points that the selections are hitting
	 * @param selectionGesture - The type of selection gesture, for example area range select
	 * @returns {boolean} - True, if a collision has occurred, otherwise false
	 */
	function isOnComponentForRange(e, targets, selectionGesture) {
	  return !!e && !!selectionGesture.chart.componentsFromPoint({
	    x: e.center.x,
	    y: e.center.y
	  }).filter(c => targets.indexOf(c.settings.key) !== -1)[0];
	}

	/**
	 * Checks whether a collision has occurred for lasso selection
	 * @param e - event, in this case a mouse event
	 * @param gesturesParams - parameters for lasso selection
	 * @param lassoGesture - the lasso gesture instance
	 * @returns {boolean} - True, if a collision has occurred, otherwise false
	 */
	function isOnComponentForLasso(e, gesturesParams, lassoGesture) {
	  return e && lassoGesture.chart.componentsFromPoint({
	    x: e.center.x,
	    y: e.center.y
	  }).filter(c => c.settings.key === gesturesParams.keys.componentKey)[0];
	}
	function isOnComponentForNavBtn(e, legendBrushKey, navBtnGesture) {
	  const components = navBtnGesture.chart.componentsFromPoint(e.center);
	  return components.some(c => c.settings.key === legendBrushKey);
	}
	var onComponentChecker = {
	  isOnComponentForRange,
	  isOnComponentForLasso,
	  isOnComponentForNavBtn
	};

	function getLassoState(handlers) {
	  return handlers.selectionHandler.lassoState() && !handlers.selectionHandler.allFieldsLocked();
	}

	/**
	 * Handles lasso events for picasso charts using HammerJS. When activating lasso selection enable function is
	 * triggered first. lassoStart is triggered on all areas specified by options.direction key. Lasso is the gesture
	 * that will be active by default.
	 */
	function callLassoGesture(state, gesturesFns, gesturesParams) {
	  return {
	    type: 'Pan',
	    options: {
	      direction: Hammer$1.DIRECTION_ALL,
	      threshold: 1,
	      enable(manager, e) {
	        if (state.lassoing) {
	          return gesturesFns.isSelectionEnabled();
	        }
	        const hitComp = onComponentChecker.isOnComponentForLasso(e, gesturesParams, this);
	        return gesturesFns.isSelectionEnabled() && e && (getLassoState(gesturesParams.handlers) || state.lassoing) && hitComp;
	      },
	      event: 'lasso'
	    },
	    recognizeWith: gesturesParams.handlers.scrollHandler ? 'drag' : null,
	    events: {
	      lassostart(e) {
	        const hitComp = onComponentChecker.isOnComponentForLasso(e, gesturesParams, this);
	        if (!hitComp) {
	          return;
	        }
	        gesturesFns.switchTo('lasso', this.chart, e);
	        state.lassoing = true;
	        gesturesParams.handlers.selectionHandler.pauseEngineCalls(gesturesParams.keys.lassoBrushKey);
	        e.clientX = e.pointers[0].clientX;
	        e.clientY = e.pointers[0].clientY;
	        gesturesFns.doEmit(this.chart, 'lasso', 'lassoStart', e);
	      },
	      lassomove(e) {
	        if (!state.lassoing) {
	          return;
	        }
	        e.clientX = e.pointers[0].clientX;
	        e.clientY = e.pointers[0].clientY;
	        gesturesFns.doEmit(this.chart, 'lasso', 'lassoMove', e);
	      },
	      lassoend(e) {
	        if (!state.lassoing) {
	          return;
	        }
	        e.clientX = e.pointers[0].clientX;
	        e.clientY = e.pointers[0].clientY;
	        gesturesFns.doEmit(this.chart, 'lasso', 'lassoEnd', e);
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.lassoBrushKey, true);
	        state.lassoing = false;
	      },
	      lassocancel(e) {
	        state.lassoing = false;
	        gesturesFns.doEmit(this.chart, 'lasso', 'lassoCancel', e);
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.lassoBrushKey, false);
	      }
	    }
	  };
	}
	var lassoGesture = {
	  callLassoGesture
	};

	/**
	 * Handles measure range selection events for picasso charts using HammerJS. When activating measure range selection enable function is
	 * triggered first. measurerangestart is triggered on all areas specified by options.direction key. Only after measurerangestart
	 * is triggered, then the other events might be triggered as well. The different event
	 * names must be appended as suffixes for options.event. In this case options.event is called measurerange, then our
	 * events must be named measurerangestart, measurerangemove, measurerangeend, measurerangecancel.
	 */
	function callMeasureRangeGesture(state, gesturesFns, gesturesParams, measureAxis) {
	  const activeRangeBrush = gesturesParams.keys.dimRangeBrushKey ? 'majorrange' : 'arearange';
	  return {
	    type: 'Pan',
	    options: {
	      direction: gesturesParams.isHorizontal ? Hammer$1.DIRECTION_HORIZONTAL : Hammer$1.DIRECTION_VERTICAL,
	      event: 'measurerange',
	      enable(manager, e) {
	        if (!gesturesParams.rangeSelStatus.isOpenMea) {
	          return false;
	        }
	        if (state.measureSelecting) {
	          return gesturesFns.isSelectionEnabled();
	        }
	        const targets = gesturesParams.active.gesture === 'measurerange' ? [measureAxis, gesturesParams.keys.componentKey] : [measureAxis];
	        const hitComp = onComponentChecker.isOnComponentForRange(e, targets, this);
	        state.measureSelecting = gesturesFns.isSelectionEnabled() && !!e && !!hitComp;
	        return state.measureSelecting && !!gesturesParams.keys.measureRangeBrushKey;
	      }
	    },
	    requireFailure: `lasso ${activeRangeBrush}`,
	    recognizeWith: gesturesParams.handlers.scrollHandler ? 'drag' : null,
	    events: {
	      measurerangestart(e) {
	        const targets = gesturesParams.active.gesture === 'measurerange' ? [measureAxis, gesturesParams.keys.componentKey] : [measureAxis];
	        const hitComp = onComponentChecker.isOnComponentForRange(e, targets, this);
	        if (!hitComp) {
	          return;
	        }
	        state.measureSelecting = true;
	        gesturesFns.switchTo('measurerange', this.chart, e);
	        gesturesFns.doEmit(this.chart, 'rangeMeasure', 'rangeStart', e);
	        gesturesParams.handlers.selectionHandler.pauseEngineCalls(gesturesParams.keys.measureRangeBrushKey);
	      },
	      measurerangemove(e) {
	        if (!state.measureSelecting) {
	          return;
	        }
	        gesturesFns.doEmit(this.chart, 'rangeMeasure', 'rangeMove', e);
	      },
	      measurerangeend(e) {
	        if (!state.measureSelecting) {
	          return;
	        }
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.measureRangeBrushKey, true);
	        gesturesFns.doEmit(this.chart, 'rangeMeasure', 'rangeEnd', e);
	        state.measureSelecting = false;
	      },
	      measurerangecancel() {
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.measureRangeBrushKey, false);
	        state.measureSelecting = false;
	      }
	    }
	  };
	}
	var measureRangeGesture = {
	  callMeasureRangeGesture
	};

	function getAxisOrientation(axis, orientation) {
	  let dir;
	  if (axis === 'x-axis') {
	    dir = orientation === 'horizontal' ? Hammer$1.DIRECTION_VERTICAL : Hammer$1.DIRECTION_HORIZONTAL;
	  } else {
	    dir = orientation === 'horizontal' ? Hammer$1.DIRECTION_HORIZONTAL : Hammer$1.DIRECTION_VERTICAL;
	  }
	  return dir;
	}

	/**
	 * Handles area range selection events for picasso charts using HammerJS. When activating area range selection enable function is
	 * triggered first. arearangestart is triggered on all areas specified by options.direction key. Only after arearangestart
	 * is triggered, then the other events might be triggered as well. The different event
	 * names must be appended as suffixes for options.event. In this case options.event is called arearange, then our
	 * events must be named arearangestart, arearangemove, arearangeend, arearangecancel.
	 */
	function callAreaRangeGesture(state, gesturesFns, gesturesParams, axis) {
	  const activeRangeBrush = gesturesParams.keys.dimRangeBrushKey ? 'majorrange' : 'measurerange';
	  return {
	    // Area range select gesture
	    type: 'Pan',
	    options: {
	      direction: getAxisOrientation(axis, gesturesParams.isHorizontal),
	      event: 'arearange',
	      enable(manager, e) {
	        if (!gesturesParams.rangeSelStatus.isOpenDim) {
	          return false;
	        }
	        if (state.minoring) {
	          return gesturesFns.isSelectionEnabled();
	        }
	        const targets = gesturesParams.active.gesture === 'arearange' ? [axis, gesturesParams.keys.componentKey] : [axis];
	        const hitComp = onComponentChecker.isOnComponentForRange(e, targets, this);
	        state.minoring = gesturesFns.isSelectionEnabled() && !!e && !!hitComp;
	        return state.minoring;
	      }
	    },
	    requireFailure: `lasso ${activeRangeBrush}`,
	    recognizeWith: gesturesParams.handlers.scrollHandler ? 'drag' : null,
	    events: {
	      arearangestart(e) {
	        const targets = gesturesParams.active.gesture === 'arearange' ? [axis, gesturesParams.keys.componentKey] : [axis];
	        const hitComp = onComponentChecker.isOnComponentForRange(e, targets, this);
	        if (!hitComp) {
	          return;
	        }
	        state.minoring = true;
	        gesturesFns.switchTo('arearange', this.chart, e);
	        gesturesFns.doEmit(this.chart, 'rangeMinor', 'areaStart', e);
	        gesturesParams.handlers.selectionHandler.pauseEngineCalls(gesturesParams.keys.areaBrushKey);
	      },
	      arearangemove(e) {
	        if (!state.minoring) {
	          return;
	        }
	        // Behaves likes lasso, which adds all data points as soon as we hit the points, we only want to highlight the values within the range
	        this.chart.brush(gesturesParams.keys.areaBrushKey).clear();
	        gesturesFns.doEmit(this.chart, 'rangeMinor', 'areaMove', e);
	      },
	      arearangeend(e) {
	        if (!state.minoring) {
	          return;
	        }
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.areaBrushKey, true);
	        gesturesFns.doEmit(this.chart, 'rangeMinor', 'areaEnd', e);
	        state.minoring = false;
	      },
	      arearangecancel() {
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.areaBrushKey, false);
	        state.minoring = false;
	      }
	    }
	  };
	}
	var areaRangeGesture = {
	  callAreaRangeGesture
	};

	/**
	 * Handles dimension range selection events for picasso charts using HammerJS. When activating dimension range selection enable function is
	 * triggered first. majorrangestart is triggered on all areas specified by options.direction key. Only after majorrangestart
	 * is triggered, then the other events might be triggered as well. The different event
	 * names must be appended as suffixes for options.event. In this case options.event is called majorrange, then our
	 * events must be named majorrangestart, majorrangemove, majorrangeend, majorrangecancel.
	 */
	function callDimensionRangeGesture(state, gesturesFns, gesturesParams, dimAxis) {
	  const activeRangeBrush = gesturesParams.keys.measureRangeBrushKey ? 'measurerange' : 'arearange';
	  return {
	    type: 'Pan',
	    options: {
	      direction: gesturesParams.isHorizontal ? Hammer$1.DIRECTION_VERTICAL : Hammer$1.DIRECTION_HORIZONTAL,
	      event: 'majorrange',
	      enable(manager, e) {
	        if (!gesturesParams.rangeSelStatus.isOpenDim) {
	          return false;
	        }
	        if (state.majoring) {
	          return gesturesFns.isSelectionEnabled();
	        }
	        const targets = gesturesParams.active.gesture === 'majorrange' ? [dimAxis, gesturesParams.keys.componentKey] : [dimAxis];
	        const hitComp = onComponentChecker.isOnComponentForRange(e, targets, this);
	        state.majoring = gesturesFns.isSelectionEnabled() && !!e && !!hitComp;
	        return state.majoring && !!gesturesParams.keys.dimRangeBrushKey;
	      }
	    },
	    requireFailure: `lasso ${activeRangeBrush}`,
	    recognizeWith: gesturesParams.handlers.scrollHandler ? 'drag' : null,
	    events: {
	      majorrangestart(e) {
	        const targets = gesturesParams.active.gesture === 'majorrange' ? [dimAxis, gesturesParams.keys.componentKey] : [dimAxis];
	        const hitComp = onComponentChecker.isOnComponentForRange(e, targets, this);
	        if (!hitComp) {
	          return;
	        }
	        state.majoring = true;
	        gesturesFns.switchTo('majorrange', this.chart, e);
	        gesturesFns.doEmit(this.chart, 'rangeDim', 'rangeStart', e);
	        gesturesParams.handlers.selectionHandler.pauseEngineCalls(gesturesParams.keys.dimRangeBrushKey);
	      },
	      majorrangemove(e) {
	        if (!state.majoring) {
	          return;
	        }
	        gesturesFns.doEmit(this.chart, 'rangeDim', 'rangeMove', e);
	      },
	      majorrangeend(e) {
	        if (!state.majoring) {
	          return;
	        }
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.dimRangeBrushKey, true);
	        gesturesFns.doEmit(this.chart, 'rangeDim', 'rangeEnd', e);
	        state.majoring = false;
	      },
	      majorrangecancel() {
	        gesturesParams.handlers.selectionHandler.resumeEngineCalls(gesturesParams.keys.dimRangeBrushKey, false);
	        state.majoring = false;
	      }
	    }
	  };
	}
	var dimensionRangeGesture = {
	  callDimensionRangeGesture
	};

	/**
	 * Handles dragging for picasso charts using HammerJS. When activating dragging the enable function is
	 * triggered first. dragstart is triggered on all areas specified by options.direction key. The different event
	 * names must be appended as suffixes for options.event. In this case options.event is called drag, then our
	 * events must be named dragstart, dragmove, dragend, dragcancel.
	 */
	function callDragGesture(state, gesturesFns, gesturesParams, hasSelections, isRtl) {
	  let dragPoint = {};
	  return {
	    type: 'Pan',
	    options: {
	      direction: gesturesParams.isHorizontal ? Hammer$1.DIRECTION_VERTICAL : Hammer$1.DIRECTION_HORIZONTAL,
	      event: 'drag',
	      enable(manager, e) {
	        if (state.dragging) {
	          return gesturesFns.isNavigationEnabled();
	        }
	        state.dragging = gesturesFns.isNavigationEnabled() && !!e && !!this.chart.componentsFromPoint({
	          x: e.center.x,
	          y: e.center.y
	        }).filter(c => c.settings.key === gesturesParams.keys.componentKey)[0];
	        return state.dragging;
	      }
	    },
	    requireFailure: hasSelections ? `lasso ${gesturesFns.getBrushConfig()}` : '',
	    events: {
	      dragstart(e) {
	        dragPoint = {
	          x: e.deltaX,
	          y: e.deltaY
	        };
	        let change = -(gesturesParams.isHorizontal ? e.deltaY : e.deltaX) / gesturesParams.handlers.scrollHandler.getItemSize();
	        if (!gesturesParams.isHorizontal && isRtl) {
	          change = -change;
	        }
	        gesturesParams.handlers.scrollHandler.getScrollApi().move(change);
	      },
	      dragmove(e) {
	        if (!state.dragging) {
	          return;
	        }
	        let change = -(gesturesParams.isHorizontal ? e.deltaY - dragPoint.y : e.deltaX - dragPoint.x) / gesturesParams.handlers.scrollHandler.getItemSize();
	        if (!gesturesParams.isHorizontal && isRtl) {
	          change = -change;
	        }
	        gesturesParams.handlers.scrollHandler.getScrollApi().move(change);
	        dragPoint = {
	          x: e.deltaX,
	          y: e.deltaY
	        };
	      },
	      dragend() {
	        if (!state.dragging) {
	          return;
	        }
	        state.dragging = false;
	      },
	      dragcancel() {
	        state.dragging = false;
	      }
	    }
	  };
	}
	var dragGesture = {
	  callDragGesture
	};

	/**
	 * Handles navigational button events for picasso charts using HammerJS. When pressing on a navigational button,
	 * the enable function is triggered to check if the navigational button should be enabled or not.
	 * For example, in edit mode it should be disabled.
	 * @param isEnabledFn - Function that returns a boolean. In this case return false if in edit mode, true otherwise
	 * @param legendBrushKey - String defining the legend brush key
	 * @returns An object for reacting to tap events according to HammerJS API
	 */
	function callNavBtnGesture(isEnabledFn, legendBrushKey) {
	  return {
	    type: 'Tap',
	    options: {
	      event: 'navBtnTap',
	      enable(manager, e) {
	        if (!e || !isEnabledFn()) {
	          return false;
	        }
	        return onComponentChecker.isOnComponentForNavBtn(e, legendBrushKey, this);
	      }
	    },
	    events: {
	      navBtnTap(e) {
	        // Invokes paging interaction on legend
	        this.chart.componentsFromPoint(e.center).forEach(c => {
	          const btn = e.target;
	          const attr = btn ? btn.getAttribute('data-action') : '';
	          if (attr) {
	            return c.emit(attr);
	          }
	          return undefined;
	        });
	      }
	    }
	  };
	}
	var navBtnGesture = {
	  callNavBtnGesture
	};

	/**
	 * Creates Picasso components for interaction component that are dependent on eatchother
	 */

	function DependentInteractions(handlers, orientation, isRtl, keys, rangeSelStatus) {
	  const ret = {};
	  orientation = orientation || 'vertical';
	  const lassoBrushKey = keys.lassoBrushKey || 'select';
	  const dimRangeBrushKey = keys.dimRangeBrushKey || null;
	  const measureRangeBrushKey = keys.measureRangeBrushKey || null;
	  const areaBrushKey = keys.areaBrushKey || null;
	  const legendBrushKey = keys.legendBrushKey || null;
	  const hasSelections = !!handlers.selectionHandler && handlers.selectionHandler.isOn();
	  const state = {
	    dragging: false,
	    lassoing: false,
	    majoring: false,
	    minoring: false,
	    measureSelecting: false
	  };
	  const active = {
	    gesture: '',
	    type: ''
	  };
	  const isHorizontal = orientation === 'horizontal';
	  const dimAxis = isHorizontal ? 'y-axis' : 'x-axis';
	  const measureAxis = isHorizontal ? 'x-axis' : 'y-axis';
	  function switchTo(gesture, chart, e) {
	    if (active.gesture === gesture) {
	      return;
	    }
	    let clearKey = lassoBrushKey;
	    const activeChart = chart || active.chart;
	    switch (active.gesture) {
	      case 'majorrange':
	        doEmit(activeChart, 'rangeDim', 'rangeClear', e);
	        clearKey = dimRangeBrushKey;
	        break;
	      case 'measurerange':
	        doEmit(activeChart, 'rangeMeasure', 'rangeClear', e);
	        clearKey = measureRangeBrushKey;
	        break;
	      case 'arearange':
	        doEmit(activeChart, 'rangeMinor', 'areaClear', e);
	        clearKey = areaBrushKey;
	        break;
	    }
	    active.gesture = gesture;
	    const newType = gesture === 'range' ? 'range' : 'item';
	    if (active.type && active.type !== newType) {
	      activeChart.brush(clearKey).clear();
	    }
	    active.chart = chart;
	    active.type = newType;
	  }

	  // Just added here to allow easy disabling of things while developing
	  function doEmit(chart, comp, cont, e) {
	    if (chart) {
	      const inst = chart.component(comp);
	      if (inst) {
	        inst.emit(cont, e);
	      }
	    }
	  }
	  function getBrushConfig() {
	    if (!dimRangeBrushKey) {
	      return 'measurerange arearange';
	    }
	    if (!measureRangeBrushKey) {
	      return 'majorrange arearange';
	    }
	    return 'majorrange measurerange';
	  }
	  let gestures = [];
	  const gesturesFns = {
	    isSelectionEnabled: () => handlers.selectionHandler && handlers.selectionHandler.isOn(),
	    isNavigationEnabled: () => handlers.scrollHandler && handlers.scrollHandler.isOn(),
	    doEmit,
	    switchTo,
	    getBrushConfig
	  };
	  const gesturesParams = {
	    handlers,
	    keys,
	    isHorizontal,
	    active,
	    rangeSelStatus
	  };
	  if (hasSelections) {
	    gestures = [{
	      type: 'Tap',
	      options: {
	        event: 'rangeClearTap'
	      },
	      events: {
	        rangeClearTap(e) {
	          switchTo('none', this.chart, e);
	          state.majoring = false;
	          state.measureSelecting = false;
	          state.minoring = false;
	        }
	      }
	    }];

	    // Ordering matters here because the tap event, because the above gesture does not return anything
	    // and we want don't want to call the navigational button enable function for all tap events
	    gestures.unshift(navBtnGesture.callNavBtnGesture(gesturesFns.isNavigationEnabled, legendBrushKey));
	    gestures.push(lassoGesture.callLassoGesture(state, gesturesFns, gesturesParams));

	    // Only two of the axis range selection can exist at the same time
	    if (!dimRangeBrushKey) {
	      gestures.push(measureRangeGesture.callMeasureRangeGesture(state, gesturesFns, gesturesParams, measureAxis));
	      // Register component to selections handler so it is cleared properly
	      handlers.selectionHandler.addComponent(measureRangeBrushKey, {
	        id: 'rangeMeasure',
	        clear: 'rangeClear'
	      });
	      gestures.push(areaRangeGesture.callAreaRangeGesture(state, gesturesFns, gesturesParams, dimAxis));
	      handlers.selectionHandler.addComponent(areaBrushKey, {
	        id: 'rangeMinor',
	        clear: 'areaClear'
	      });
	    } else if (!measureRangeBrushKey) {
	      gestures.push(dimensionRangeGesture.callDimensionRangeGesture(state, gesturesFns, gesturesParams, dimAxis));
	      handlers.selectionHandler.addComponent(dimRangeBrushKey, {
	        id: 'rangeDim',
	        clear: 'rangeClear'
	      });
	      gestures.push(areaRangeGesture.callAreaRangeGesture(state, gesturesFns, gesturesParams, measureAxis));
	      handlers.selectionHandler.addComponent(areaBrushKey, {
	        id: 'rangeMinor',
	        clear: 'areaClear'
	      });
	    } else {
	      gestures.push(dimensionRangeGesture.callDimensionRangeGesture(state, gesturesFns, gesturesParams, dimAxis));
	      handlers.selectionHandler.addComponent(dimRangeBrushKey, {
	        id: 'rangeDim',
	        clear: 'rangeClear'
	      });
	      gestures.push(measureRangeGesture.callMeasureRangeGesture(state, gesturesFns, gesturesParams, measureAxis));
	      handlers.selectionHandler.addComponent(measureRangeBrushKey, {
	        id: 'rangeMeasure',
	        clear: 'rangeClear'
	      });
	    }
	  }
	  if (handlers.scrollHandler) {
	    gestures.push(dragGesture.callDragGesture(state, gesturesFns, gesturesParams, hasSelections, isRtl));

	    // On scroll we need to switch of the major ranging, so that pan will work
	    handlers.scrollHandler.getScrollApi().on('update', onScrollUpdate);
	  }
	  function onScrollUpdate() {
	    switchTo('none');
	    state.majoring = false;
	    state.measureSelecting = false;
	    state.minoring = false;
	  }
	  ret.gestures = gestures;
	  ret.destroy = function () {
	    if (handlers.scrollHandler) {
	      handlers.scrollHandler.getScrollApi().removeListener('update', onScrollUpdate);
	    }
	  };
	  return ret;
	}
	var DependentInteractions$1 = {
	  create: DependentInteractions
	};

	const ChartStyleComponent = (fontResolver, theme, chartId) => {
	  const propertyDefs = {};
	  propertyDefs.getOptions = (key, ref) => {
	    const getFontFamilyComponent = () => ({
	      ref: `${ref}.fontFamily`,
	      component: 'dropdown',
	      options: () => fontResolver.getOptions(`${ref}.fontFamily`),
	      defaultValue: () => fontResolver.getDefaultValue(`${ref}.fontFamily`)
	    });
	    const getFontSizeComponent = () => ({
	      ref: `${ref}.fontSize`,
	      component: 'dropdown',
	      width: true,
	      options: () => fontResolver.getOptions(`${ref}.fontSize`),
	      defaultValue: () => fontResolver.getDefaultValue(`${ref}.fontSize`)
	    });
	    const getColorComponent = (theme, chartId) => ({
	      ref: `${ref}.fontColor`,
	      component: 'color-picker',
	      width: false,
	      defaultValue: () => {
	        const color = theme.getStyle(chartId, `${ref}.color`, 'color');
	        const palette = theme.getDataColorPickerPalettes()[0].colors;
	        const index = palette.indexOf(color);
	        return {
	          color,
	          index
	        };
	      }
	    });
	    const getFontWrapperComponent = (theme, chartId) => ({
	      fontWrapper: {
	        component: 'inline-wrapper',
	        items: {
	          fontSize: {
	            ...getFontSizeComponent()
	          },
	          fontColor: {
	            ...getColorComponent(theme, chartId)
	          }
	        }
	      }
	    });
	    return {
	      labelSection: {
	        component: 'items',
	        ref: 'components',
	        key,
	        items: {
	          fontFamily: {
	            ...getFontFamilyComponent()
	          },
	          ...getFontWrapperComponent(theme, chartId)
	        }
	      }
	    };
	  };
	  return propertyDefs;
	};
	const getChartFontResolver = (theme, translator, chartId, createFontResolver, flags) => createFontResolver({
	  theme,
	  translator,
	  flags,
	  config: {
	    id: chartId,
	    paths: ['axis.title', 'axis.label.name', 'label.value', 'legend.title', 'legend.label']
	  }
	});
	const overrides = (key, layout) => (layout.components || []).find(c => c.key === key);
	const getAxisTitleStyle = (chartId, theme, layout) => {
	  const axis = overrides('axis', layout)?.axis;
	  return {
	    text: {
	      fontFamily: axis?.title?.fontFamily || theme.getStyle(chartId, 'axis.title', 'fontFamily'),
	      fontSize: axis?.title?.fontSize || theme.getStyle(chartId, 'axis.title', 'fontSize'),
	      fill: axis?.title?.fontColor?.color || theme.getStyle(chartId, 'axis.title', 'color')
	    }
	  };
	};
	const getAxisLabelStyle = (chartId, theme, layout) => {
	  const axis = overrides('axis', layout)?.axis;
	  return {
	    labels: {
	      fontFamily: axis?.label?.name?.fontFamily || theme.getStyle(chartId, 'axis.label.name', 'fontFamily'),
	      fontSize: axis?.label?.name?.fontSize || theme.getStyle(chartId, 'axis.label.name', 'fontSize'),
	      fill: axis?.label?.name?.fontColor?.color || theme.getStyle(chartId, 'axis.label.name', 'color')
	    }
	  };
	};
	const getValueLabelStyle = (chartId, styles, layout) => {
	  const value = overrides('value', layout)?.label;
	  const fontFamily = value?.value?.fontFamily || styles.label.value.fontFamily;
	  let fontSize = value?.value?.fontSize || styles.label.value.fontSize;
	  fontSize = parseFloat(fontSize);
	  const fill = value?.value?.fontColor?.color;
	  return {
	    fontFamily,
	    fontSize,
	    fill
	  };
	};

	const MAX_GLYPH_COUNT = 20;

	//
	// Implementation details
	//

	function getMaxGlyphCountForDimAxis(layout) {
	  const qApprMaxGlyphCount = vr(layout, 'qUndoExclude.box.qHyperCube.qDimensionInfo.0.qApprMaxGlyphCount', 0);
	  return Math.min(MAX_GLYPH_COUNT, qApprMaxGlyphCount);
	}
	function createDimensionAxisSettings(layout) {
	  return {
	    settings: {
	      labels: {
	        maxGlyphCount: getMaxGlyphCountForDimAxis(layout)
	      }
	    }
	  };
	}
	const DimensionAxis = {
	  createSettings: createDimensionAxisSettings
	};

	//
	// Implementation details
	//

	function createDimensionScaleSettings(layout) {
	  const isAutoMode = histogramUtils.isAutoBin(layout);
	  const binMode = histogramUtils.getBinMode(layout);
	  const binSize = histogramUtils.getDerivedBinSize(layout);
	  let min;
	  let max;
	  if (isAutoMode || binMode === 'maxCount') {
	    // User is expecting a specific number of bars so we make sure the axis
	    // will hold this number of bars even if there are not that many bars in the data
	    const offset = histogramUtils.getDerivedBinOffset(layout);
	    const binCount = histogramUtils.getDerivedBinCount(layout);
	    min = offset;
	    max = offset + binCount * binSize;
	  } else {
	    const dimInfo = vr(layout, 'qUndoExclude.box.qHyperCube.qDimensionInfo.0', {});
	    min = dimInfo.qMin || 0;
	    max = (dimInfo.qMax || 0) + binSize;
	  }
	  return {
	    component: {
	      type: 'linear',
	      min,
	      max
	    }
	  };
	}
	const DimensionScale = {
	  createSettings: createDimensionScaleSettings
	};

	const colorStruct = {
	  aliceblue: {
	    r: 240,
	    g: 248,
	    b: 255
	  },
	  antiquewhite: {
	    r: 250,
	    g: 235,
	    b: 215
	  },
	  aqua: {
	    r: 0,
	    g: 255,
	    b: 255
	  },
	  aquamarine: {
	    r: 127,
	    g: 255,
	    b: 212
	  },
	  azure: {
	    r: 240,
	    g: 255,
	    b: 255
	  },
	  beige: {
	    r: 245,
	    g: 245,
	    b: 220
	  },
	  bisque: {
	    r: 255,
	    g: 228,
	    b: 196
	  },
	  black: {
	    r: 0,
	    g: 0,
	    b: 0
	  },
	  blanchedalmond: {
	    r: 255,
	    g: 235,
	    b: 205
	  },
	  blue: {
	    r: 0,
	    g: 0,
	    b: 255
	  },
	  blueviolet: {
	    r: 138,
	    g: 43,
	    b: 226
	  },
	  brown: {
	    r: 165,
	    g: 42,
	    b: 42
	  },
	  burlywood: {
	    r: 222,
	    g: 184,
	    b: 135
	  },
	  cadetblue: {
	    r: 95,
	    g: 158,
	    b: 160
	  },
	  chartreuse: {
	    r: 127,
	    g: 255,
	    b: 0
	  },
	  chocolate: {
	    r: 210,
	    g: 105,
	    b: 30
	  },
	  coral: {
	    r: 255,
	    g: 127,
	    b: 80
	  },
	  cornflowerblue: {
	    r: 100,
	    g: 149,
	    b: 237
	  },
	  cornsilk: {
	    r: 255,
	    g: 248,
	    b: 220
	  },
	  crimson: {
	    r: 220,
	    g: 20,
	    b: 60
	  },
	  cyan: {
	    r: 0,
	    g: 255,
	    b: 255
	  },
	  darkblue: {
	    r: 0,
	    g: 0,
	    b: 139
	  },
	  darkcyan: {
	    r: 0,
	    g: 139,
	    b: 139
	  },
	  darkgoldenrod: {
	    r: 184,
	    g: 134,
	    b: 11
	  },
	  darkgray: {
	    r: 169,
	    g: 169,
	    b: 169
	  },
	  darkgreen: {
	    r: 0,
	    g: 100,
	    b: 0
	  },
	  darkgrey: {
	    r: 169,
	    g: 169,
	    b: 169
	  },
	  darkkhaki: {
	    r: 189,
	    g: 183,
	    b: 107
	  },
	  darkmagenta: {
	    r: 139,
	    g: 0,
	    b: 139
	  },
	  darkolivegreen: {
	    r: 85,
	    g: 107,
	    b: 47
	  },
	  darkorange: {
	    r: 255,
	    g: 140,
	    b: 0
	  },
	  darkorchid: {
	    r: 153,
	    g: 50,
	    b: 204
	  },
	  darkred: {
	    r: 139,
	    g: 0,
	    b: 0
	  },
	  darksalmon: {
	    r: 233,
	    g: 150,
	    b: 122
	  },
	  darkseagreen: {
	    r: 143,
	    g: 188,
	    b: 143
	  },
	  darkslateblue: {
	    r: 72,
	    g: 61,
	    b: 139
	  },
	  darkslategray: {
	    r: 47,
	    g: 79,
	    b: 79
	  },
	  darkslategrey: {
	    r: 47,
	    g: 79,
	    b: 79
	  },
	  darkturquoise: {
	    r: 0,
	    g: 206,
	    b: 209
	  },
	  darkviolet: {
	    r: 148,
	    g: 0,
	    b: 211
	  },
	  deeppink: {
	    r: 255,
	    g: 20,
	    b: 147
	  },
	  deepskyblue: {
	    r: 0,
	    g: 191,
	    b: 255
	  },
	  dimgray: {
	    r: 105,
	    g: 105,
	    b: 105
	  },
	  dimgrey: {
	    r: 105,
	    g: 105,
	    b: 105
	  },
	  dodgerblue: {
	    r: 30,
	    g: 144,
	    b: 255
	  },
	  firebrick: {
	    r: 178,
	    g: 34,
	    b: 34
	  },
	  floralwhite: {
	    r: 255,
	    g: 250,
	    b: 240
	  },
	  forestgreen: {
	    r: 34,
	    g: 139,
	    b: 34
	  },
	  fuchsia: {
	    r: 255,
	    g: 0,
	    b: 255
	  },
	  gainsboro: {
	    r: 220,
	    g: 220,
	    b: 220
	  },
	  ghostwhite: {
	    r: 248,
	    g: 248,
	    b: 255
	  },
	  gold: {
	    r: 255,
	    g: 215,
	    b: 0
	  },
	  goldenrod: {
	    r: 218,
	    g: 165,
	    b: 32
	  },
	  gray: {
	    r: 128,
	    g: 128,
	    b: 128
	  },
	  green: {
	    r: 0,
	    g: 128,
	    b: 0
	  },
	  greenyellow: {
	    r: 173,
	    g: 255,
	    b: 47
	  },
	  grey: {
	    r: 128,
	    g: 128,
	    b: 128
	  },
	  honeydew: {
	    r: 240,
	    g: 255,
	    b: 240
	  },
	  hotpink: {
	    r: 255,
	    g: 105,
	    b: 180
	  },
	  indianred: {
	    r: 205,
	    g: 92,
	    b: 92
	  },
	  indigo: {
	    r: 75,
	    g: 0,
	    b: 130
	  },
	  ivory: {
	    r: 255,
	    g: 255,
	    b: 240
	  },
	  khaki: {
	    r: 240,
	    g: 230,
	    b: 140
	  },
	  lavender: {
	    r: 230,
	    g: 230,
	    b: 250
	  },
	  lavenderblush: {
	    r: 255,
	    g: 240,
	    b: 245
	  },
	  lawngreen: {
	    r: 124,
	    g: 252,
	    b: 0
	  },
	  lemonchiffon: {
	    r: 255,
	    g: 250,
	    b: 205
	  },
	  lightblue: {
	    r: 173,
	    g: 216,
	    b: 230
	  },
	  lightcoral: {
	    r: 240,
	    g: 128,
	    b: 128
	  },
	  lightcyan: {
	    r: 224,
	    g: 255,
	    b: 255
	  },
	  lightgoldenrodyellow: {
	    r: 250,
	    g: 250,
	    b: 210
	  },
	  lightgray: {
	    r: 211,
	    g: 211,
	    b: 211
	  },
	  lightgreen: {
	    r: 144,
	    g: 238,
	    b: 144
	  },
	  lightgrey: {
	    r: 211,
	    g: 211,
	    b: 211
	  },
	  lightpink: {
	    r: 255,
	    g: 182,
	    b: 193
	  },
	  lightsalmon: {
	    r: 255,
	    g: 160,
	    b: 122
	  },
	  lightseagreen: {
	    r: 32,
	    g: 178,
	    b: 170
	  },
	  lightskyblue: {
	    r: 135,
	    g: 206,
	    b: 250
	  },
	  lightslategray: {
	    r: 119,
	    g: 136,
	    b: 153
	  },
	  lightslategrey: {
	    r: 119,
	    g: 136,
	    b: 153
	  },
	  lightsteelblue: {
	    r: 176,
	    g: 196,
	    b: 222
	  },
	  lightyellow: {
	    r: 255,
	    g: 255,
	    b: 224
	  },
	  lime: {
	    r: 0,
	    g: 255,
	    b: 0
	  },
	  limegreen: {
	    r: 50,
	    g: 205,
	    b: 50
	  },
	  linen: {
	    r: 250,
	    g: 240,
	    b: 230
	  },
	  magenta: {
	    r: 255,
	    g: 0,
	    b: 255
	  },
	  maroon: {
	    r: 128,
	    g: 0,
	    b: 0
	  },
	  mediumaquamarine: {
	    r: 102,
	    g: 205,
	    b: 170
	  },
	  mediumblue: {
	    r: 0,
	    g: 0,
	    b: 205
	  },
	  mediumorchid: {
	    r: 186,
	    g: 85,
	    b: 211
	  },
	  mediumpurple: {
	    r: 147,
	    g: 112,
	    b: 219
	  },
	  mediumseagreen: {
	    r: 60,
	    g: 179,
	    b: 113
	  },
	  mediumslateblue: {
	    r: 123,
	    g: 104,
	    b: 238
	  },
	  mediumspringgreen: {
	    r: 0,
	    g: 250,
	    b: 154
	  },
	  mediumturquoise: {
	    r: 72,
	    g: 209,
	    b: 204
	  },
	  mediumvioletred: {
	    r: 199,
	    g: 21,
	    b: 133
	  },
	  midnightblue: {
	    r: 25,
	    g: 25,
	    b: 112
	  },
	  mintcream: {
	    r: 245,
	    g: 255,
	    b: 250
	  },
	  mistyrose: {
	    r: 255,
	    g: 228,
	    b: 225
	  },
	  moccasin: {
	    r: 255,
	    g: 228,
	    b: 181
	  },
	  navajowhite: {
	    r: 255,
	    g: 222,
	    b: 173
	  },
	  navy: {
	    r: 0,
	    g: 0,
	    b: 128
	  },
	  oldlace: {
	    r: 253,
	    g: 245,
	    b: 230
	  },
	  olive: {
	    r: 128,
	    g: 128,
	    b: 0
	  },
	  olivedrab: {
	    r: 107,
	    g: 142,
	    b: 35
	  },
	  orange: {
	    r: 255,
	    g: 165,
	    b: 0
	  },
	  orangered: {
	    r: 255,
	    g: 69,
	    b: 0
	  },
	  orchid: {
	    r: 218,
	    g: 112,
	    b: 214
	  },
	  palegoldenrod: {
	    r: 238,
	    g: 232,
	    b: 170
	  },
	  palegreen: {
	    r: 152,
	    g: 251,
	    b: 152
	  },
	  paleturquoise: {
	    r: 175,
	    g: 238,
	    b: 238
	  },
	  palevioletred: {
	    r: 219,
	    g: 112,
	    b: 147
	  },
	  papayawhip: {
	    r: 255,
	    g: 239,
	    b: 213
	  },
	  peachpuff: {
	    r: 255,
	    g: 218,
	    b: 185
	  },
	  peru: {
	    r: 205,
	    g: 133,
	    b: 63
	  },
	  pink: {
	    r: 255,
	    g: 192,
	    b: 203
	  },
	  plum: {
	    r: 221,
	    g: 160,
	    b: 221
	  },
	  powderblue: {
	    r: 176,
	    g: 224,
	    b: 230
	  },
	  purple: {
	    r: 128,
	    g: 0,
	    b: 128
	  },
	  red: {
	    r: 255,
	    g: 0,
	    b: 0
	  },
	  rosybrown: {
	    r: 188,
	    g: 143,
	    b: 143
	  },
	  royalblue: {
	    r: 65,
	    g: 105,
	    b: 225
	  },
	  saddlebrown: {
	    r: 139,
	    g: 69,
	    b: 19
	  },
	  salmon: {
	    r: 250,
	    g: 128,
	    b: 114
	  },
	  sandybrown: {
	    r: 244,
	    g: 164,
	    b: 96
	  },
	  seagreen: {
	    r: 46,
	    g: 139,
	    b: 87
	  },
	  seashell: {
	    r: 255,
	    g: 245,
	    b: 238
	  },
	  sienna: {
	    r: 160,
	    g: 82,
	    b: 45
	  },
	  silver: {
	    r: 192,
	    g: 192,
	    b: 192
	  },
	  skyblue: {
	    r: 135,
	    g: 206,
	    b: 235
	  },
	  slateblue: {
	    r: 106,
	    g: 90,
	    b: 205
	  },
	  slategray: {
	    r: 112,
	    g: 128,
	    b: 144
	  },
	  slategrey: {
	    r: 112,
	    g: 128,
	    b: 144
	  },
	  snow: {
	    r: 255,
	    g: 250,
	    b: 250
	  },
	  springgreen: {
	    r: 0,
	    g: 255,
	    b: 127
	  },
	  steelblue: {
	    r: 70,
	    g: 130,
	    b: 180
	  },
	  tan: {
	    r: 210,
	    g: 180,
	    b: 140
	  },
	  teal: {
	    r: 0,
	    g: 128,
	    b: 128
	  },
	  thistle: {
	    r: 216,
	    g: 191,
	    b: 216
	  },
	  tomato: {
	    r: 255,
	    g: 99,
	    b: 71
	  },
	  transparent: {
	    r: 255,
	    g: 255,
	    b: 255,
	    a: 0
	  },
	  turquoise: {
	    r: 64,
	    g: 224,
	    b: 208
	  },
	  violet: {
	    r: 238,
	    g: 130,
	    b: 238
	  },
	  wheat: {
	    r: 245,
	    g: 222,
	    b: 179
	  },
	  white: {
	    r: 255,
	    g: 255,
	    b: 255
	  },
	  whitesmoke: {
	    r: 245,
	    g: 245,
	    b: 245
	  },
	  yellow: {
	    r: 255,
	    g: 255,
	    b: 0
	  },
	  yellowgreen: {
	    r: 154,
	    g: 205,
	    b: 50
	  }
	};

	/* eslint-disable camelcase */
	/* eslint-disable no-bitwise */
	/* eslint-disable no-nested-ternary */
	/* eslint-disable no-cond-assign */
	/* eslint-disable prefer-rest-params */


	// color formats
	const rgb = /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/i;
	const rgba = /^rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),(\d(\.\d+)?)\)$/i;
	const hex = /^#([A-f0-9]{2})([A-f0-9]{2})([A-f0-9]{2})$/i;
	const hexShort = /^#([A-f0-9])([A-f0-9])([A-f0-9])$/i;
	const hsl = /^hsl\(\s*(\d+(\.\d+)?)\s*,\s*(\d+(\.\d+)?%?)\s*,\s*(\d+(\.\d+)?%?)\s*\)$/i;
	const hsla = /^hsla\(\s*(\d+(\.\d+)?)\s*,\s*(\d+(\.\d+)?%?)\s*,\s*(\d+(\.\d+)?%?)\s*,(\d(\.\d+)?)\)$/i;
	const floor = Math.floor;
	const round = Math.round;

	/**
	 * @class
	 * @classdesc Class which provides color transformation functionality
	 * @description This is a constructor.
	 * @param {object} - Parameters to create a color from different notations
	 * @example
	 * // a few ways of instantiating a red color
	 * var red;
	 * red = new Color(255, 0, 0, 1); // rgba as parameters
	 * red = new Color('#ff0000'); // hex
	 * red = new Color('rgb(255,0,0)');//rgb as string
	 * red = new Color('hsl(0, 100, 50)');// hsl as string
	 * red = new Color(16711680);// uint
	 */
	const Color = Class.extend(/** @lends module:objects.views/charts/representation/color~Color# */{
	  init() {
	    let r = 0;
	    let g = 0;
	    let b = 0;
	    let a = 1;
	    let h;
	    let s;
	    let lcs;
	    let l;
	    let v;
	    let c;
	    let h_;
	    let x;
	    let rgb_;
	    let m;
	    let matches;
	    let colorString;
	    this._invalid = false;
	    if (arguments[0] instanceof Color) {
	      r = arguments[0]._r;
	      g = arguments[0]._g;
	      b = arguments[0]._b;
	      a = arguments[0]._a;
	      this._invalid = arguments[0]._invalid;
	    } else if (arguments.length < 3) {
	      if (typeof arguments[0] === 'string') {
	        colorString = arguments[0];
	        if (matches = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i.exec(colorString)) {
	          r = parseInt(matches[1], 10);
	          g = parseInt(matches[2], 10);
	          b = parseInt(matches[3], 10);
	        } else if (matches = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d(\.\d+)?)\s*\)$/i.exec(colorString)) {
	          // rgba(1, 2, 3, 0.4)
	          r = parseInt(matches[1], 10);
	          g = parseInt(matches[2], 10);
	          b = parseInt(matches[3], 10);
	          a = parseFloat(matches[4]);
	        } else if (matches = /^#([A-f0-9]{2})([A-f0-9]{2})([A-f0-9]{2})$/i.exec(colorString)) {
	          // #aBc123
	          r = parseInt(matches[1], 16);
	          g = parseInt(matches[2], 16);
	          b = parseInt(matches[3], 16);
	          a = 1;
	        } else if (matches = /^#([A-f0-9])([A-f0-9])([A-f0-9])$/i.exec(colorString)) {
	          // #a5F
	          r = parseInt(matches[1] + matches[1], 16);
	          g = parseInt(matches[2] + matches[2], 16);
	          b = parseInt(matches[3] + matches[3], 16);
	          a = 1;
	        } else if (matches = /^hsl\(\s*(\d+(\.\d+)?)\s*,\s*(\d+(\.\d+)?%?)\s*,\s*(\d+(\.\d+)?%?)\s*\)$/i.exec(colorString)) {
	          // hsl(1, 2, 3)
	          h = parseFloat(matches[1]);
	          s = parseFloat(matches[3]);
	          l = parseFloat(matches[5]);
	          h %= 360;
	          s /= 100;
	          l /= 100;
	          h = h < 0 ? 0 : h > 360 ? 360 : h;
	          s = s < 0 ? 0 : s > 1 ? 1 : s;
	          l = l < 0 ? 0 : l > 1 ? 1 : l;
	          c = l <= 0.5 ? 2 * l * s : (2 - 2 * l) * s;
	          h_ = h / 60;
	          x = c * (1 - Math.abs(h_ % 2 - 1));
	          rgb_ = [];
	          h_ = Math.floor(h_);
	          switch (h_) {
	            case 0:
	              rgb_ = [c, x, 0];
	              break;
	            case 1:
	              rgb_ = [x, c, 0];
	              break;
	            case 2:
	              rgb_ = [0, c, x];
	              break;
	            case 3:
	              rgb_ = [0, x, c];
	              break;
	            case 4:
	              rgb_ = [x, 0, c];
	              break;
	            case 5:
	              rgb_ = [c, 0, x];
	              break;
	            default:
	              rgb_ = [0, 0, 0];
	          }
	          m = l - 0.5 * c;
	          r = rgb_[0] + m;
	          g = rgb_[1] + m;
	          b = rgb_[2] + m;
	          r = round(255 * r);
	          g = round(255 * g);
	          b = round(255 * b);
	          a = 1.0;
	        } else if (matches = /^hsla\(\s*(\d+(\.\d+)?)\s*,\s*(\d+(\.\d+)?%?)\s*,\s*(\d+(\.\d+)?%?)\s*,(\d(\.\d+)?)\)$/i.exec(colorString)) {
	          // hsla(1,2,3,0.4)
	          h = parseFloat(matches[1]);
	          s = parseFloat(matches[3]);
	          l = parseFloat(matches[5]);
	          a = parseFloat(matches[7]);
	          h %= 360;
	          s /= 100;
	          l /= 100;
	          h = h < 0 ? 0 : h > 360 ? 360 : h;
	          s = s < 0 ? 0 : s > 1 ? 1 : s;
	          l = l < 0 ? 0 : l > 1 ? 1 : l;
	          c = l <= 0.5 ? 2 * l * s : (2 - 2 * l) * s;
	          h_ = h / 60;
	          x = c * (1 - Math.abs(h_ % 2 - 1));
	          rgb_ = [];
	          h_ = Math.floor(h_);
	          switch (h_) {
	            case 0:
	              rgb_ = [c, x, 0];
	              break;
	            case 1:
	              rgb_ = [x, c, 0];
	              break;
	            case 2:
	              rgb_ = [0, c, x];
	              break;
	            case 3:
	              rgb_ = [0, x, c];
	              break;
	            case 4:
	              rgb_ = [x, 0, c];
	              break;
	            case 5:
	              rgb_ = [c, 0, x];
	              break;
	            default:
	              rgb_ = [0, 0, 0];
	          }
	          m = l - 0.5 * c;
	          r = rgb_[0] + m;
	          g = rgb_[1] + m;
	          b = rgb_[2] + m;
	          r = round(255 * r);
	          g = round(255 * g);
	          b = round(255 * b);
	        } else if (matches = /^hsv\(\s*(\d+(\.\d+)?)\s*,\s*(\d+(\.\d+)?%?)\s*,\s*(\d+(\.\d+)?%?)\s*\)$/i.exec(colorString)) {
	          // hsv(1, 2, 3) {
	          h = parseFloat(matches[1]);
	          s = parseFloat(matches[3]);
	          v = parseFloat(matches[5]);
	          h %= 360;
	          s /= 100;
	          v /= 100;
	          h = h < 0 ? 0 : h > 360 ? 360 : h;
	          s = s < 0 ? 0 : s > 1 ? 1 : s;
	          v = v < 0 ? 0 : v > 1 ? 1 : v;
	          c = v * s;
	          h_ = h / 60;
	          x = c * (1 - Math.abs(h_ % 2 - 1));
	          rgb_ = [];
	          h_ = Math.floor(h_);
	          switch (h_) {
	            case 0:
	              rgb_ = [c, x, 0];
	              break;
	            case 1:
	              rgb_ = [x, c, 0];
	              break;
	            case 2:
	              rgb_ = [0, c, x];
	              break;
	            case 3:
	              rgb_ = [0, x, c];
	              break;
	            case 4:
	              rgb_ = [x, 0, c];
	              break;
	            case 5:
	              rgb_ = [c, 0, x];
	              break;
	            default:
	              rgb_ = [0, 0, 0];
	          }
	          m = v - c;
	          r = rgb_[0] + m;
	          g = rgb_[1] + m;
	          b = rgb_[2] + m;
	          r = round(255 * r);
	          g = round(255 * g);
	          b = round(255 * b);
	          a = 1.0;
	        } else if (colorStruct[colorString.toLowerCase()]) {
	          lcs = colorString.toLowerCase();
	          r = colorStruct[lcs].r;
	          g = colorStruct[lcs].g;
	          b = colorStruct[lcs].b;
	          a = typeof colorStruct[lcs].a === 'number' ? colorStruct[lcs].a : 1.0;
	        } else {
	          this._invalid = true;
	        }
	      } else if (typeof arguments[0] === 'number' && arguments[0] >= 0 && arguments[1] === 'argb') {
	        a = (0xff000000 & arguments[0]) >>> 24;
	        a /= 255;
	        r = (0xff0000 & arguments[0]) >> 16;
	        g = (0x00ff00 & arguments[0]) >> 8;
	        b = 0x0000ff & arguments[0];
	      } else if (typeof arguments[0] === 'number' && arguments[0] >= 0) {
	        r = (0xff0000 & arguments[0]) >> 16;
	        g = (0x00ff00 & arguments[0]) >> 8;
	        b = 0x0000ff & arguments[0];
	      } else {
	        this._invalid = true;
	      }
	    } else if (arguments.length >= 3) {
	      r = arguments[0];
	      g = arguments[1];
	      b = arguments[2];
	      a = arguments.length >= 4 ? arguments[3] : 1;
	    } else {
	      this._invalid = true;
	    }
	    if (Number.isNaN(+r + g + b + a)) {
	      this._invalid = true;
	    }
	    this._r = floor(r);
	    this._g = floor(g);
	    this._b = floor(b);
	    this._a = a;

	    // object to cache string representations in various color spaces
	    this._spaces = {};
	  },
	  isInvalid() {
	    return this._invalid;
	  },
	  /**
	   * Sets alpha value of color
	   * @param {number} a - Alpha value of the color
	   */
	  setAlpha(a) {
	    this._a = a;
	    this._spaces = {};
	  },
	  /**
	   * Gets the alpha value of this color
	   * @returns {number}
	   */
	  getAlpha() {
	    return this._a;
	  },
	  /**
	   * Returns an rgb string representation of this color.
	   * @return {string} An rgb string representation of this color
	   */
	  toRGB: function toRGB() {
	    if (!this._spaces.rgb) {
	      this._spaces.rgb = Color.toRGB(this);
	    }
	    return this._spaces.rgb;
	  },
	  /**
	   * Returns an rgba string representation of this color.
	   * @return {string} An rgba string representation of this color.
	   */
	  toRGBA: function toRGBA() {
	    if (!this._spaces.rgba) {
	      this._spaces.rgba = Color.toRGBA(this);
	    }
	    return this._spaces.rgba;
	  },
	  toString() {
	    if (!this._spaces.rgb) {
	      this._spaces.rgb = Color.toRGB(this);
	    }
	    return this._spaces.rgb;
	  },
	  /**
	   * Returns a hex string representation of this color.
	   * @return {string}
	   */
	  toHex: function toHex() {
	    if (!this._spaces.hex) {
	      this._spaces.hex = Color.toHex(this);
	    }
	    return this._spaces.hex;
	  },
	  /**
	   * Returns a hsl string representation of this color using "bi-hexcone" model for lightness
	   * @param {boolean} luma - Whether to use luma calculation
	   * @return {string} In format hsl(0,0,0)
	   */
	  toHSL: function toHSL(luma) {
	    if (!this._spaces.hsl) {
	      this._spaces.hsl = Color.toHSL(this, luma);
	    }
	    return this._spaces.hsl;
	  },
	  /**
	   * Returns a hsla string representation of this color using "bi-hexcone" model for lightness
	   * @param {boolean} luma - Whether to use luma calculation
	   * @return {string} In format hsla(0,0,0,0)
	   */
	  toHSLA: function toHSLA(luma) {
	    if (!this._spaces.hsla) {
	      this._spaces.hsla = Color.toHSLA(this, luma);
	    }
	    return this._spaces.hsla;
	  },
	  /**
	   * Return the color components in hsv space using "hexcone" model for value (lightness)
	   * @param {Color|string} c
	   * @returns {object} The color components in hsv space {h:0-360, s:0-100, v:0-100}
	   */
	  toHSV() {
	    const hsvComp = this.toHSVComponents();
	    return `hsv(${hsvComp.h},${hsvComp.s},${hsvComp.v})`;
	  },
	  /**
	   * Return the color components in hsv space using "hexcone" model for value (lightness)
	   * @param {Color|string} c
	   * @returns {object} The color components in hsv space {h:0-360, s:0-100, v:0-100}
	   */
	  toHSVComponents: function toHSVComponents() {
	    if (!this._spaces.hsvComp) {
	      this._spaces.hsvComp = Color.toHSVComponents(this);
	    }
	    return this._spaces.hsvComp;
	  },
	  /**
	   * Returns a uint representation of this color
	   * @return {number}
	   */
	  toNumber: function toNumber() {
	    if (!this._spaces.num) {
	      this._spaces.num = Color.toNumber(this);
	    }
	    return this._spaces.num;
	  },
	  /**
	   * Checks if this color is perceived as dark.
	   * @return {string} True if the luminance is below 160, false otherwise.
	   */
	  isDark() {
	    return this.isInvalid() || this.getLuminance() < 125; // luminace calc option #2
	    // return this.getLuminance() < 160; //luminace calc option #3
	  },
	  /**
	   * Calculates the perceived luminance of the color.
	   * @return {number} A value in the range 0-255 where a low value is considered dark and vice versa.
	   */
	  getLuminance() {
	    // alpha channel is not considered
	    if (typeof this._lumi === 'undefined') {
	      // calculate luminance
	      // this._lumi = 0.2126 * this._r + 0.7152 * this._g + 0.0722 * this._b; // option 1
	      this._lumi = 0.299 * this._r + 0.587 * this._g + 0.114 * this._b; // option 2
	      // this._lumi = Math.sqrt( 0.241 * this._r * this._r + 0.691 * this._g * this._g + 0.068 * this._b * this._b ); // option 3
	    }
	    return this._lumi;
	  },
	  /**
	   * Shifts the color towards a lighter or darker shade
	   * @param {number} value - A value in the range -100-100 to shift the color with along the HSL lightness.
	   * @return {string} The shifted color as hsla string.
	   */
	  shiftLuminance(value) {
	    const chsla = this.toHSLA();
	    const matches = /^hsla\(\s*(\d+(\.\d+)?)\s*,\s*(\d+(\.\d+)?%?)\s*,\s*(\d+(\.\d+)?%?)\s*,(\d(\.\d+)?)\)$/i.exec(chsla);
	    const h = parseFloat(matches[1]);
	    const s = parseFloat(matches[3]);
	    let l = parseFloat(matches[5]);
	    const a = parseFloat(matches[7]);
	    // l *= 1 + value / 100;
	    // l = Math.max( 0, l % 100 );
	    l += value;
	    l = Math.max(0, Math.min(l, 100));

	    // if( value > 0 ){
	    // s = s*0.2; //removing saturation to avoid the border from being too light
	    // }

	    return `hsla(${h},${s},${l},${a})`;
	  },
	  /**
	   * Compares two colors.
	   * @param {Color} c The color to compare with.
	   * @return {boolean} True if the rgb channels are the same, false otherwise
	   */
	  isEqual(c) {
	    if (c instanceof Color) {
	      return this._r === c._r && this._g === c._g && this._b === c._b;
	    }
	    c = new Color(c);
	    return this._r === c._r && this._g === c._g && this._b === c._b;
	  },
	  /**
	   * Linearly interpolates each channel of two colors.
	   * @param {Color} c2 The other color.
	   * @param {number} t The interpolation value in the range (0-1).
	   * @return {string} The blend as an rgb string.
	   */
	  blend(c2, t) {
	    const r = floor(this._r + (c2._r - this._r) * t);
	    const g = floor(this._g + (c2._g - this._g) * t);
	    const b = floor(this._b + (c2._b - this._b) * t);
	    const a = floor(this._a + (c2._a - this._a) * t);
	    return `rgba(${[r, g, b, a].join(',')})`;
	  },
	  createShiftedColor(v) {
	    if (v === undefined || Number.isNaN(+v)) {
	      v = 1;
	    }
	    const lumi = this.getLuminance();
	    const greenMultiplier = this._g < 126 ? 1 : 1 + this._g / 512;
	    const hsla_string = this.shiftLuminance((lumi * greenMultiplier < 220 ? 0.8 + 4 * (1 / (lumi + 1)) : -(0.8 + 1 * (lumi / 255))) * 20 * v);
	    return new Color(hsla_string);
	  }
	});

	/**
	 * Returns an rgb string representation of this color
	 * @param {Color|string} c
	 * @returns {string} An rgb string with channel values within range 0-255.
	 */
	Color.toRGB = function toRGB(c) {
	  if (c instanceof Color) {
	    return `rgb(${[c._r, c._g, c._b].join(',')})`;
	  }
	  if (typeof c === 'string') {
	    c = Color.toNumber(c);
	  }
	  const r = (c & 0xff0000) >> 16;
	  const g = (c & 0x00ff00) >> 8;
	  const b = c & 0x0000ff;
	  return `rgb(${r},${g},${b})`;
	};
	/**
	 *
	 * @param c
	 * @param a
	 * @returns {string} The color rgb format.
	 */
	Color.toRGBA = function toRGB(c, a) {
	  if (c instanceof Color) {
	    return `rgba(${[c._r, c._g, c._b, typeof a !== 'undefined' ? a : c._a].join(',')})`;
	  }
	  if (typeof c === 'string') {
	    c = Color.toNumber(c);
	  }
	  const r = (c & 0xff0000) >> 16;
	  const g = (c & 0x00ff00) >> 8;
	  const b = c & 0x0000ff;
	  return `rgba(${r},${g},${b},${typeof a !== 'undefined' ? a : c._a})`;
	};
	/**
	 *
	 * @param {Color|string} c
	 * @returns {string} The color in hexadecimal space.
	 */
	Color.toHex = function toHex(c) {
	  let r;
	  let g;
	  let b;
	  if (c instanceof Color) {
	    r = c._r.toString(16);
	    g = c._g.toString(16);
	    b = c._b.toString(16);
	    if (r.length === 1) {
	      r = `0${r}`;
	    }
	    if (g.length === 1) {
	      g = `0${g}`;
	    }
	    if (b.length === 1) {
	      b = `0${b}`;
	    }
	    return `#${[r, g, b].join('')}`;
	  }
	  if (typeof c === 'string') {
	    c = Color.toNumber(c);
	  }
	  r = ((c & 0xff0000) >> 16).toString(16);
	  g = ((c & 0x00ff00) >> 8).toString(16);
	  b = (c & 0x0000ff).toString(16);
	  if (r.length === 1) {
	    r = `0${r}`;
	  }
	  if (g.length === 1) {
	    g = `0${g}`;
	  }
	  if (b.length === 1) {
	    b = `0${b}`;
	  }
	  return `#${r}${g}${b}`;
	};
	/**
	 * Return the color in hsl space using "bi-hexcone" model for lightness
	 * @param {Color|string} c
	 * @param {boolean} luma - Whether to use luma calculation
	 * @returns {string} The color in hsl space.
	 */
	Color.toHSL = function (c, luma) {
	  let h = 0;
	  let s;
	  let l;
	  let ch;
	  if (typeof c === 'string') {
	    c = new Color(c);
	  }

	  // red, green, blue, hue, saturation, lightness/luma, max, min, chroma
	  const r = c._r / 255;
	  const g = c._g / 255;
	  const b = c._b / 255;
	  const max = Math.max(r, g, b);
	  const min = Math.min(r, g, b);
	  if (luma) {
	    // Y'709 http://en.wikipedia.org/wiki/Rec._709
	    // Y′709 = 0.21R + 0.72G + 0.07B
	    l = 0.21 * r + 0.72 * g + 0.07 * b;
	  } else {
	    l = (max + min) / 2;
	  }
	  if (max === min) {
	    // greyscale
	    s = 0;
	    h = 0;
	  } else {
	    ch = max - min;
	    s = l > 0.5 ? ch / (2 - max - min) : ch / (max + min);
	    switch (max) {
	      case r:
	        h = (g - b) / ch + (g < b ? 6 : 0);
	        break;
	      case g:
	        h = (b - r) / ch + 2;
	        break;
	      case b:
	        h = (r - g) / ch + 4;
	        break;
	    }
	    h /= 6;
	  }
	  return `hsl(${h * 360},${s * 100},${l * 100})`;
	};
	/**
	 * Return the color in hsla space using "bi-hexcone" model for lightness
	 * @param {Color|string} c
	 * @param {boolean} luma - Whether to use luma calculation
	 * @returns {string} The color in hsla space.
	 */
	Color.toHSLA = function (c, luma) {
	  let h = 0;
	  let s;
	  let l;
	  let ch;
	  if (typeof c === 'string') {
	    c = new Color(c);
	  }

	  // red, green, blue, hue, saturation, lightness/luma, max, min, chroma
	  const r = c._r / 255;
	  const g = c._g / 255;
	  const b = c._b / 255;
	  const a = c._a;
	  const max = Math.max(r, g, b);
	  const min = Math.min(r, g, b);
	  if (luma) {
	    // Y'709 http://en.wikipedia.org/wiki/Rec._709
	    // Y′709 = 0.21R + 0.72G + 0.07B
	    l = 0.21 * r + 0.72 * g + 0.07 * b;
	  } else {
	    l = (max + min) / 2;
	  }
	  if (max === min) {
	    // greyscale
	    s = 0;
	    h = 0;
	  } else {
	    ch = max - min;
	    s = l > 0.5 ? ch / (2 - max - min) : ch / (max + min);
	    switch (max) {
	      case r:
	        h = (g - b) / ch + (g < b ? 6 : 0);
	        break;
	      case g:
	        h = (b - r) / ch + 2;
	        break;
	      case b:
	        h = (r - g) / ch + 4;
	        break;
	    }
	    h /= 6;
	  }
	  return `hsla(${h * 360},${s * 100},${l * 100},${a})`;
	};
	/**
	 * Return the color components in hsv space using "hexcone" model for value (lightness)
	 * @param {Color|string} c
	 * @returns {object} The color components in hsv space {h:0-360, s:0-100, v:0-100}
	 */
	Color.toHSVComponents = function (c) {
	  let h = 0;
	  let s;
	  let ch;
	  if (typeof c === 'string') {
	    c = new Color(c);
	  }

	  // red, green, blue, hue, saturation, value/luma, max, min, chroma
	  const r = c._r / 255;
	  const g = c._g / 255;
	  const b = c._b / 255;
	  const max = Math.max(r, g, b);
	  const min = Math.min(r, g, b);
	  const v = max;
	  if (max === min) {
	    // greyscale
	    s = 0;
	    h = 0;
	  } else {
	    ch = max - min;
	    s = ch === 0 ? 0 : ch / v;
	    switch (max) {
	      case r:
	        h = (g - b) / ch + (g < b ? 6 : 0);
	        break;
	      case g:
	        h = (b - r) / ch + 2;
	        break;
	      case b:
	        h = (r - g) / ch + 4;
	        break;
	    }
	    h /= 6;
	  }
	  return {
	    h: h * 360 % 360,
	    s: s * 100,
	    v: v * 100
	  };
	};
	/**
	 * Returns an number representation of the color
	 * @param {Color|string} c
	 * @returns {Number} Unsigned integer in the range 0-16 777 216
	 */
	Color.toNumber = function toNumber() {
	  if (arguments.length === 1 && arguments[0] instanceof Color) {
	    return (arguments[0]._r << 16) + (arguments[0]._g << 8) + arguments[0]._b;
	  }
	  let r = 0;
	  let g = 0;
	  let b = 0;
	  let matches;
	  let colorString;
	  if (arguments.length === 1) {
	    if (typeof arguments[0] === 'string') {
	      colorString = arguments[0];
	      if (matches = /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/i.exec(colorString)) {
	        r = parseInt(matches[1], 10);
	        g = parseInt(matches[2], 10);
	        b = parseInt(matches[3], 10);
	      } else if (matches = /^#([A-f0-9]{2})([A-f0-9]{2})([A-f0-9]{2})$/i.exec(colorString)) {
	        r = parseInt(matches[1], 16);
	        g = parseInt(matches[2], 16);
	        b = parseInt(matches[3], 16);
	      } else if (matches = /^#([A-f0-9])([A-f0-9])([A-f0-9])$/i.exec(colorString)) {
	        r = parseInt(matches[1] + matches[1], 16);
	        g = parseInt(matches[2] + matches[2], 16);
	        b = parseInt(matches[3] + matches[3], 16);
	      }
	    }
	  }
	  return (r << 16) + (g << 8) + b;
	};
	Color.blend = function blend(c1, c2, t) {
	  c1 = Color.toNumber(c1);
	  c2 = Color.toNumber(c2);
	  const r1 = (c1 & 0xff0000) >> 16;
	  const g1 = (c1 & 0x00ff00) >> 8;
	  const b1 = c1 & 0x0000ff;
	  const r2 = (c2 & 0xff0000) >> 16;
	  const g2 = (c2 & 0x00ff00) >> 8;
	  const b2 = c2 & 0x0000ff;
	  const r = r1 + (r2 - r1) * t;
	  const g = g1 + (g2 - g1) * t;
	  const b = b1 + (b2 - b1) * t;
	  return (r << 16) + (g << 8) + b;
	};
	Color.getBlend = function getBlend(c1, c2, t) {
	  const r = c1._r + (c2._r - c1._r) * t;
	  const g = c1._g + (c2._g - c1._g) * t;
	  const b = c1._b + (c2._b - c1._b) * t;
	  const a = c1._a + (c2._a - c1._a) * t;
	  return new Color(r, g, b, a);
	};
	Color.isCSSColor = function (color) {
	  if (arguments.length > 1 || typeof color !== 'string') {
	    return false;
	  }
	  return rgb.test(color) || rgba.test(color) || hex.test(color) || hexShort.test(color) || hsl.test(color) || hsla.test(color) || colorStruct[color.toLowerCase()];
	};
	Color.getBestContrast = function (color, cl, cd) {
	  const lum = color.getLuminance();
	  return Math.abs(lum - cl.getLuminance()) > Math.abs(lum - cd.getLuminance()) ? cl : cd;
	};
	Color.getContrast = function (color1, color2) {
	  if (!color1 || !color2) {
	    return undefined;
	  }
	  const l1 = color1.getLuminance() / 100;
	  const l2 = color2.getLuminance() / 100;
	  if (l1 > l2) {
	    return (l1 + 0.05) / (l2 + 0.05);
	  }
	  return (l2 + 0.05) / (l1 + 0.05);
	};
	Color.isDark = function () {
	  const o = {
	    getLuminance: Color.prototype.getLuminance,
	    isInvalid: Color.prototype.isInvalid
	  };
	  Color.prototype.init.apply(o, [].slice.call(arguments));
	  return Color.prototype.isDark.call(o);
	};
	Color.useDarkLabel = function (areaColor, bgIsDark) {
	  return areaColor._a > 0.5 ? !areaColor.isDark() : !bgIsDark;
	};

	const chartUtils = {
	  TRANSPARENT_BLACK: 'rgba( 0,0,0,0.2 )',
	  TRANSPARENT_WHITE: 'rgba( 255,255,255,0.7 )',
	  LIGHT_GREY: '#ccc',
	  DARK_GREY: '#666',
	  BLACK: '#000',
	  WHITE: '#fff',
	  getInverse(color) {
	    const colorObj = new Color(color);
	    const alpha = colorObj.getAlpha();
	    if (alpha === 0) {
	      return this.BLACK;
	    }
	    return colorObj.isDark() ? this.WHITE : this.BLACK;
	  },
	  getContrastingGrey(color) {
	    const colorObj = new Color(color);
	    const alpha = colorObj.getAlpha();
	    if (alpha === 0) {
	      return this.DARK_GREY;
	    }
	    return Color.getBestContrast(colorObj, new Color(chartUtils.LIGHT_GREY), new Color(chartUtils.DARK_GREY));
	  },
	  getBestContrast(color, color1, color2) {
	    return Color.getBestContrast(new Color(color), new Color(color1), new Color(color2));
	  },
	  getContrastingTransparent(color) {
	    const colorObj = new Color(color);
	    const alpha = colorObj.getAlpha();
	    if (alpha === 0 || color === 'none') {
	      return this.TRANSPARENT_BLACK;
	    }
	    return colorObj.isDark() ? this.TRANSPARENT_WHITE : this.TRANSPARENT_BLACK;
	  }
	};

	//
	// Implementation details
	//

	function createBoxMarkerSettings(chartView, layout, basicSelectionSettings, dimensionSelectionSettings, measureSelectionSettings, tooltipSettings) {
	  const {
	    theme
	  } = chartView.environment;
	  const boxFillColor = theme.getColorPickerColor(layout.color.bar.paletteColor);
	  const binSize = histogramUtils.getDerivedBinSize(layout);
	  const brushTrigger = [];
	  const brushConsume = [basicSelectionSettings.consume, dimensionSelectionSettings.consume, measureSelectionSettings.consume];
	  if (chartView._tooltipHandler.isOn()) {
	    brushTrigger.push(tooltipSettings.box.trigger);
	    // eslint-disable-next-line prefer-spread
	    brushConsume.push.apply(brushConsume, tooltipSettings.box.consume);
	  }
	  brushTrigger.push(basicSelectionSettings.trigger);
	  return {
	    key: 'box-marker',
	    settings: {
	      box: {
	        fill: boxFillColor,
	        stroke: chartUtils.getContrastingGrey(boxFillColor).toHex(),
	        strokeWidth: 1,
	        maxWidthPx: Infinity,
	        minWidthPx: NaN,
	        // Temp fix for QLIK-92353 until a proper fix is available in picasso.js
	        minWidth: 0
	      },
	      major: {
	        scale: 'dimension',
	        ref: {
	          start: 'binStart',
	          end: 'binEnd'
	        }
	      },
	      minor: {
	        scale: 'measure'
	      },
	      whiskers: false,
	      orientation: 'vertical'
	    },
	    brush: {
	      trigger: brushTrigger,
	      consume: brushConsume
	    },
	    data: {
	      extract: {
	        field: 'qDimensionInfo/0',
	        props: {
	          start: 0,
	          end: {
	            field: 'qMeasureInfo/0'
	          },
	          measure: {
	            field: 'qMeasureInfo/0',
	            reduce: 'first',
	            value(v) {
	              return v;
	            },
	            reduceLabel: 'none'
	          },
	          binStart: {
	            field: 'qDimensionInfo/0',
	            value(v) {
	              return v.qNum;
	            }
	          },
	          binEnd: {
	            field: 'qDimensionInfo/0',
	            value(v) {
	              return v.qNum + binSize;
	            }
	          },
	          elemNo: {
	            field: 'qDimensionInfo/0'
	          },
	          bin: {
	            field: 'qDimensionInfo/0',
	            value(v) {
	              return v;
	            }
	          }
	        }
	      }
	    }
	  };
	}
	const BoxMarker = {
	  createSettings: createBoxMarkerSettings
	};

	//
	// Implementation details
	//

	function createLabelSettings(layout, themeService, chartId) {
	  const styles = themeService.getStyles();
	  const valueLabelSettings = getValueLabelStyle(chartId, styles, layout);
	  const boxFillColor = valueLabelSettings.fill || styles.label.value.color;
	  const getContrastColor = () => ctx => Color.isDark(ctx.node.attrs.fill) ? styles.label.value.lightColor : styles.label.value.darkColor;
	  return {
	    settings: {
	      sources: [{
	        strategy: {
	          settings: {
	            ...valueLabelSettings,
	            labels: [{
	              placements: [{
	                fill: boxFillColor
	              }, {
	                fill: valueLabelSettings.fill ? boxFillColor : getContrastColor()
	              }]
	            }]
	          }
	        }
	      }]
	    }
	  };
	}
	const Label = {
	  createSettings: createLabelSettings
	};

	// import propertyResolver from '../../../../assets/client/utils/property-resolver';

	const chartID$1 = 'object.histogram';

	//
	// Implementation details
	//

	/**
	 * Checks whether the dimension is locked or not
	 * @param layout - layout for histogram
	 * @returns {boolean} - true is the dimension is locked, otherwise false
	 */
	function getLockedDim(layout) {
	  const dimInfos = layout.qUndoExclude && layout.qUndoExclude.box && layout.qUndoExclude.box.qHyperCube && layout.qUndoExclude.box.qHyperCube.qDimensionInfo ? layout.qUndoExclude.box.qHyperCube.qDimensionInfo : undefined;
	  if (!dimInfos) {
	    return false;
	  }
	  return !!dimInfos[0].qLocked;
	}

	/**
	 * Disables/Enables measure- dimension range selection depending if the field is locked or not.
	 * In this case, as soon as the current class function is locked, then both measure and dimension
	 * range selection is locked down
	 * @param lockedDim - boolean determining if the dimension is locked down
	 * @returns {object} that gives the status of measure and dimension range selection
	 */
	function retrieveRangeSelStatus(lockedDim) {
	  const rangeSelStatus = {};
	  if (lockedDim) {
	    rangeSelStatus.isOpenDim = false;
	    rangeSelStatus.isOpenMea = false;
	  } else {
	    rangeSelStatus.isOpenDim = true;
	    rangeSelStatus.isOpenMea = true;
	  }
	  return rangeSelStatus;
	}
	function isSingleSelect(layout) {
	  return vr(layout, 'qHyperCube.qDimensionInfo.0.qIsOneAndOnlyOne', false);
	}
	function createChartSettings(chartView, layout) {
	  const isRtl = chartView.isRtl();
	  const orgDimInfo = vr(layout, 'qHyperCube.qDimensionInfo.0', {});
	  const dimTitle = orgDimInfo.qFallbackTitle || '';
	  const {
	    theme,
	    translator
	  } = chartView.environment;
	  // Create components
	  const chartBuilder = ChartBuilder.create({
	    chartID: chartID$1,
	    theme,
	    isRtl,
	    flags: chartView.flags
	  });
	  const themeService = qa({
	    theme,
	    config: {
	      id: 'histogram'
	    }
	  });
	  let basicSelectionSettings = {};
	  let dimensionSelectionSettings = {};
	  let measureSelectionSettings = {};
	  if (chartView._selectionHandler.isOn()) {
	    chartView._selectionHandler.setUpStart();
	    basicSelectionSettings = chartView._selectionHandler.setUpBrush({
	      contexts: ['select'],
	      data: ['elemNo'],
	      dataPath: 'qUndoExclude/box'
	    });
	    dimensionSelectionSettings = chartView._selectionHandler.setUpBrush({
	      contexts: ['select-dimension'],
	      data: ['elemNo'],
	      dataPath: 'qUndoExclude/box',
	      isSingleSelect: isSingleSelect(layout)
	    });
	    measureSelectionSettings = chartView._selectionHandler.setUpBrush({
	      dataPath: 'qUndoExclude/box',
	      contexts: ['select-measure'],
	      data: ['end']
	    });
	    chartView._selectionHandler.setUpDone();
	  }
	  const tooltipSettings = {
	    box: {}
	  };
	  if (chartView._tooltipHandler.isOn()) {
	    tooltipSettings.box = chartView._tooltipHandler.setUp({
	      chartBuilder,
	      environment: chartView.environment,
	      data: [''],
	      contexts: ['boxTip'],
	      componentKey: 'box-marker',
	      measureRows: ['measure'],
	      // Should be a mapped path under extract, mandatory to display tooltip
	      labelData: ['bin'] // Should be a mapped path under extract, mandatory to display tooltip
	    });
	  }
	  const lockedDims = getLockedDim(layout);
	  const rangeSelStatus = retrieveRangeSelStatus(lockedDims);
	  const handlers = {
	    scrollHandler: null,
	    selectionHandler: chartView._selectionHandler
	  };
	  const keys = {
	    componentKey: 'box-marker',
	    lassoBrushKey: 'select',
	    dimRangeBrushKey: null,
	    measureRangeBrushKey: 'select-measure',
	    areaBrushKey: 'select-dimension'
	  };
	  if (this._dependentActions) {
	    this._dependentActions.destroy();
	  }
	  this._dependentActions = DependentInteractions$1.create(handlers, 'vertical', isRtl, keys, rangeSelStatus);
	  chartBuilder.addPreset('dimension-measure-chart', {
	    // common
	    isRtl,
	    includeDimensionAxis: true,
	    orientation: 'vertical',
	    selectionsEnabled: chartView._selectionHandler.isOn(),
	    theme,
	    // measure scale
	    measureSource: 'qMeasureInfo/0',
	    measureScaleSettings: {
	      component: {
	        expand: 0,
	        include: [0] // Make sure that the measure axis starts from 0.
	      }
	    },
	    // Lasso
	    enableLasso: true,
	    lasso: {
	      brushKey: 'select',
	      brushComponents: ['box-marker']
	    },
	    // Mea range selection
	    enableMeasureRange: true,
	    measureRange: {
	      brushKey: 'select-measure',
	      brushAxis: 'y-axis',
	      brushArea: 'box-marker',
	      brushScale: 'measure'
	    },
	    // Area range selection
	    enableAreaRange: true,
	    areaRange: {
	      brushKey: 'select-dimension',
	      brushAxis: 'x-axis',
	      brushData: ['elemNo'],
	      brushArea: 'box-marker',
	      brushScale: 'rangeSelSettings',
	      brushComponents: ['box-marker'],
	      multiple: true,
	      chartInstance: chartView.chartInstance
	    },
	    brushActions: this._dependentActions.gestures,
	    dimensionSource: 'qDimensionInfo/0',
	    dimensionScaleSettings: DimensionScale.createSettings(layout),
	    // measure axis and title
	    measureAxisProperties: layout.measureAxis,
	    // used by both
	    measureTitleText: layout.measureAxis.label || translator.get('Visualization.Histogram.MeasureAxisLabel'),
	    // dimension axis and title
	    dimensionAxisProperties: layout.dimensionAxis,
	    // used by both
	    dimensionAxisSettings: DimensionAxis.createSettings(layout),
	    dimensionTitleText: dimTitle,
	    // grid lines
	    gridlines: layout.gridlines,
	    // scroll
	    hasNavigation: false,
	    isNavigationEnabledFn: () => false,
	    // ref-lines
	    refLines: layout.refLine && layout.refLine.refLines,
	    axisTitleStyle: getAxisTitleStyle(chartID$1, theme, layout),
	    axisLabelStyle: getAxisLabelStyle(chartID$1, theme, layout)
	  });
	  const settings = chartBuilder.getSettings();

	  // Box marker
	  const boxMarkerSettings = BoxMarker.createSettings(chartView, layout, basicSelectionSettings, dimensionSelectionSettings, measureSelectionSettings, tooltipSettings);
	  chartBuilder.addComponent('box-marker', boxMarkerSettings);
	  if (layout.dataPoint && layout.dataPoint.showLabels) {
	    const binLabelSettings = Label.createSettings(layout, themeService, chartID$1);
	    chartBuilder.addComponent('labels', binLabelSettings);
	  }

	  // Add snapshot settings
	  chartView.addSnapshotChartSettings(settings, layout);

	  // max: layout.qHyperCube.qDimensionInfo[0].qMax + binSize,
	  settings.scales.rangeSelSettings = {
	    type: 'linear',
	    min: settings.scales.dimension.min,
	    max: settings.scales.dimension.max,
	    source: 'qDimensionInfo/0'
	  };
	  return settings;
	}
	const ChartSettings = {
	  createChartSettings
	};

	/* eslint-disable no-shadow */
	const namespace = '.histogram';
	const chartID = 'object.histogram';

	//
	// Implementation details
	//

	function init({
	  environment,
	  flags,
	  lasso,
	  picasso,
	  $element,
	  backendApi,
	  selectionsApi,
	  renderState
	}) {
	  this._super(picasso, $element, environment, backendApi, selectionsApi);
	  this.flags = flags;
	  this.renderState = renderState;
	  this.picassoElement.__do_not_use_findShapes = this.chartInstance.findShapes.bind(this.chartInstance); // to allow access to renderered content via DOM

	  this._derivedProperties = new DerivedProperties();
	  this._selectionHandler = SelectionHandler.create({
	    model: backendApi.model,
	    chartInstance: this.chartInstance,
	    selectionsApi,
	    selectPaths: ['/qUndoExclude/box/qHyperCubeDef'],
	    lasso
	  });
	  this._tooltipHandler = TooltipHandler.create(this.chartInstance, $element, chartID);
	  this.setDataPaths(['qUndoExclude/box/qHyperCube']);
	}
	function updateConstraints(constraints) {
	  const tooltip = !constraints.passive;
	  const selection = !constraints.select && !constraints.active;
	  this._tooltipHandler[tooltip ? 'on' : 'off']();
	  this._selectionHandler[selection ? 'on' : 'off']();
	}
	function off() {
	  this._tooltipHandler.off();
	  this._selectionHandler.off();
	}
	function setSnapshotData(snapshotLayout) {
	  this._super(snapshotLayout);
	  snapshotLayout.qUndoExclude.box.qHyperCube.qDataPages = this.layout.qUndoExclude.box.qHyperCube.qDataPages; // eslint-disable-line no-param-reassign

	  return Promise.resolve(snapshotLayout);
	}
	function getRequireNumericDimensionAttribute(qHyperCube) {
	  return qHyperCube.qDimensionInfo.length > 0 && qHyperCube.qDimensionInfo[0].qTags.indexOf('$numeric') === -1;
	}
	function getDisclaimerAttributes(layout) {
	  function isOnlyNanData() {
	    const rows = vr(layout, 'qUndoExclude.box.qHyperCube.qDataPages.0.qMatrix', []);

	    // There is only one row and the dimension value on that row is null, then we only have NaN data
	    return rows.length === 1 && rows[0][0] && rows[0][0].qIsNull;
	  }
	  const onlyNanData = isOnlyNanData();
	  return {
	    data: layout.qUndoExclude && layout.qUndoExclude.box,
	    supportedDisclaimers: {
	      LimitedData: true,
	      OnlyNanData: true,
	      OnlyNegativeOrZeroValues: !onlyNanData,
	      RequireNumericDimension: true
	    },
	    options: {
	      bottom: true,
	      supportNegative: false,
	      explicitOnlyNanData: onlyNanData,
	      explicitRequireNumericDimension: getRequireNumericDimensionAttribute(layout.qHyperCube)
	    }
	  };
	}
	function updateChart(layout, settings) {
	  if (!layout.qUndoExclude) {
	    // Console error when undefined data is sent to picasso
	    return Promise.resolve();
	  }
	  this._super(layout, settings);
	  return undefined;
	}
	function getHashData(layout, properties) {
	  return {
	    box: properties.qHyperCubeDef,
	    binMappings: histogramMappings.getMappingValues(layout),
	    binProperties: properties.bins,
	    measureAxis: properties.measureAxis,
	    version: '2.0' // Added to trigger update because of logic changes in generateHyperCubes
	  };
	}
	function updateData(layout) {
	  const self = this;
	  return self._super(layout).then(() => {
	    if (self._destroyed) {
	      return Promise.reject();
	    }
	    layout = self.layout; // eslint-disable-line no-param-reassign

	    const rect = {
	      height: Math.min(layout.qHyperCube.qSize.qcy, 1000),
	      width: 2
	    };
	    const model = self.backendApi.model;
	    const isSnapshot = !!this.layout.snapshotData;
	    if (isSnapshot) {
	      return Promise.resolve();
	    }
	    return model.getEffectiveProperties().then(properties => {
	      if (self._destroyed) {
	        return Promise.reject();
	      }
	      return self._derivedProperties.addDefaultHyperCubeHash(properties.qHyperCubeDef, layout.qHyperCube, self.environment.app, getHashData(layout, properties)).then(hashData => {
	        if (self._destroyed) {
	          return Promise.reject();
	        }
	        const settings = {
	          layout,
	          properties,
	          model,
	          hashData,
	          generateDerivedProperties(layout, properties) {
	            return cubesGenerator.generateHyperCubes(layout, properties, self.environment);
	          }
	        };
	        if (!self._derivedProperties.isDerivedUpToDate(settings)) {
	          self.renderState.pending();
	          return self._derivedProperties.updateDerivedProperties(settings);
	        }
	        if (!layout.qUndoExclude) {
	          // Have seen a couple of console errors because qUndoExclude did not exist when calling backendApi.updateCache bellow
	          return Promise.resolve();
	        }
	        self.renderState.restore();
	        self.backendApi.updateCache(layout.qUndoExclude.box);
	        return self.getData(self.backendApi, layout.qUndoExclude.box.qHyperCube, rect);
	      });
	    });
	  });
	}
	function paint() {
	  const undoExclude = this.layout.qUndoExclude;
	  if (!undoExclude) {
	    return Promise.resolve(false);
	  }
	  const haveBoxData = undoExclude.box && undoExclude.box.qHyperCube.qDataPages.length;
	  if (haveBoxData) {
	    return this._super();
	  }
	  return Promise.resolve(false);
	}
	function isLassoDisabled() {
	  return false;
	}
	const HistogramView = ChartView.extend('Histogram', {
	  namespace,
	  init,
	  updateConstraints,
	  off,
	  createChartSettings: function createChartSettings(layout) {
	    return ChartSettings.createChartSettings(this, layout);
	  },
	  setSnapshotData,
	  getDisclaimerAttributes,
	  updateChart,
	  updateData,
	  paint,
	  isLassoDisabled
	});

	class BackednAPi {
	  constructor(model) {
	    this.model = model;
	    this.path = '/qUndoExclude/box/qHyperCubeDef';
	  }

	  // eslint-disable-next-line class-methods-use-this, no-unused-vars
	  setCacheOptions({
	    maxStackedValues
	  }) {}

	  // eslint-disable-next-line class-methods-use-this, no-unused-vars
	  updateCache(args) {}
	  getData(pages) {
	    return this.model.getHyperCubeData(this.path, pages);
	  }
	}

	function onChangeCalcCond(data) {
	  const baseCube = data?.qHyperCubeDef;
	  const generatedCube = data?.qUndoExclude?.box?.qHyperCubeDef;
	  if (baseCube && generatedCube) {
	    generatedCube.qCalcCond = baseCube.qCalcCond;
	    generatedCube.qCalcCondition = baseCube.qCalcCondition;
	  }
	}
	var propsLogic = {
	  onChangeCalcCond
	};

	const getStylingPanelDefinition = (bkgOptionsEnabled, styleOptions) => ({
	  component: 'styling-panel',
	  chartTitle: 'Object.Histogram',
	  translation: 'LayerStyleEditor.component.styling',
	  subtitle: 'LayerStyleEditor.component.styling',
	  ref: 'components',
	  useGeneral: true,
	  useBackground: bkgOptionsEnabled,
	  items: {
	    axisTitleSection: {
	      translation: 'properties.axis.title',
	      component: 'panel-section',
	      items: styleOptions.getOptions('axis', 'axis.title')
	    },
	    axisLabelSection: {
	      translation: 'properties.axis.label',
	      component: 'panel-section',
	      items: styleOptions.getOptions('axis', 'axis.label.name')
	    },
	    valueLabelSection: {
	      translation: 'properties.value.label',
	      component: 'panel-section',
	      items: styleOptions.getOptions('value', 'label.value')
	    }
	  }
	});

	/* eslint-disable no-param-reassign */
	/* eslint-disable no-shadow */
	const maxCountMode = 'maxCount';
	const sizeMode = 'size';
	function inAdvancedMode(data) {
	  return !(data.bins && data.bins.auto);
	}
	function showBinCount(data) {
	  return inAdvancedMode(data) && data.bins.binMode === maxCountMode;
	}
	function propertyDefinition(env) {
	  const {
	    translator,
	    flags
	  } = env;
	  const stylingPanelEnabled = env?.flags?.isEnabled('SENSECLIENT_IM_2021_STYLINGPANEL_HISTOGRAM');
	  const bkgOptionsEnabled = env?.flags?.isEnabled('SENSECLIENT_IM_2021_HISTOGRAM_BG');
	  const measureAxis = {
	    uses: 'axis.picasso.measureAxis',
	    items: {
	      label: {
	        type: 'string',
	        expression: 'optional',
	        expressionType: 'StringExpression',
	        ref: 'measureAxis.label',
	        defaultValue: '',
	        translation: 'Common.Label',
	        placeholderTranslation: 'Visualization.Histogram.MeasureAxisLabel'
	      }
	    }
	  };
	  const dimensionAxis = {
	    uses: 'axis.picasso.dimensionAxis',
	    items: {
	      othersGroup: {
	        items: {
	          label: {
	            show: false // SUI-2470
	          }
	        }
	      }
	    }
	  };
	  const theme = env.theme;
	  const defaultColor = () => {
	    const {
	      primary
	    } = theme.getDataColorSpecials();
	    const palette = theme.getDataColorPickerPalettes()[0].colors;
	    const index = palette.indexOf(primary);
	    return {
	      index: index === -1 ? Math.min(6, palette.length - 1) : index
	    };
	  };
	  const colors = {
	    translation: 'properties.colors',
	    type: 'items',
	    items: {
	      colors: {
	        classification: {
	          section: 'color',
	          tags: ['simple']
	        },
	        type: 'items',
	        items: {
	          barColor: {
	            ref: 'color.bar.paletteColor',
	            translation: 'properties.histogram.barColor',
	            type: 'object',
	            component: 'color-picker',
	            dualOutput: true,
	            defaultValue: defaultColor
	          }
	        }
	      }
	    }
	  };
	  const chartID = 'object.histogram';
	  const fontResolver = getChartFontResolver(theme, translator, chartID, Xe$1, flags);
	  const styleOptions = ChartStyleComponent(fontResolver, theme, chartID);
	  const presentation = {
	    type: 'items',
	    translation: 'properties.presentation',
	    items: {
	      stylingPanel: stylingPanelEnabled && getStylingPanelDefinition(bkgOptionsEnabled, styleOptions),
	      gridLines: {
	        type: 'items',
	        snapshot: {
	          tid: 'property-gridLines'
	        },
	        items: {
	          showGridLines: {
	            ref: 'gridlines.auto',
	            type: 'boolean',
	            translation: 'properties.gridLine.spacing',
	            component: 'switch',
	            defaultValue: true,
	            options: [{
	              value: true,
	              translation: 'Common.Auto'
	            }, {
	              value: false,
	              translation: 'Common.Custom'
	            }]
	          },
	          gridSpacing: {
	            ref: 'gridlines.spacing',
	            type: 'number',
	            component: 'dropdown',
	            defaultValue: 2,
	            options: [{
	              value: 0,
	              translation: 'properties.gridLine.noLines'
	            }, {
	              value: 2,
	              translation: 'properties.gridLine.medium'
	            }, {
	              value: 3,
	              translation: 'properties.gridLine.narrow'
	            }],
	            show(data) {
	              return data.gridlines && !data.gridlines.auto;
	            }
	          }
	        }
	      },
	      showLabels: {
	        ref: 'dataPoint.showLabels',
	        type: 'boolean',
	        translation: 'properties.dataPoints.labelmode',
	        component: 'switch',
	        defaultValue: false,
	        options: [{
	          value: true,
	          translation: 'Common.Auto'
	        }, {
	          value: false,
	          translation: 'properties.off'
	        }],
	        snapshot: {
	          tid: 'property-dataPoints'
	        }
	      }
	    }
	  };
	  const simpleLabels = {
	    items: {
	      labels: {
	        items: {
	          header: {
	            show(props) {
	              return props.qHyperCubeDef.qDimensions?.length;
	            }
	          },
	          pointLabels: {
	            component: 'checkbox',
	            ref: 'dataPoint.showLabels',
	            type: 'boolean',
	            translation: 'Simple.Label.Value',
	            show(props) {
	              return props.qHyperCubeDef.qDimensions?.length;
	            }
	          },
	          dimensionTitle: {
	            component: 'checkbox',
	            ref: 'dimensionAxis.show',
	            type: 'string',
	            translation: 'Simple.Label.XAxis.Hide',
	            defaultValue: 'all',
	            show(props) {
	              return props.qHyperCubeDef.qDimensions?.length;
	            },
	            convertFunctions: {
	              get(getter, def, args, data) {
	                return data.dimensionAxis.show === 'labels' || data.dimensionAxis.show === 'none';
	              },
	              set(value, setter, def, args, data) {
	                data.dimensionAxis.show = value ? 'labels' : 'all';
	              }
	            }
	          },
	          measureTitle: {
	            component: 'checkbox',
	            ref: 'measureAxis.show',
	            type: 'string',
	            translation: 'Simple.Label.YAxis.Hide',
	            defaultValue: 'all',
	            show(props) {
	              return props.qHyperCubeDef.qDimensions?.length;
	            },
	            convertFunctions: {
	              get(getter, def, args, data) {
	                return data.measureAxis.show === 'labels' || data.measureAxis.show === 'none';
	              },
	              set(value, setter, def, args, data) {
	                data.measureAxis.show = value ? 'labels' : 'all';
	              }
	            }
	          }
	        }
	      }
	    }
	  };
	  const settings = {
	    uses: 'settings',
	    items: {
	      simpleLabels,
	      presentation,
	      colors,
	      measureAxis,
	      dimensionAxis
	    }
	  };
	  const addons = {
	    type: 'items',
	    component: 'expandable-items',
	    translation: 'properties.addons',
	    items: {
	      dataHandling: {
	        uses: 'dataHandling',
	        items: {
	          calcCond: {
	            uses: 'calcCond',
	            change: propsLogic.onChangeCalcCond
	          }
	        }
	      },
	      refLines: {
	        uses: 'reflines',
	        items: {
	          colorBackground: {
	            show: false
	          }
	        }
	      }
	    }
	  };
	  const dimensions = {
	    translation: 'Common.Fields',
	    alternativeTranslation: 'properties.alternative.fields',
	    items: {
	      dimensionLimits: {
	        show: false,
	        items: {
	          otherMode: {
	            readOnly: false
	          },
	          otherSortMode: {
	            show(itemData /* , handler */) {
	              return vr(itemData, 'qOtherTotalSpec.qOtherMode') === 'OTHER_COUNTED';
	            }
	          },
	          otherCounted: {
	            show(itemData /* , handler */) {
	              return vr(itemData, 'qOtherTotalSpec.qOtherMode') === 'OTHER_COUNTED';
	            }
	          },
	          otherLimitMode: {
	            show(itemData /* , handler */) {
	              const limitMode = vr(itemData, 'qOtherTotalSpec.qOtherMode');
	              return limitMode === 'OTHER_ABS_LIMITED' || limitMode === 'OTHER_REL_LIMITED';
	            }
	          },
	          otherLimit: {
	            show(itemData /* , handler */) {
	              const limitMode = vr(itemData, 'qOtherTotalSpec.qOtherMode');
	              return limitMode === 'OTHER_ABS_LIMITED' || limitMode === 'OTHER_REL_LIMITED';
	            }
	          },
	          calculatedAgainstMessage: {
	            show: true,
	            label() {
	              const measureName = translator.get('properties.histogram.staticMeasureName');
	              return translator.get('Properties.DimensionLimits.CalculatedAgainst', measureName);
	            }
	          }
	        }
	      },
	      others: {
	        show: false,
	        items: {
	          suppressOther: {
	            defaultValue: true
	          }
	        }
	      }
	    }
	  };
	  const data = {
	    uses: 'data',
	    items: {
	      dimensions
	    }
	  };
	  const customBinMode = {
	    ref: 'bins.binMode',
	    type: 'string',
	    component: 'dropdown',
	    options: [{
	      value: maxCountMode,
	      translation: 'Visualization.Histogram.Binning.NumberOfBinsOption'
	    }, {
	      value: sizeMode,
	      translation: 'Visualization.Histogram.Binning.BarWidthOption'
	    }],
	    defaultValue: maxCountMode,
	    show(data) {
	      return inAdvancedMode(data);
	    }
	  };
	  const bins = {
	    translation: 'Visualization.Histogram.Bins',
	    type: 'items',
	    component: 'items',
	    items: {
	      auto: {
	        ref: 'bins.auto',
	        translation: 'Visualization.Histogram.Binning',
	        component: 'switch',
	        type: 'boolean',
	        defaultValue: true,
	        undefinedValue: false,
	        options: [{
	          value: true,
	          translation: 'Visualization.Histogram.Binning.Auto'
	        }, {
	          value: false,
	          translation: 'Visualization.Histogram.Binning.Custom'
	        }]
	      },
	      autoMessage: {
	        component: 'text',
	        translation: 'Visualization.Histogram.Binning.AutoDescription',
	        show(data /* , handler, args */) {
	          return !inAdvancedMode(data);
	        }
	      },
	      mode: customBinMode,
	      binCount: {
	        ref: 'bins.binCount',
	        type: 'number',
	        expression: 'optional',
	        expressionType: 'ValueExpression',
	        translation: 'Visualization.Histogram.Binning.BinCount',
	        defaultValue: '',
	        convertFunctions: {
	          get(getter, definition, args) {
	            const binCount = args.properties.bins.binCount;
	            if (histogramUtils.isEmpty(binCount)) {
	              return histogramUtils.getDerivedBinCount(args.layout);
	            }
	            return getter(null) || '';
	          },
	          set(value, setter, definition) {
	            setter(definition.type, value, undefined);
	          }
	        },
	        show: showBinCount
	      },
	      binMessage: {
	        component: 'text',
	        translation: 'Visualization.Histogram.Binning.BinCountRounding',
	        show(data /* , handler, args */) {
	          const binCount = vr(data, 'bins.binCount');
	          const isExpression = typeof binCount === 'object';
	          return showBinCount(data) && !histogramUtils.isEmpty(binCount) && !isExpression && !isInteger(binCount) && binCount > 0;
	        }
	      },
	      minBinMessage: {
	        component: 'text',
	        translation: 'Visualization.Histogram.Binning.BinCountMin',
	        show(data) {
	          const binCount = vr(data, 'bins.binCount');
	          return !!(showBinCount(data) && !histogramUtils.isEmpty(binCount) && binCount <= 0);
	        }
	      },
	      binSize: {
	        ref: 'bins.binSize',
	        type: 'number',
	        expression: 'optional',
	        expressionType: 'ValueExpression',
	        defaultValue: 10,
	        show(data) {
	          return inAdvancedMode(data) && data.bins.binMode === sizeMode;
	        },
	        translation: 'Visualization.Histogram.Binning.BinSize'
	      },
	      offset: {
	        ref: 'bins.offset',
	        type: 'number',
	        expression: 'optional',
	        expressionType: 'ValueExpression',
	        show(data) {
	          return inAdvancedMode(data) && data.bins.binMode === sizeMode;
	        },
	        translation: 'Visualization.Histogram.Binning.Offset'
	      },
	      distinct: {
	        ref: 'bins.countDistinct',
	        type: 'boolean',
	        defaultValue: false,
	        component: 'checkbox',
	        translation: 'Visualization.Histogram.CountDistinct'
	      }
	    }
	  };
	  return {
	    type: 'items',
	    component: 'accordion',
	    items: {
	      data,
	      bins,
	      addons,
	      settings
	    }
	  };
	}

	var exploreProperties = {
	  type: 'items',
	  component: 'accordion',
	  items: {
	    data: {
	      uses: 'data',
	      items: {
	        dimensions: {
	          translation: 'Common.Fields'
	        }
	      }
	    }
	  }
	};

	/**
	 * Implementation details
	 */

	function getExportRawDataOptions(object) {
	  return {
	    model: object.model,
	    exportDataPath: '/qUndoExclude/box/qHyperCubeDef'
	  };
	}
	var histogramExport = {
	  getExportRawDataOptions
	};

	const VIEW_DATA_HYPERCUBE_PATH = 'qUndoExclude.box';
	function ext(env) {
	  return {
	    definition: propertyDefinition(env),
	    softDefinition: exploreProperties,
	    support: {
	      cssScaling: false,
	      snapshot: true,
	      export: true,
	      exportData: true,
	      sharing: true,
	      viewData: true
	    },
	    importProperties: (exportFormat, initialProperties, extension, hypercubePath) => {
	      const dataDefinition = data(env);
	      extension.mapProperties();
	      const defaultPropertyValues = {
	        defaultDimension: extension.getDefaultDimensionProperties(),
	        defaultMeasure: extension.getDefaultMeasureProperties()
	      };
	      return conversion.hypercube.importProperties({
	        exportFormat,
	        initialProperties,
	        dataDefinition,
	        defaultPropertyValues,
	        hypercubePath
	      });
	    },
	    exportProperties(propertyTree, hyperCubePath, viewDataMode) {
	      return conversion.hypercube.exportProperties({
	        propertyTree,
	        hyperCubePath: viewDataMode ? VIEW_DATA_HYPERCUBE_PATH : hyperCubePath,
	        viewDataMode
	      });
	    },
	    requireNumericDimension: true,
	    exportTableProperties(propertyTree) {
	      // the hypercube that will be used for "building" the table is under `qUndoExclude.box.qHyperCubeDef`
	      const hypercubePath = VIEW_DATA_HYPERCUBE_PATH;
	      return conversion.hypercube.exportProperties({
	        propertyTree,
	        hypercubePath,
	        viewData: true
	      });
	    },
	    getExportRawDataOptions: histogramExport.getExportRawDataOptions
	  };
	}

	/* eslint-disable react-hooks/rules-of-hooks */
	function supernova(env) {
	  autoRegister(env.translator);
	  const dataDefinition = data(env);
	  return {
	    qae: {
	      properties,
	      data: {
	        targets: [dataDefinition]
	      },
	      exportProperties: ({
	        propertyTree,
	        hypercubePath,
	        viewDataMode
	      }) => conversion.hypercube.exportProperties({
	        propertyTree,
	        hypercubePath: viewDataMode ? 'qUndoExclude.box' : hypercubePath
	      })
	    },
	    ext: ext(env),
	    component() {
	      const constraints = stardust.useConstraints();
	      const element = stardust.useElement();
	      const environment = useEnvironment();
	      const renderer = environment.options.renderer;
	      const picasso = stardust.useMemo(() => setup(renderer), [renderer]);
	      const lasso = useSelect();
	      const model = stardust.useModel();
	      const selections = stardust.useSelections();
	      const layout = stardust.useStaleLayout();
	      const renderState = stardust.useRenderState();
	      const [instance, setInstance] = stardust.useState();
	      stardust.useEffect(() => {
	        const $element = $$2(element);
	        const backendApi = new BackednAPi(model);
	        const selectionsApi = selections;
	        const view = new HistogramView({
	          $element,
	          backendApi,
	          environment,
	          flags: env.flags,
	          lasso,
	          picasso,
	          selectionsApi,
	          renderState
	        });
	        setInstance(view);
	        return () => {
	          view.destroy();
	        };
	        // eslint-disable-next-line react-hooks/exhaustive-deps
	      }, []);
	      const [, error] = stardust.usePromise(async () => {
	        if (!instance) {
	          return;
	        }
	        instance.updateEnvironment(environment);
	        instance.updateConstraints(constraints);

	        // TODO: confim selection if triggered from engine (another websocket to the same session (browser tab))

	        await instance.updateData(layout);
	        await instance.paint();
	      }, [layout, instance, environment]);
	      if (error) {
	        throw error;
	      }
	      useResize(instance);
	      setupSnapshot(instance);
	    }
	  };
	}

	return supernova;

}));
//# sourceMappingURL=sn-histogram.js.map
