(function(global2, factory) {
  typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, global2.ApexCharts = factory());
})(this, (function() {
  "use strict";var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
/*!
 * ApexCharts v5.10.6
 * (c) 2018-2026 ApexCharts
 */

  class Environment {
    /**
     * Check if running in server-side rendering environment (Node.js)
     * @returns {boolean} True if in SSR/Node.js, false if in browser
     */
    static isSSR() {
      return typeof window === "undefined" || typeof document === "undefined";
    }
    /**
     * Check if running in browser environment
     * @returns {boolean} True if in browser, false if in SSR/Node.js
     */
    static isBrowser() {
      return !this.isSSR();
    }
    /**
     * Check if a specific browser API is available
     * @param {string} api - Name of the API to check (e.g., 'ResizeObserver')
     * @returns {boolean} True if API is available
     */
    static hasAPI(api) {
      if (this.isSSR()) return false;
      return typeof /** @type {any} */
      window[api] !== "undefined";
    }
    /**
     * Returns the global Apex config object regardless of environment.
     * In browser: window.Apex; in SSR/Node.js: global.Apex; fallback: {}.
     * @returns {any}
     */
    static getApex() {
      if (typeof window !== "undefined" && window.Apex) return window.Apex;
      if (typeof global !== "undefined" && global.Apex) return global.Apex;
      return {};
    }
  }
  class SSRElement {
    /**
     * @param {string} nodeName
     * @param {any} namespaceURI
     */
    constructor(nodeName, namespaceURI = null) {
      this.nodeName = nodeName;
      this.namespaceURI = namespaceURI;
      this.attributes = /* @__PURE__ */ new Map();
      this.children = [];
      this.textContent = "";
      this.style = {};
      this.classList = new SSRClassList();
      this.parentNode = /** @type {SSRElement | null} */
      null;
      this._ssrWidth = void 0;
      this._ssrHeight = void 0;
      this._ssrMode = void 0;
    }
    /**
     * @param {string} name
     * @param {any} value
     */
    setAttribute(name2, value) {
      this.attributes.set(name2, value);
    }
    /**
     * @param {string} name
     */
    getAttribute(name2) {
      return this.attributes.get(name2);
    }
    /**
     * @param {string} name
     */
    removeAttribute(name2) {
      this.attributes.delete(name2);
    }
    /**
     * @param {string} name
     */
    hasAttribute(name2) {
      return this.attributes.has(name2);
    }
    /**
     * @param {any} child
     */
    appendChild(child) {
      if (child && child !== this) {
        if (child.parentNode && child.parentNode !== this) {
          child.parentNode.removeChild(child);
        } else if (child.parentNode === this) {
          const index = this.children.indexOf(child);
          if (index !== -1) this.children.splice(index, 1);
        }
        child.parentNode = this;
        this.children.push(child);
      }
      return child;
    }
    /**
     * @param {any} child
     */
    removeChild(child) {
      const index = this.children.indexOf(child);
      if (index !== -1) {
        this.children.splice(index, 1);
        child.parentNode = null;
      }
      return child;
    }
    /**
     * @param {any} newNode
     * @param {any} referenceNode
     */
    insertBefore(newNode, referenceNode) {
      if (!referenceNode) {
        return this.appendChild(newNode);
      }
      if (newNode.parentNode && newNode.parentNode !== this) {
        newNode.parentNode.removeChild(newNode);
      } else if (newNode.parentNode === this) {
        const existingIndex = this.children.indexOf(newNode);
        if (existingIndex !== -1) this.children.splice(existingIndex, 1);
      }
      const index = this.children.indexOf(referenceNode);
      if (index !== -1) {
        newNode.parentNode = this;
        this.children.splice(index, 0, newNode);
      }
      return newNode;
    }
    cloneNode(deep = false) {
      const clone = new SSRElement(this.nodeName, this.namespaceURI);
      clone.textContent = this.textContent;
      this.attributes.forEach((value, key) => {
        clone.attributes.set(key, value);
      });
      Object.assign(clone.style, this.style);
      if (deep) {
        this.children.forEach((child) => {
          if (child.cloneNode) {
            clone.appendChild(child.cloneNode(true));
          }
        });
      }
      return clone;
    }
    getBoundingClientRect() {
      return {
        width: this._ssrWidth || 0,
        height: this._ssrHeight || 0,
        top: 0,
        left: 0,
        right: this._ssrWidth || 0,
        bottom: this._ssrHeight || 0,
        x: 0,
        y: 0
      };
    }
    getRootNode() {
      let root = this;
      while (root.parentNode) {
        root = root.parentNode;
      }
      return root;
    }
    querySelector() {
      return null;
    }
    querySelectorAll() {
      return [];
    }
    getElementsByClassName() {
      return [];
    }
    addEventListener() {
    }
    removeEventListener() {
    }
    get childNodes() {
      return this.children;
    }
    toString() {
      let attrs = "";
      this.attributes.forEach((value, key) => {
        attrs += ` ${key}="${value}"`;
      });
      if (this.children.length === 0 && !this.textContent) {
        return `<${this.nodeName}${attrs}/>`;
      }
      const childrenStr = this.children.map((c) => c.toString()).join("");
      return `<${this.nodeName}${attrs}>${this.textContent}${childrenStr}</${this.nodeName}>`;
    }
    // Property getters/setters
    get innerHTML() {
      return this.children.map((c) => c.toString()).join("");
    }
    set innerHTML(value) {
      this.children = [];
      this.textContent = value;
    }
    get outerHTML() {
      return this.toString();
    }
    get isConnected() {
      return true;
    }
  }
  class SSRClassList {
    constructor() {
      this.classes = /* @__PURE__ */ new Set();
    }
    add(...classNames) {
      classNames.forEach((name2) => this.classes.add(name2));
    }
    remove(...classNames) {
      classNames.forEach((name2) => this.classes.delete(name2));
    }
    /**
     * @param {string} className
     */
    contains(className) {
      return this.classes.has(className);
    }
    /**
     * @param {string} className
     * @param {any} force
     */
    toggle(className, force) {
      if (force === true) {
        this.classes.add(className);
        return true;
      } else if (force === false) {
        this.classes.delete(className);
        return false;
      } else {
        if (this.classes.has(className)) {
          this.classes.delete(className);
          return false;
        } else {
          this.classes.add(className);
          return true;
        }
      }
    }
    toString() {
      return Array.from(this.classes).join(" ");
    }
  }
  class SSRDOMShim {
    constructor() {
      this.SVGNS = "http://www.w3.org/2000/svg";
      this.XLINKNS = "http://www.w3.org/1999/xlink";
    }
    /**
     * Create SVG element with namespace
     * @param {string} namespaceURI - Namespace URI
     * @param {string} qualifiedName - Element tag name
     * @returns {SSRElement} Mock SVG element
     */
    createElementNS(namespaceURI, qualifiedName) {
      return new SSRElement(qualifiedName, namespaceURI);
    }
    /**
     * Create text node
     * @param {string} data - Text content
     * @returns {object} Text node mock
     */
    createTextNode(data) {
      const node = {
        nodeName: "#text",
        nodeType: 3,
        textContent: data,
        toString() {
          return node.textContent;
        }
      };
      return node;
    }
    /**
     * Query selector (returns null in SSR)
     * @returns {null}
     */
    querySelector() {
      return null;
    }
    /**
     * Query selector all (returns empty array in SSR)
     * @returns {any[]}
     */
    querySelectorAll() {
      return [];
    }
    /**
     * Get computed style (returns empty object in SSR)
     * @returns {object}
     */
    getComputedStyle() {
      return {};
    }
    /**
     * Get bounding client rect for element
     * @param {SSRElement} element - Element to measure
     * @returns {object} Mock dimensions
     */
    getBoundingClientRect(element) {
      if (element && element.getBoundingClientRect) {
        return element.getBoundingClientRect();
      }
      return {
        width: 0,
        height: 0,
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        x: 0,
        y: 0
      };
    }
    /**
     * Create mock XMLSerializer for SSR
     * @returns {object} XMLSerializer mock
     */
    createXMLSerializer() {
      return {
        /**
         * @param {Element} element
         */
        serializeToString(element) {
          return element.toString ? element.toString() : "";
        }
      };
    }
    /**
     * Create mock DOMParser for SSR
     * @returns {object} DOMParser mock
     */
    createDOMParser() {
      return {
        /**
         * @param {string} str
         * @param {string} _type
         */
        parseFromString(str, _type) {
          const root = new SSRElement("root");
          root.innerHTML = str;
          return {
            documentElement: root
          };
        }
      };
    }
  }
  let shim = null;
  let xmlSerializerInstance = null;
  let domParserInstance = null;
  class BrowserAPIs {
    /**
     * Initialize the SSR shim if in SSR environment
     * Must be called before using other methods
     */
    static init() {
      if (Environment.isSSR() && !shim) {
        shim = new SSRDOMShim();
      }
    }
    /**
     * Create an HTML element
     * @param {string} tagName - Element tag name
     * @returns {HTMLElement} HTML element
     */
    static createElement(tagName) {
      if (Environment.isSSR()) {
        if (!shim) this.init();
        return shim.createElementNS(null, tagName);
      }
      return document.createElement(tagName);
    }
    /**
     * Create an SVG element with namespace
     * @param {string} namespaceURI - Namespace URI
     * @param {string} qualifiedName - Element tag name
     * @returns {HTMLElement} created element
     */
    static createElementNS(namespaceURI, qualifiedName) {
      if (Environment.isSSR()) {
        if (!shim) this.init();
        return shim.createElementNS(namespaceURI, qualifiedName);
      }
      return (
        /** @type {HTMLElement} */
        document.createElementNS(namespaceURI, qualifiedName)
      );
    }
    /**
     * Create a text node
     * @param {string} data - Text content
     * @returns {Text|object} Text node
     */
    static createTextNode(data) {
      if (Environment.isSSR()) {
        if (!shim) this.init();
        return shim.createTextNode(data);
      }
      return document.createTextNode(data);
    }
    /**
     * Query selector
     * @param {string} selector - CSS selector
     * @returns {Element|null}
     */
    static querySelector(selector) {
      if (Environment.isSSR()) {
        return null;
      }
      return document.querySelector(selector);
    }
    /**
     * Query selector all
     * @param {string} selector - CSS selector
     * @returns {NodeList|any[]}
     */
    static querySelectorAll(selector) {
      if (Environment.isSSR()) {
        return [];
      }
      return document.querySelectorAll(selector);
    }
    /**
     * Get computed style for an element
     * @param {Element} element - Element to get styles for
     * @returns {CSSStyleDeclaration|object}
     */
    static getComputedStyle(element) {
      if (Environment.isSSR()) {
        return {};
      }
      return window.getComputedStyle(element);
    }
    /**
     * Get bounding client rect for an element
     * @param {Element} element - Element to measure
     * @returns {DOMRect|object}
     */
    static getBoundingClientRect(element) {
      if (Environment.isSSR()) {
        if (!shim) this.init();
        return shim.getBoundingClientRect(element);
      }
      return element ? element.getBoundingClientRect() : {
        width: 0,
        height: 0,
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        x: 0,
        y: 0
      };
    }
    /**
     * Get XMLSerializer instance
     * @returns {XMLSerializer|object}
     */
    static getXMLSerializer() {
      if (Environment.isSSR()) {
        if (!shim) this.init();
        if (!xmlSerializerInstance) {
          xmlSerializerInstance = shim.createXMLSerializer();
        }
        return xmlSerializerInstance;
      }
      if (!xmlSerializerInstance) {
        xmlSerializerInstance = new XMLSerializer();
      }
      return xmlSerializerInstance;
    }
    /**
     * Get DOMParser instance
     * @returns {DOMParser|object}
     */
    static getDOMParser() {
      if (Environment.isSSR()) {
        if (!shim) this.init();
        if (!domParserInstance) {
          domParserInstance = shim.createDOMParser();
        }
        return domParserInstance;
      }
      if (!domParserInstance) {
        domParserInstance = new DOMParser();
      }
      return domParserInstance;
    }
    /**
     * Add event listener to window
     * @param {string} event - Event name
     * @param {EventListenerOrEventListenerObject} handler - Event handler
     * @param {object} options - Event options
     */
    static addWindowEventListener(event, handler, options2) {
      if (Environment.isBrowser()) {
        window.addEventListener(event, handler, options2);
      }
    }
    /**
     * Remove event listener from window
     * @param {string} event - Event name
     * @param {EventListenerOrEventListenerObject} handler - Event handler
     * @param {object} options - Event options
     */
    static removeWindowEventListener(event, handler, options2) {
      if (Environment.isBrowser()) {
        window.removeEventListener(event, handler, options2);
      }
    }
    /**
     * Request animation frame
     * @param {FrameRequestCallback} callback - Callback function
     * @returns {number|null}
     */
    static requestAnimationFrame(callback) {
      if (Environment.isBrowser()) {
        return window.requestAnimationFrame(callback);
      }
      callback(0);
      return null;
    }
    /**
     * Cancel animation frame
     * @param {number} id - Animation frame ID
     */
    static cancelAnimationFrame(id) {
      if (Environment.isBrowser() && id) {
        window.cancelAnimationFrame(id);
      }
    }
    /**
     * Check if element exists
     * @param {Element} element - Element to check
     * @returns {boolean}
     */
    static elementExists(element) {
      if (!element) return false;
      if (Environment.isSSR()) {
        return element._ssrMode === true || element.nodeName !== void 0;
      }
      return element.getRootNode ? element.getRootNode({ composed: true }) === document || element.isConnected : false;
    }
    /**
     * Get window object (or null in SSR)
     * @returns {Window|null}
     */
    static getWindow() {
      return Environment.isBrowser() ? window : null;
    }
    /**
     * Get document object (or null in SSR)
     * @returns {Document|null}
     */
    static getDocument() {
      return Environment.isBrowser() ? document : null;
    }
    /**
     * Get the shim instance (for testing purposes)
     * @returns {SSRDOMShim|null}
     */
    static _getShim() {
      return shim;
    }
    /**
     * Reset the shim instance (for testing purposes)
     */
    static _resetShim() {
      shim = null;
      xmlSerializerInstance = null;
      domParserInstance = null;
    }
  }
  let Utils$1 = class Utils2 {
    /**
     * @param {*} item
     */
    static isObject(item) {
      return item && typeof item === "object" && !Array.isArray(item);
    }
    // Type checking that works across different window objects
    /**
     * @param {string} type
     * @param {string} val
     */
    static is(type, val) {
      return Object.prototype.toString.call(val) === "[object " + type + "]";
    }
    static isSafari() {
      return Environment.isBrowser() && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
    }
    // to extend defaults with user options
    // credit: http://stackoverflow.com/questions/27936772/deep-object-merging-in-es6-es7#answer-34749873
    /**
     * @param {any} target
     * @param {any} source
     */
    static extend(target, source) {
      const output = Object.assign({}, target);
      if (this.isObject(target) && this.isObject(source)) {
        Object.keys(source).forEach((key) => {
          if (this.isObject(source[key])) {
            if (!(key in target)) {
              Object.assign(output, {
                [key]: source[key]
              });
            } else {
              output[key] = this.extend(target[key], source[key]);
            }
          } else {
            Object.assign(output, {
              [key]: source[key]
            });
          }
        });
      }
      return output;
    }
    /**
     * @param {any[]} arrToExtend
     * @param {any} resultArr
     */
    static extendArray(arrToExtend, resultArr) {
      const extendedArr = [];
      arrToExtend.map((item) => {
        extendedArr.push(Utils2.extend(resultArr, item));
      });
      arrToExtend = extendedArr;
      return arrToExtend;
    }
    // If month counter exceeds 12, it starts again from 1
    /**
     * @param {number} month
     */
    static monthMod(month) {
      return month % 12;
    }
    /**
     * clone object with optional shallow copy for performance
     * @param {*} source - Source object to clone
     * @param {WeakMap<any, any>} visited - Circular reference tracker
     * @param {boolean} shallow - If true, performs shallow copy (default: false)
     * @returns {*} Cloned object
     */
    static clone(source, visited = /* @__PURE__ */ new WeakMap(), shallow = false) {
      if (source === null || typeof source !== "object") {
        return source;
      }
      if (visited.has(source)) {
        return visited.get(source);
      }
      let cloneResult;
      if (Array.isArray(source)) {
        if (shallow) {
          cloneResult = source.slice();
        } else {
          cloneResult = [];
          visited.set(source, cloneResult);
          for (let i = 0; i < source.length; i++) {
            cloneResult[i] = this.clone(source[i], visited, false);
          }
        }
      } else if (source instanceof Date) {
        cloneResult = new Date(source.getTime());
      } else {
        if (shallow) {
          cloneResult = Object.assign({}, source);
        } else {
          cloneResult = {};
          visited.set(source, cloneResult);
          for (const prop in source) {
            if (Object.prototype.hasOwnProperty.call(source, prop)) {
              cloneResult[prop] = this.clone(
                /** @type {Record<string,any>} */
                source[prop],
                visited,
                false
              );
            }
          }
        }
      }
      return cloneResult;
    }
    /**
     * Shallow clone for performance when deep clone isn't needed
     * @param {*} source - Source to clone
     * @returns {*} Shallow cloned object
     */
    static shallowClone(source) {
      if (source === null || typeof source !== "object") {
        return source;
      }
      if (Array.isArray(source)) {
        return source.slice();
      }
      return Object.assign({}, source);
    }
    /**
     * Fast shallow equality check for objects
     * @param {Object} obj1 - First object
     * @param {Object} obj2 - Second object
     * @returns {boolean} True if shallowly equal
     */
    static shallowEqual(obj1, obj2) {
      if (obj1 === obj2) return true;
      if (!obj1 || !obj2) return false;
      if (typeof obj1 !== "object" || typeof obj2 !== "object") {
        return obj1 === obj2;
      }
      const keys1 = Object.keys(obj1);
      const keys2 = Object.keys(obj2);
      if (keys1.length !== keys2.length) return false;
      for (const key of keys1) {
        if (
          /** @type {Record<string,any>} */
          obj1[key] !== /** @type {Record<string,any>} */
          obj2[key]
        )
          return false;
      }
      return true;
    }
    /**
     * @param {number} x
     */
    static log10(x) {
      return Math.log(x) / Math.LN10;
    }
    /**
     * @param {number} x
     */
    static roundToBase10(x) {
      return Math.pow(10, Math.floor(Math.log10(x)));
    }
    /**
     * @param {number} x
     * @param {number} base
     */
    static roundToBase(x, base) {
      return Math.pow(base, Math.floor(Math.log(x) / Math.log(base)));
    }
    /**
     * @param {any} val
     */
    static parseNumber(val) {
      if (typeof val === "number" || val === null) return val;
      return parseFloat(val);
    }
    /**
     * @param {number} num
     */
    static stripNumber(num, precision = 2) {
      return Number.isInteger(num) ? num : parseFloat(num.toPrecision(precision));
    }
    static randomId() {
      return (Math.random() + 1).toString(36).substring(4);
    }
    /**
     * @param {number} num
     */
    static noExponents(num) {
      if (num.toString().includes("e")) {
        return Math.round(num);
      }
      return num;
    }
    /**
     * @param {any} element
     */
    static elementExists(element) {
      if (!element || !element.isConnected) {
        return false;
      }
      return true;
    }
    /**
     * detects if an element is inside a Shadow DOM
     * @param {any} el
     */
    static isInShadowDOM(el) {
      if (!el || !el.getRootNode) {
        return false;
      }
      const rootNode = el.getRootNode();
      return rootNode && rootNode !== document && Utils2.is("ShadowRoot", rootNode);
    }
    /**
     * gets the shadow root host element
     * @param {any} el
     */
    static getShadowRootHost(el) {
      if (!Utils2.isInShadowDOM(el)) {
        return null;
      }
      const rootNode = el.getRootNode();
      return rootNode.host || null;
    }
    /**
     * @param {any} el
     */
    static getDimensions(el) {
      if (!el) return [0, 0];
      if (Environment.isSSR()) {
        return [el._ssrWidth || 400, el._ssrHeight || 300];
      }
      let computedStyle;
      try {
        computedStyle = getComputedStyle(el, null);
      } catch (e) {
        return [el.clientWidth || 0, el.clientHeight || 0];
      }
      let elementWidth = el.clientWidth;
      let elementHeight = el.clientHeight;
      if (!elementWidth || !elementHeight) {
        const rect = el.getBoundingClientRect();
        elementWidth = elementWidth || rect.width;
        elementHeight = elementHeight || rect.height;
      }
      elementHeight -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom);
      elementWidth -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
      return [elementWidth, elementHeight];
    }
    /**
     * @returns {any}
     * @param {any} element
     */
    static getBoundingClientRect(element) {
      if (!element) {
        return {
          top: 0,
          right: 0,
          bottom: 0,
          left: 0,
          width: 0,
          height: 0,
          x: 0,
          y: 0
        };
      }
      if (Environment.isSSR()) {
        return BrowserAPIs.getBoundingClientRect(element);
      }
      const rect = element.getBoundingClientRect();
      return {
        top: rect.top,
        right: rect.right,
        bottom: rect.bottom,
        left: rect.left,
        width: element.clientWidth,
        height: element.clientHeight,
        x: rect.left,
        y: rect.top
      };
    }
    /**
     * @param {any[]} arr
     */
    static getLargestStringFromArr(arr) {
      return arr.reduce((a, b) => {
        if (Array.isArray(b)) {
          b = b.reduce((aa, bb) => aa.length > bb.length ? aa : bb);
        }
        return a.length > b.length ? a : b;
      }, 0);
    }
    // http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-12342275
    static hexToRgba(hex = "#999999", opacity = 0.6) {
      if (hex.substring(0, 1) !== "#") {
        hex = "#999999";
      }
      const hexStr = hex.replace("#", "");
      const h = hexStr.match(new RegExp("(.{" + hexStr.length / 3 + "})", "g")) || [];
      for (let i = 0; i < h.length; i++) {
        h[i] = parseInt(h[i].length === 1 ? h[i] + h[i] : h[i], 16);
      }
      if (typeof opacity !== "undefined") h.push(opacity);
      return "rgba(" + h.join(",") + ")";
    }
    /**
     * @param {string} rgba
     */
    static getOpacityFromRGBA(rgba) {
      return parseFloat(rgba.replace(/^.*,(.+)\)/, "$1"));
    }
    /**
     * @param {any} rgb
     */
    static rgb2hex(rgb) {
      rgb = rgb.match(
        /^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i
      );
      return rgb && rgb.length === 4 ? "#" + ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : "";
    }
    /**
     * @param {number} percent
     * @param {string} color
     */
    shadeRGBColor(percent, color) {
      const f = color.split(","), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = parseInt(f[0].slice(4), 10), G = parseInt(f[1], 10), B = parseInt(f[2], 10);
      return "rgb(" + (Math.round((t - R) * p) + R) + "," + (Math.round((t - G) * p) + G) + "," + (Math.round((t - B) * p) + B) + ")";
    }
    /**
     * @param {number} percent
     * @param {string} color
     */
    shadeHexColor(percent, color) {
      const f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 255, B = f & 255;
      return "#" + (16777216 + (Math.round((t - R) * p) + R) * 65536 + (Math.round((t - G) * p) + G) * 256 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
    }
    // beautiful color shading blending code
    // http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors
    /**
     * @param {number} p
     * @param {string} color
     */
    shadeColor(p, color) {
      if (Utils2.isColorHex(color)) {
        return this.shadeHexColor(p, color);
      } else {
        return this.shadeRGBColor(p, color);
      }
    }
    /**
     * @param {string} color
     */
    static isColorHex(color) {
      return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)|(^#[0-9A-F]{8}$)/i.test(color);
    }
    /**
     * @param {string} color
     */
    static isCSSVariable(color) {
      if (typeof color !== "string") return false;
      const value = color.trim();
      return value.startsWith("var(") && value.endsWith(")");
    }
    /**
     * @param {string} color
     */
    static getThemeColor(color) {
      if (!Utils2.isCSSVariable(color)) return color;
      if (Environment.isSSR()) return color;
      const tempElem = document.createElement("div");
      tempElem.style.cssText = "position:fixed; left: -9999px; visibility:hidden;";
      tempElem.style.color = color;
      document.body.appendChild(tempElem);
      let computedColor;
      try {
        computedColor = window.getComputedStyle(tempElem).color;
      } finally {
        if (tempElem.parentNode) {
          tempElem.parentNode.removeChild(tempElem);
        }
      }
      return computedColor;
    }
    /**
     * @param {string} color
     * @param {number} opacity
     */
    static applyOpacityToColor(color, opacity) {
      const value = Number(opacity);
      if (!Number.isFinite(value)) return color;
      if (value <= 0) return "transparent";
      if (value >= 1) return color;
      const percent = Math.round(value * 100);
      return `color-mix(in srgb, ${color} ${percent}%, transparent)`;
    }
    /**
     * @param {number} size
     * @param {number} dataPointsLen
     */
    static getPolygonPos(size, dataPointsLen) {
      const dotsArray = [];
      const angle = Math.PI * 2 / dataPointsLen;
      for (let i = 0; i < dataPointsLen; i++) {
        const curPos = {};
        curPos.x = size * Math.sin(i * angle);
        curPos.y = -size * Math.cos(i * angle);
        dotsArray.push(curPos);
      }
      return dotsArray;
    }
    /**
     * @param {number} centerX
     * @param {number} centerY
     * @param {number} radius
     * @param {number} angleInDegrees
     */
    static polarToCartesian(centerX, centerY, radius, angleInDegrees) {
      const angleInRadians = (angleInDegrees - 90) * Math.PI / 180;
      return {
        x: centerX + radius * Math.cos(angleInRadians),
        y: centerY + radius * Math.sin(angleInRadians)
      };
    }
    /**
     * @param {string} str
     */
    static escapeString(str, escapeWith = "x") {
      let newStr = str.toString().slice();
      newStr = newStr.replace(/[` ~!@#$%^&*()|+=?;:'",.<>{}[\]\\/]/gi, escapeWith);
      return newStr;
    }
    /**
     * @param {number} val
     */
    static negToZero(val) {
      return val < 0 ? 0 : val;
    }
    /**
     * @param {any[]} arr
     * @param {number} old_index
     * @param {number} new_index
     */
    static moveIndexInArray(arr, old_index, new_index) {
      if (new_index >= arr.length) {
        let k = new_index - arr.length + 1;
        while (k--) {
          arr.push(void 0);
        }
      }
      arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
      return arr;
    }
    /**
     * @param {string} s
     */
    static extractNumber(s) {
      return parseFloat(s.replace(/[^\d.]*/g, ""));
    }
    /**
     * @param {any} el
     * @param {string} cls
     */
    static findAncestor(el, cls) {
      while ((el = el.parentElement) && !el.classList.contains(cls)) ;
      return el;
    }
    /**
     * @param {any} el
     * @param {Record<string, any>} styles
     */
    static setELstyles(el, styles) {
      for (const key in styles) {
        if (Object.prototype.hasOwnProperty.call(styles, key)) {
          el.style.key = styles[key];
        }
      }
    }
    // prevents JS prevision errors when adding
    /**
     * @param {number} a
     * @param {number} b
     */
    static preciseAddition(a, b) {
      const aDecimals = (String(a).split(".")[1] || "").length;
      const bDecimals = (String(b).split(".")[1] || "").length;
      const factor = Math.pow(10, Math.max(aDecimals, bDecimals));
      return (Math.round(a * factor) + Math.round(b * factor)) / factor;
    }
    /**
     * @param {any} value
     */
    static isNumber(value) {
      return !isNaN(value) && parseFloat(String(Number(value))) === value && !isNaN(parseInt(value, 10));
    }
    /**
     * @param {number} n
     */
    static isFloat(n) {
      return Number(n) === n && n % 1 !== 0;
    }
    static isMsEdge() {
      if (Environment.isSSR()) return false;
      const ua = window.navigator.userAgent;
      const edge = ua.indexOf("Edge/");
      if (edge > 0) {
        return parseInt(ua.substring(edge + 5, ua.indexOf(".", edge)), 10);
      }
      return false;
    }
    //
    // Find the Greatest Common Divisor of two numbers
    //
    /**
     * @param {number} a
     * @param {number} b
     */
    static getGCD(a, b, p = 7) {
      let factor = Math.pow(10, p - Math.floor(Math.log10(Math.max(a, b))));
      if (factor > 1) {
        a = Math.round(Math.abs(a) * factor);
        b = Math.round(Math.abs(b) * factor);
      } else {
        factor = 1;
      }
      while (b) {
        const t = b;
        b = a % b;
        a = t;
      }
      return a / factor;
    }
    /**
     * @param {number} n
     */
    static getPrimeFactors(n) {
      const factors = [];
      let divisor = 2;
      while (n >= 2) {
        if (n % divisor == 0) {
          factors.push(divisor);
          n = n / divisor;
        } else {
          divisor++;
        }
      }
      return factors;
    }
    /**
     * @param {number} a
     * @param {number} b
     */
    static mod(a, b, p = 7) {
      const big = Math.pow(10, p - Math.floor(Math.log10(Math.max(a, b))));
      a = Math.round(Math.abs(a) * big);
      b = Math.round(Math.abs(b) * big);
      return a % b / big;
    }
  };
  class DateTime {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this.months31 = [1, 3, 5, 7, 8, 10, 12];
      this.months30 = [2, 4, 6, 9, 11];
      this.daysCntOfYear = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
    }
    /**
     * @param {any} date
     */
    isValidDate(date) {
      if (typeof date === "number") {
        return false;
      }
      return !isNaN(this.parseDate(date));
    }
    /**
     * @param {any} dateStr
     */
    getTimeStamp(dateStr) {
      if (!Date.parse(dateStr)) {
        return dateStr;
      }
      const utc = this.w.config.xaxis.labels.datetimeUTC;
      return !utc ? new Date(dateStr).getTime() : new Date(new Date(dateStr).toISOString().substr(0, 25)).getTime();
    }
    /**
     * @param {any} timestamp
     */
    getDate(timestamp) {
      const utc = this.w.config.xaxis.labels.datetimeUTC;
      return utc ? new Date(new Date(timestamp).toUTCString()) : new Date(timestamp);
    }
    /**
     * @param {string} dateStr
     */
    parseDate(dateStr) {
      const parsed = Date.parse(dateStr);
      if (!isNaN(parsed)) {
        return this.getTimeStamp(dateStr);
      }
      let output = Date.parse(dateStr.replace(/-/g, "/").replace(/[a-z]+/gi, " "));
      output = this.getTimeStamp(output);
      return output;
    }
    // This fixes the difference of x-axis labels between chrome/safari
    // Fixes #1726, #1544, #1485, #1255
    /**
     * @param {string} dateStr
     */
    parseDateWithTimezone(dateStr) {
      return Date.parse(dateStr.replace(/-/g, "/").replace(/[a-z]+/gi, " "));
    }
    // http://stackoverflow.com/questions/14638018/current-time-formatting-with-javascript#answer-14638191
    /**
     * @param {Date} date
     * @param {string} format
     */
    formatDate(date, format) {
      const locale = this.w.globals.locale;
      const utc = this.w.config.xaxis.labels.datetimeUTC;
      const MMMM = ["\0", ...locale.months];
      const MMM = ["", ...locale.shortMonths];
      const dddd = ["", ...locale.days];
      const ddd = ["", ...locale.shortDays];
      function ii(i, len = 2) {
        let s2 = i + "";
        while (s2.length < len) s2 = "0" + s2;
        return s2;
      }
      const y = utc ? date.getUTCFullYear() : date.getFullYear();
      format = format.replace(/(^|[^\\])yyyy+/g, "$1" + y);
      format = format.replace(/(^|[^\\])yy/g, "$1" + y.toString().substr(2, 2));
      format = format.replace(/(^|[^\\])y/g, "$1" + y);
      const M = (utc ? date.getUTCMonth() : date.getMonth()) + 1;
      format = format.replace(/(^|[^\\])MMMM+/g, "$1" + MMMM[0]);
      format = format.replace(/(^|[^\\])MMM/g, "$1" + MMM[0]);
      format = format.replace(/(^|[^\\])MM/g, "$1" + ii(M));
      format = format.replace(/(^|[^\\])M/g, "$1" + M);
      const d = utc ? date.getUTCDate() : date.getDate();
      format = format.replace(/(^|[^\\])dddd+/g, "$1" + dddd[0]);
      format = format.replace(/(^|[^\\])ddd/g, "$1" + ddd[0]);
      format = format.replace(/(^|[^\\])dd/g, "$1" + ii(d));
      format = format.replace(/(^|[^\\])d/g, "$1" + d);
      const H = utc ? date.getUTCHours() : date.getHours();
      format = format.replace(/(^|[^\\])HH+/g, "$1" + ii(H));
      format = format.replace(/(^|[^\\])H/g, "$1" + H);
      const h = H > 12 ? H - 12 : H === 0 ? 12 : H;
      format = format.replace(/(^|[^\\])hh+/g, "$1" + ii(h));
      format = format.replace(/(^|[^\\])h/g, "$1" + h);
      const m = utc ? date.getUTCMinutes() : date.getMinutes();
      format = format.replace(/(^|[^\\])mm+/g, "$1" + ii(m));
      format = format.replace(/(^|[^\\])m/g, "$1" + m);
      const s = utc ? date.getUTCSeconds() : date.getSeconds();
      format = format.replace(/(^|[^\\])ss+/g, "$1" + ii(s));
      format = format.replace(/(^|[^\\])s/g, "$1" + s);
      let f = utc ? date.getUTCMilliseconds() : date.getMilliseconds();
      format = format.replace(/(^|[^\\])fff+/g, "$1" + ii(f, 3));
      f = Math.round(f / 10);
      format = format.replace(/(^|[^\\])ff/g, "$1" + ii(f));
      f = Math.round(f / 10);
      format = format.replace(/(^|[^\\])f/g, "$1" + f);
      const T = H < 12 ? "AM" : "PM";
      format = format.replace(/(^|[^\\])TT+/g, "$1" + T);
      format = format.replace(/(^|[^\\])T/g, "$1" + T.charAt(0));
      const t = T.toLowerCase();
      format = format.replace(/(^|[^\\])tt+/g, "$1" + t);
      format = format.replace(/(^|[^\\])t/g, "$1" + t.charAt(0));
      let tz = -date.getTimezoneOffset();
      let K = utc || !tz ? "Z" : tz > 0 ? "+" : "-";
      if (!utc) {
        tz = Math.abs(tz);
        const tzHrs = Math.floor(tz / 60);
        const tzMin = tz % 60;
        K += ii(tzHrs) + ":" + ii(tzMin);
      }
      format = format.replace(/(^|[^\\])K/g, "$1" + K);
      const day = (utc ? date.getUTCDay() : date.getDay()) + 1;
      format = format.replace(new RegExp(dddd[0], "g"), dddd[day]);
      format = format.replace(new RegExp(ddd[0], "g"), ddd[day]);
      format = format.replace(new RegExp(MMMM[0], "g"), MMMM[M]);
      format = format.replace(new RegExp(MMM[0], "g"), MMM[M]);
      format = format.replace(/\\(.)/g, "$1");
      return format;
    }
    /**
     * @param {number} minX
     * @param {number} maxX
     */
    getTimeUnitsfromTimestamp(minX, maxX) {
      const w = this.w;
      if (w.config.xaxis.min !== void 0) {
        minX = w.config.xaxis.min;
      }
      if (w.config.xaxis.max !== void 0) {
        maxX = w.config.xaxis.max;
      }
      const tsMin = this.getDate(minX);
      const tsMax = this.getDate(maxX);
      const minD = this.formatDate(tsMin, "yyyy MM dd HH mm ss fff").split(" ");
      const maxD = this.formatDate(tsMax, "yyyy MM dd HH mm ss fff").split(" ");
      return {
        minMillisecond: parseInt(minD[6], 10),
        maxMillisecond: parseInt(maxD[6], 10),
        minSecond: parseInt(minD[5], 10),
        maxSecond: parseInt(maxD[5], 10),
        minMinute: parseInt(minD[4], 10),
        maxMinute: parseInt(maxD[4], 10),
        minHour: parseInt(minD[3], 10),
        maxHour: parseInt(maxD[3], 10),
        minDate: parseInt(minD[2], 10),
        maxDate: parseInt(maxD[2], 10),
        minMonth: parseInt(minD[1], 10) - 1,
        maxMonth: parseInt(maxD[1], 10) - 1,
        minYear: parseInt(minD[0], 10),
        maxYear: parseInt(maxD[0], 10)
      };
    }
    /**
     * @param {number} year
     */
    isLeapYear(year) {
      return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
    }
    /**
     * @param {number} month
     * @param {number} year
     * @param {number} subtract
     */
    calculcateLastDaysOfMonth(month, year, subtract) {
      const days = this.determineDaysOfMonths(month, year);
      return days - subtract;
    }
    /**
     * @param {number} year
     */
    determineDaysOfYear(year) {
      let days = 365;
      if (this.isLeapYear(year)) {
        days = 366;
      }
      return days;
    }
    /**
     * @param {number} year
     * @param {number} month
     * @param {number} date
     */
    determineRemainingDaysOfYear(year, month, date) {
      let dayOfYear = this.daysCntOfYear[month] + date;
      if (month > 1 && this.isLeapYear(year)) dayOfYear++;
      return dayOfYear;
    }
    /**
     * @param {number} month
     * @param {number} year
     */
    determineDaysOfMonths(month, year) {
      let days = 30;
      month = Utils$1.monthMod(month);
      switch (true) {
        case this.months30.indexOf(month) > -1:
          if (month === 2) {
            if (this.isLeapYear(year)) {
              days = 29;
            } else {
              days = 28;
            }
          }
          break;
        case this.months31.indexOf(month) > -1:
          days = 31;
          break;
        default:
          days = 31;
          break;
      }
      return days;
    }
  }
  class Formatters {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this.tooltipKeyFormat = "dd MMM";
    }
    /**
     * @param {Function} fn
     * @param {any} val
     * @param {any} timestamp
     * @param {any} _opts
     */
    xLabelFormat(fn, val, timestamp, _opts) {
      const w = this.w;
      if (w.config.xaxis.type === "datetime") {
        if (w.config.xaxis.labels.formatter === void 0) {
          if (w.config.tooltip.x.formatter === void 0) {
            const datetimeObj = new DateTime(this.w);
            return datetimeObj.formatDate(
              datetimeObj.getDate(val),
              w.config.tooltip.x.format
            );
          }
        }
      }
      return fn(val, timestamp, _opts);
    }
    /**
     * @param {any} val
     */
    defaultGeneralFormatter(val) {
      if (Array.isArray(val)) {
        return val.map((v) => {
          return v;
        });
      } else {
        return val;
      }
    }
    /**
     * @param {any} v
     * @param {ApexYAxis} yaxe
     */
    defaultYFormatter(v, yaxe) {
      const w = this.w;
      if (Utils$1.isNumber(v)) {
        if (w.globals.yValueDecimal !== 0) {
          v = v.toFixed(
            yaxe.decimalsInFloat !== void 0 ? yaxe.decimalsInFloat : w.globals.yValueDecimal
          );
        } else {
          const f = v.toFixed(0);
          v = Number(f) === v ? f : v.toFixed(1);
        }
      }
      return v;
    }
    setLabelFormatters() {
      const w = this.w;
      const fmt = w.formatters;
      fmt.xaxisTooltipFormatter = (val) => {
        return this.defaultGeneralFormatter(val);
      };
      fmt.ttKeyFormatter = (val) => {
        return this.defaultGeneralFormatter(val);
      };
      fmt.ttZFormatter = (val) => {
        return val;
      };
      fmt.legendFormatter = (val) => {
        return this.defaultGeneralFormatter(val);
      };
      if (w.config.xaxis.labels.formatter !== void 0) {
        fmt.xLabelFormatter = w.config.xaxis.labels.formatter;
      } else {
        fmt.xLabelFormatter = (val) => {
          if (Utils$1.isNumber(val)) {
            if (!w.config.xaxis.convertedCatToNumeric && w.config.xaxis.type === "numeric") {
              if (Utils$1.isNumber(w.config.xaxis.decimalsInFloat)) {
                return val.toFixed(w.config.xaxis.decimalsInFloat);
              } else {
                const diff = w.globals.maxX - w.globals.minX;
                if (diff > 0 && diff < 100) {
                  return val.toFixed(1);
                }
                return val.toFixed(0);
              }
            }
            if (w.globals.isBarHorizontal) {
              const range = w.globals.maxY - /** @type {any} */
              w.globals.minYArr;
              if (range < 4) {
                return val.toFixed(1);
              }
            }
            return val.toFixed(0);
          }
          return val;
        };
      }
      if (typeof w.config.tooltip.x.formatter === "function") {
        fmt.ttKeyFormatter = w.config.tooltip.x.formatter;
      } else {
        fmt.ttKeyFormatter = fmt.xLabelFormatter;
      }
      if (typeof w.config.xaxis.tooltip.formatter === "function") {
        fmt.xaxisTooltipFormatter = w.config.xaxis.tooltip.formatter;
      }
      if (Array.isArray(w.config.tooltip.y)) {
        fmt.ttVal = w.config.tooltip.y;
      } else {
        if (w.config.tooltip.y.formatter !== void 0) {
          fmt.ttVal = w.config.tooltip.y;
        }
      }
      if (w.config.tooltip.z.formatter !== void 0) {
        fmt.ttZFormatter = w.config.tooltip.z.formatter;
      }
      if (w.config.legend.formatter !== void 0) {
        fmt.legendFormatter = w.config.legend.formatter;
      }
      fmt.yLabelFormatters = [];
      w.config.yaxis.forEach((yaxe, i) => {
        if (yaxe.labels.formatter !== void 0) {
          fmt.yLabelFormatters[i] = yaxe.labels.formatter;
        } else {
          fmt.yLabelFormatters[i] = (val) => {
            if (!w.globals.xyCharts) return val;
            if (Array.isArray(val)) {
              return val.map((v) => {
                return this.defaultYFormatter(v, yaxe);
              });
            } else {
              return this.defaultYFormatter(val, yaxe);
            }
          };
        }
      });
      return w.globals;
    }
    heatmapLabelFormatters() {
      const w = this.w;
      if (w.config.chart.type === "heatmap") {
        w.globals.yAxisScale[0].result = /** @type {any} */
        w.seriesData.seriesNames.slice();
        const longest = (
          /** @type {any} */
          w.seriesData.seriesNames.reduce(
            (a, b) => a.length > b.length ? a : b,
            0
          )
        );
        w.globals.yAxisScale[0].niceMax = longest;
        w.globals.yAxisScale[0].niceMin = longest;
      }
    }
  }
  const getRangeValues = ({
    isTimeline,
    seriesIndex,
    dataPointIndex,
    y1,
    y2,
    w
  }) => {
    var _a;
    let start = w.rangeData.seriesRangeStart[seriesIndex][dataPointIndex];
    let end = w.rangeData.seriesRangeEnd[seriesIndex][dataPointIndex];
    let ylabel = w.labelData.labels[dataPointIndex];
    let seriesName = w.config.series[seriesIndex].name ? w.config.series[seriesIndex].name : "";
    const yLbFormatter = w.formatters.ttKeyFormatter;
    const yLbTitleFormatter = w.config.tooltip.y.title.formatter;
    const opts = {
      w,
      seriesIndex,
      dataPointIndex,
      start,
      end
    };
    if (typeof yLbTitleFormatter === "function") {
      seriesName = yLbTitleFormatter(seriesName, opts);
    }
    if ((_a = w.config.series[seriesIndex].data[dataPointIndex]) == null ? void 0 : _a.x) {
      ylabel = w.config.series[seriesIndex].data[dataPointIndex].x;
    }
    if (!isTimeline) {
      if (w.config.xaxis.type === "datetime") {
        const xFormat = new Formatters(w);
        ylabel = xFormat.xLabelFormat(
          w.formatters.ttKeyFormatter,
          ylabel,
          ylabel,
          {
            i: void 0,
            dateFormatter: new DateTime(w).formatDate,
            w
          }
        );
      }
    }
    if (typeof yLbFormatter === "function") {
      ylabel = yLbFormatter(ylabel, opts);
    }
    if (Number.isFinite(y1) && Number.isFinite(y2)) {
      start = y1;
      end = y2;
    }
    let startVal = "";
    let endVal = "";
    const color = w.globals.colors[seriesIndex];
    if (w.config.tooltip.x.formatter === void 0) {
      if (w.config.xaxis.type === "datetime") {
        const datetimeObj = new DateTime(w);
        startVal = datetimeObj.formatDate(
          datetimeObj.getDate(start),
          w.config.tooltip.x.format
        );
        endVal = datetimeObj.formatDate(
          datetimeObj.getDate(end),
          w.config.tooltip.x.format
        );
      } else {
        startVal = start;
        endVal = end;
      }
    } else {
      startVal = w.config.tooltip.x.formatter(start);
      endVal = w.config.tooltip.x.formatter(end);
    }
    return { start, end, startVal, endVal, ylabel, color, seriesName };
  };
  const buildRangeTooltipHTML = (opts) => {
    let { color, seriesName, ylabel, start, end, seriesIndex, dataPointIndex } = opts;
    const formatter = opts.w.globals.tooltip.tooltipLabels.getFormatters(seriesIndex);
    start = formatter.yLbFormatter(start);
    end = formatter.yLbFormatter(end);
    const val = formatter.yLbFormatter(
      opts.w.seriesData.series[seriesIndex][dataPointIndex]
    );
    let valueHTML = "";
    const rangeValues = `<span class="value start-value">
  ${start}
  </span> <span class="separator">-</span> <span class="value end-value">
  ${end}
  </span>`;
    if (opts.w.globals.comboCharts) {
      if (opts.w.config.series[seriesIndex].type === "rangeArea" || opts.w.config.series[seriesIndex].type === "rangeBar") {
        valueHTML = rangeValues;
      } else {
        valueHTML = `<span>${val}</span>`;
      }
    } else {
      valueHTML = rangeValues;
    }
    return '<div class="apexcharts-tooltip-rangebar"><div> <span class="series-name" style="color: ' + color + '">' + (seriesName ? seriesName : "") + '</span></div><div> <span class="category">' + ylabel + ": </span> " + valueHTML + " </div></div>";
  };
  class Defaults {
    /**
     * @param {Record<string, any>} opts
     */
    constructor(opts) {
      this.opts = opts;
    }
    hideYAxis() {
      this.opts.yaxis[0].show = false;
      this.opts.yaxis[0].title.text = "";
      this.opts.yaxis[0].axisBorder.show = false;
      this.opts.yaxis[0].axisTicks.show = false;
      this.opts.yaxis[0].floating = true;
    }
    line() {
      return {
        dataLabels: {
          enabled: false
        },
        stroke: {
          width: 5,
          curve: "straight"
        },
        markers: {
          size: 0,
          hover: {
            sizeOffset: 6
          }
        },
        xaxis: {
          crosshairs: {
            width: 1
          }
        }
      };
    }
    /**
     * @param {Record<string, any>} defaults
     */
    sparkline(defaults) {
      this.hideYAxis();
      const ret = {
        grid: {
          show: false,
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0
          }
        },
        legend: {
          show: false
        },
        xaxis: {
          labels: {
            show: false
          },
          tooltip: {
            enabled: false
          },
          axisBorder: {
            show: false
          },
          axisTicks: {
            show: false
          }
        },
        chart: {
          toolbar: {
            show: false
          },
          zoom: {
            enabled: false
          }
        },
        dataLabels: {
          enabled: false
        }
      };
      return Utils$1.extend(defaults, ret);
    }
    slope() {
      this.hideYAxis();
      return {
        chart: {
          toolbar: {
            show: false
          },
          zoom: {
            enabled: false
          }
        },
        dataLabels: {
          enabled: true,
          /**
           * @param {any} val
           * @param {Record<string, any>} opts
           */
          formatter(val, opts) {
            const seriesName = opts.w.config.series[opts.seriesIndex].name;
            return val !== null ? seriesName + ": " + val : "";
          },
          background: {
            enabled: false
          },
          offsetX: -5
        },
        grid: {
          xaxis: {
            lines: {
              show: true
            }
          },
          yaxis: {
            lines: {
              show: false
            }
          }
        },
        xaxis: {
          position: "top",
          labels: {
            style: {
              fontSize: 14,
              fontWeight: 900
            }
          },
          tooltip: {
            enabled: false
          },
          crosshairs: {
            show: false
          }
        },
        markers: {
          size: 8,
          hover: {
            sizeOffset: 1
          }
        },
        legend: {
          show: false
        },
        tooltip: {
          shared: false,
          intersect: true,
          followCursor: true
        },
        stroke: {
          width: 5,
          curve: "straight"
        }
      };
    }
    bar() {
      return {
        chart: {
          stacked: false
        },
        plotOptions: {
          bar: {
            dataLabels: {
              position: "center"
            }
          }
        },
        dataLabels: {
          style: {
            colors: ["#fff"]
          },
          background: {
            enabled: false
          }
        },
        stroke: {
          width: 0,
          lineCap: "square"
        },
        fill: {
          opacity: 0.85
        },
        legend: {
          markers: {
            shape: "square"
          }
        },
        tooltip: {
          shared: false,
          intersect: true
        },
        xaxis: {
          tooltip: {
            enabled: false
          },
          tickPlacement: "between",
          crosshairs: {
            width: "barWidth",
            position: "back",
            fill: {
              type: "gradient"
            },
            dropShadow: {
              enabled: false
            },
            stroke: {
              width: 0
            }
          }
        }
      };
    }
    funnel() {
      this.hideYAxis();
      return __spreadProps(__spreadValues({}, this.bar()), {
        chart: {
          animations: {
            speed: 800,
            animateGradually: {
              enabled: false
            }
          }
        },
        plotOptions: {
          bar: {
            horizontal: true,
            borderRadiusApplication: "around",
            borderRadius: 0,
            dataLabels: {
              position: "center"
            }
          }
        },
        grid: {
          show: false,
          padding: {
            left: 0,
            right: 0
          }
        },
        xaxis: {
          labels: {
            show: false
          },
          tooltip: {
            enabled: false
          },
          axisBorder: {
            show: false
          },
          axisTicks: {
            show: false
          }
        }
      });
    }
    candlestick() {
      return {
        stroke: {
          width: 1
        },
        fill: {
          opacity: 1
        },
        dataLabels: {
          enabled: false
        },
        tooltip: {
          shared: true,
          custom: ({ seriesIndex, dataPointIndex, w }) => {
            return this._getBoxTooltip(
              w,
              seriesIndex,
              dataPointIndex,
              ["Open", "High", "", "Low", "Close"],
              "candlestick"
            );
          }
        },
        states: {
          active: {
            filter: {
              type: "none"
            }
          }
        },
        xaxis: {
          crosshairs: {
            width: 1
          }
        }
      };
    }
    boxPlot() {
      return {
        chart: {
          animations: {
            dynamicAnimation: {
              enabled: false
            }
          }
        },
        stroke: {
          width: 1,
          colors: ["#24292e"]
        },
        dataLabels: {
          enabled: false
        },
        tooltip: {
          shared: true,
          custom: ({ seriesIndex, dataPointIndex, w }) => {
            return this._getBoxTooltip(
              w,
              seriesIndex,
              dataPointIndex,
              ["Minimum", "Q1", "Median", "Q3", "Maximum"],
              "boxPlot"
            );
          }
        },
        markers: {
          size: 7,
          strokeWidth: 1,
          strokeColors: "#111"
        },
        xaxis: {
          crosshairs: {
            width: 1
          }
        }
      };
    }
    rangeBar() {
      const handleTimelineTooltip = (opts) => {
        const { color, seriesName, ylabel, startVal, endVal } = getRangeValues(__spreadProps(__spreadValues({}, opts), {
          isTimeline: true
        }));
        return buildRangeTooltipHTML(__spreadProps(__spreadValues({}, opts), {
          color,
          seriesName,
          ylabel,
          start: startVal,
          end: endVal
        }));
      };
      const handleRangeColumnTooltip = (opts) => {
        const { color, seriesName, ylabel, start, end } = getRangeValues(opts);
        return buildRangeTooltipHTML(__spreadProps(__spreadValues({}, opts), {
          color,
          seriesName,
          ylabel,
          start,
          end
        }));
      };
      return {
        chart: {
          animations: {
            animateGradually: false
          }
        },
        stroke: {
          width: 0,
          lineCap: "square"
        },
        plotOptions: {
          bar: {
            borderRadius: 0,
            dataLabels: {
              position: "center"
            }
          }
        },
        dataLabels: {
          enabled: false,
          /**
           * @param {any} val
           */
          formatter(val, { seriesIndex, dataPointIndex, w }) {
            const getVal = () => {
              const start = w.rangeData.seriesRangeStart[seriesIndex][dataPointIndex];
              const end = w.rangeData.seriesRangeEnd[seriesIndex][dataPointIndex];
              return end - start;
            };
            if (w.globals.comboCharts) {
              if (w.config.series[seriesIndex].type === "rangeBar" || w.config.series[seriesIndex].type === "rangeArea") {
                return getVal();
              } else {
                return val;
              }
            } else {
              return getVal();
            }
          },
          background: {
            enabled: false
          },
          style: {
            colors: ["#fff"]
          }
        },
        markers: {
          size: 10
        },
        tooltip: {
          shared: false,
          followCursor: true,
          /**
           * @param {Record<string, any>} opts
           */
          custom(opts) {
            if (opts.w.config.plotOptions && opts.w.config.plotOptions.bar && opts.w.config.plotOptions.bar.horizontal) {
              return handleTimelineTooltip(opts);
            } else {
              return handleRangeColumnTooltip(opts);
            }
          }
        },
        xaxis: {
          tickPlacement: "between",
          tooltip: {
            enabled: false
          },
          crosshairs: {
            stroke: {
              width: 0
            }
          }
        }
      };
    }
    /**
     * @param {Record<string, any>} opts
     */
    dumbbell(opts) {
      var _a, _b;
      if (!((_a = opts.plotOptions.bar) == null ? void 0 : _a.barHeight)) {
        opts.plotOptions.bar.barHeight = 2;
      }
      if (!((_b = opts.plotOptions.bar) == null ? void 0 : _b.columnWidth)) {
        opts.plotOptions.bar.columnWidth = 2;
      }
      return opts;
    }
    area() {
      return {
        stroke: {
          width: 4,
          fill: {
            type: "solid",
            gradient: {
              inverseColors: false,
              shade: "light",
              type: "vertical",
              opacityFrom: 0.65,
              opacityTo: 0.5,
              stops: [0, 100, 100]
            }
          }
        },
        fill: {
          type: "gradient",
          gradient: {
            inverseColors: false,
            shade: "light",
            type: "vertical",
            opacityFrom: 0.65,
            opacityTo: 0.5,
            stops: [0, 100, 100]
          }
        },
        markers: {
          size: 0,
          hover: {
            sizeOffset: 6
          }
        },
        tooltip: {
          followCursor: false
        }
      };
    }
    rangeArea() {
      const handleRangeAreaTooltip = (opts) => {
        const { color, seriesName, ylabel, start, end } = getRangeValues(opts);
        return buildRangeTooltipHTML(__spreadProps(__spreadValues({}, opts), {
          color,
          seriesName,
          ylabel,
          start,
          end
        }));
      };
      return {
        stroke: {
          curve: "straight",
          width: 0
        },
        fill: {
          type: "solid",
          opacity: 0.6
        },
        markers: {
          size: 0
        },
        states: {
          hover: {
            filter: {
              type: "none"
            }
          },
          active: {
            filter: {
              type: "none"
            }
          }
        },
        tooltip: {
          intersect: false,
          shared: true,
          followCursor: true,
          /**
           * @param {Record<string, any>} opts
           */
          custom(opts) {
            return handleRangeAreaTooltip(opts);
          }
        }
      };
    }
    /**
     * @param {Record<string, any>} defaults
     */
    brush(defaults) {
      const ret = {
        chart: {
          toolbar: {
            autoSelected: "selection",
            show: false
          },
          zoom: {
            enabled: false
          }
        },
        dataLabels: {
          enabled: false
        },
        stroke: {
          width: 1
        },
        tooltip: {
          enabled: false
        },
        xaxis: {
          tooltip: {
            enabled: false
          }
        }
      };
      return Utils$1.extend(defaults, ret);
    }
    /**
     * @param {Record<string, any>} opts
     */
    stacked100(opts) {
      opts.dataLabels = opts.dataLabels || {};
      opts.dataLabels.formatter = opts.dataLabels.formatter || void 0;
      const existingDataLabelFormatter = opts.dataLabels.formatter;
      opts.yaxis.forEach((yaxe, index) => {
        opts.yaxis[index].min = 0;
        opts.yaxis[index].max = 100;
      });
      const isBar = opts.chart.type === "bar";
      if (isBar) {
        opts.dataLabels.formatter = existingDataLabelFormatter || /**
         * @param {any} val
         */
        function(val) {
          if (typeof val === "number") {
            return val ? val.toFixed(0) + "%" : val;
          }
          return val;
        };
      }
      return opts;
    }
    stackedBars() {
      const barDefaults = this.bar();
      return __spreadProps(__spreadValues({}, barDefaults), {
        plotOptions: __spreadProps(__spreadValues({}, barDefaults.plotOptions), {
          bar: __spreadProps(__spreadValues({}, barDefaults.plotOptions.bar), {
            borderRadiusApplication: "end",
            borderRadiusWhenStacked: "last"
          })
        })
      });
    }
    // This function removes the left and right spacing in chart for line/area/scatter if xaxis type = category for those charts by converting xaxis = numeric. Numeric/Datetime xaxis prevents the unnecessary spacing in the left/right of the chart area
    /**
     * @param {Record<string, any>} opts
     */
    convertCatToNumeric(opts) {
      opts.xaxis.convertedCatToNumeric = true;
      return opts;
    }
    /**
     * @param {Record<string, any>} opts
     * @param {any} cats
     */
    convertCatToNumericXaxis(opts, cats) {
      opts.xaxis.type = "numeric";
      opts.xaxis.labels = opts.xaxis.labels || {};
      opts.xaxis.labels.formatter = opts.xaxis.labels.formatter || /**
       * @param {any} val
       */
      function(val) {
        return Utils$1.isNumber(val) ? Math.floor(val) : val;
      };
      const defaultFormatter = opts.xaxis.labels.formatter;
      let labels = opts.xaxis.categories && opts.xaxis.categories.length ? opts.xaxis.categories : opts.labels;
      if (cats && cats.length) {
        labels = cats.map((c) => {
          return Array.isArray(c) ? c : String(c);
        });
      }
      if (labels && labels.length) {
        opts.xaxis.labels.formatter = function(val) {
          return Utils$1.isNumber(val) ? defaultFormatter(labels[Math.floor(val) - 1]) : defaultFormatter(val);
        };
      }
      opts.xaxis.categories = [];
      opts.labels = [];
      opts.xaxis.tickAmount = opts.xaxis.tickAmount || "dataPoints";
      return opts;
    }
    bubble() {
      return {
        dataLabels: {
          style: {
            colors: ["#fff"]
          }
        },
        tooltip: {
          shared: false,
          intersect: true
        },
        xaxis: {
          crosshairs: {
            width: 0
          }
        },
        fill: {
          type: "solid",
          gradient: {
            shade: "light",
            inverse: true,
            shadeIntensity: 0.55,
            opacityFrom: 0.4,
            opacityTo: 0.8
          }
        }
      };
    }
    scatter() {
      return {
        dataLabels: {
          enabled: false
        },
        tooltip: {
          shared: false,
          intersect: true
        },
        markers: {
          size: 6,
          strokeWidth: 1,
          hover: {
            sizeOffset: 2
          }
        }
      };
    }
    heatmap() {
      return {
        chart: {
          stacked: false
        },
        fill: {
          opacity: 1
        },
        dataLabels: {
          style: {
            colors: ["#fff"]
          }
        },
        stroke: {
          colors: ["#fff"]
        },
        tooltip: {
          followCursor: true,
          marker: {
            show: false
          },
          x: {
            show: false
          }
        },
        legend: {
          position: "top",
          markers: {
            shape: "square"
          }
        },
        grid: {
          padding: {
            right: 20
          }
        }
      };
    }
    treemap() {
      return {
        chart: {
          zoom: {
            enabled: false
          }
        },
        dataLabels: {
          style: {
            fontSize: 14,
            fontWeight: 600,
            colors: ["#fff"]
          }
        },
        stroke: {
          show: true,
          width: 2,
          colors: ["#fff"]
        },
        legend: {
          show: false
        },
        fill: {
          opacity: 1,
          gradient: {
            stops: [0, 100]
          }
        },
        tooltip: {
          followCursor: true,
          x: {
            show: false
          }
        },
        grid: {
          padding: {
            left: 0,
            right: 0
          }
        },
        xaxis: {
          crosshairs: {
            show: false
          },
          tooltip: {
            enabled: false
          }
        }
      };
    }
    pie() {
      return {
        chart: {
          toolbar: {
            show: false
          }
        },
        plotOptions: {
          pie: {
            donut: {
              labels: {
                show: false
              }
            }
          }
        },
        dataLabels: {
          /**
           * @param {number} val
           */
          formatter(val) {
            return val.toFixed(1) + "%";
          },
          style: {
            colors: ["#fff"]
          },
          background: {
            enabled: false
          },
          dropShadow: {
            enabled: true
          }
        },
        stroke: {
          colors: ["#fff"]
        },
        fill: {
          opacity: 1,
          gradient: {
            shade: "light",
            stops: [0, 100]
          }
        },
        tooltip: {
          theme: "dark",
          fillSeriesColor: true
        },
        legend: {
          position: "right"
        },
        grid: {
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0
          }
        }
      };
    }
    donut() {
      return {
        chart: {
          toolbar: {
            show: false
          }
        },
        dataLabels: {
          /**
           * @param {number} val
           */
          formatter(val) {
            return val.toFixed(1) + "%";
          },
          style: {
            colors: ["#fff"]
          },
          background: {
            enabled: false
          },
          dropShadow: {
            enabled: true
          }
        },
        stroke: {
          colors: ["#fff"]
        },
        fill: {
          opacity: 1,
          gradient: {
            shade: "light",
            shadeIntensity: 0.35,
            stops: [80, 100],
            opacityFrom: 1,
            opacityTo: 1
          }
        },
        tooltip: {
          theme: "dark",
          fillSeriesColor: true
        },
        legend: {
          position: "right"
        },
        grid: {
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0
          }
        }
      };
    }
    polarArea() {
      return {
        chart: {
          toolbar: {
            show: false
          }
        },
        dataLabels: {
          /**
           * @param {number} val
           */
          formatter(val) {
            return val.toFixed(1) + "%";
          },
          enabled: false
        },
        stroke: {
          show: true,
          width: 2
        },
        fill: {
          opacity: 0.7
        },
        tooltip: {
          theme: "dark",
          fillSeriesColor: true
        },
        legend: {
          position: "right"
        },
        grid: {
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0
          }
        }
      };
    }
    radar() {
      this.opts.yaxis[0].labels.offsetY = this.opts.yaxis[0].labels.offsetY ? this.opts.yaxis[0].labels.offsetY : 6;
      return {
        dataLabels: {
          enabled: false,
          style: {
            fontSize: "11px"
          }
        },
        stroke: {
          width: 2
        },
        markers: {
          size: 5,
          strokeWidth: 1,
          strokeOpacity: 1
        },
        fill: {
          opacity: 0.2
        },
        tooltip: {
          shared: false,
          intersect: true,
          followCursor: true
        },
        grid: {
          show: false,
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0
          }
        },
        xaxis: {
          labels: {
            formatter: (val) => val,
            style: {
              colors: ["#a8a8a8"],
              fontSize: "11px"
            }
          },
          tooltip: {
            enabled: false
          },
          crosshairs: {
            show: false
          }
        }
      };
    }
    radialBar() {
      return {
        chart: {
          animations: {
            dynamicAnimation: {
              enabled: true,
              speed: 800
            }
          },
          toolbar: {
            show: false
          }
        },
        fill: {
          gradient: {
            shade: "dark",
            shadeIntensity: 0.4,
            inverseColors: false,
            type: "diagonal2",
            opacityFrom: 1,
            opacityTo: 1,
            stops: [70, 98, 100]
          }
        },
        legend: {
          show: false,
          position: "right"
        },
        tooltip: {
          enabled: false,
          fillSeriesColor: true
        },
        grid: {
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0
          }
        }
      };
    }
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {number} seriesIndex
     * @param {number} dataPointIndex
     * @param {any[]} labels
     * @param {string} chartType
     */
    _getBoxTooltip(w, seriesIndex, dataPointIndex, labels, chartType) {
      const o = w.candleData.seriesCandleO[seriesIndex][dataPointIndex];
      const h = w.candleData.seriesCandleH[seriesIndex][dataPointIndex];
      const m = w.candleData.seriesCandleM[seriesIndex][dataPointIndex];
      const l = w.candleData.seriesCandleL[seriesIndex][dataPointIndex];
      const c = w.candleData.seriesCandleC[seriesIndex][dataPointIndex];
      const _si = (
        /** @type {Record<string,any>} */
        w.config.series[seriesIndex]
      );
      if (_si.type && _si.type !== chartType) {
        return `<div class="apexcharts-custom-tooltip">
          ${_si.name ? _si.name : "series-" + (seriesIndex + 1)}: <strong>${w.seriesData.series[seriesIndex][dataPointIndex]}</strong>
        </div>`;
      } else {
        return `<div class="apexcharts-tooltip-box apexcharts-tooltip-${w.config.chart.type}"><div>${labels[0]}: <span class="value">` + o + `</span></div><div>${labels[1]}: <span class="value">` + h + "</span></div>" + (m ? `<div>${labels[2]}: <span class="value">` + m + "</span></div>" : "") + `<div>${labels[3]}: <span class="value">` + l + `</span></div><div>${labels[4]}: <span class="value">` + c + "</span></div></div>";
      }
    }
  }
  const name = "en";
  const options = { "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"], "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], "toolbar": { "exportToSVG": "Download SVG", "exportToPNG": "Download PNG", "exportToCSV": "Download CSV", "menu": "Menu", "selection": "Selection", "selectionZoom": "Selection Zoom", "zoomIn": "Zoom In", "zoomOut": "Zoom Out", "pan": "Panning", "reset": "Reset Zoom" } };
  const en = {
    name,
    options
  };
  class Options {
    constructor() {
      this.yAxis = {
        show: true,
        showAlways: false,
        showForNullSeries: true,
        seriesName: void 0,
        opposite: false,
        reversed: false,
        logarithmic: false,
        logBase: 10,
        tickAmount: void 0,
        stepSize: void 0,
        forceNiceScale: false,
        max: void 0,
        min: void 0,
        floating: false,
        decimalsInFloat: void 0,
        labels: {
          show: true,
          showDuplicates: false,
          minWidth: 0,
          maxWidth: 160,
          offsetX: 0,
          offsetY: 0,
          align: void 0,
          rotate: 0,
          padding: 20,
          style: {
            colors: [],
            fontSize: "11px",
            fontWeight: 400,
            fontFamily: void 0,
            cssClass: ""
          },
          formatter: void 0
        },
        axisBorder: {
          show: false,
          color: "#e0e0e0",
          width: 1,
          offsetX: 0,
          offsetY: 0
        },
        axisTicks: {
          show: false,
          color: "#e0e0e0",
          width: 6,
          offsetX: 0,
          offsetY: 0
        },
        title: {
          text: void 0,
          rotate: -90,
          offsetY: 0,
          offsetX: 0,
          style: {
            color: void 0,
            fontSize: "11px",
            fontWeight: 900,
            fontFamily: void 0,
            cssClass: ""
          }
        },
        tooltip: {
          enabled: false,
          offsetX: 0
        },
        crosshairs: {
          show: true,
          position: "front",
          stroke: {
            color: "#b6b6b6",
            width: 1,
            dashArray: 0
          }
        }
      };
      this.pointAnnotation = {
        id: void 0,
        x: 0,
        y: null,
        yAxisIndex: 0,
        seriesIndex: void 0,
        mouseEnter: void 0,
        mouseLeave: void 0,
        click: void 0,
        marker: {
          size: 4,
          fillColor: "#fff",
          strokeWidth: 2,
          strokeColor: "#333",
          shape: "circle",
          offsetX: 0,
          offsetY: 0,
          // radius: 2, // DEPRECATED
          cssClass: ""
        },
        label: {
          borderColor: "#c2c2c2",
          borderWidth: 1,
          borderRadius: 2,
          text: void 0,
          textAnchor: "middle",
          offsetX: 0,
          offsetY: 0,
          mouseEnter: void 0,
          mouseLeave: void 0,
          click: void 0,
          style: {
            background: "#fff",
            color: void 0,
            fontSize: "11px",
            fontFamily: void 0,
            fontWeight: 400,
            cssClass: "",
            padding: {
              left: 5,
              right: 5,
              top: 2,
              bottom: 2
            }
          }
        },
        customSVG: {
          // this will be deprecated in the next major version as it is going to be replaced with a better alternative below (image)
          SVG: void 0,
          cssClass: void 0,
          offsetX: 0,
          offsetY: 0
        },
        image: {
          path: void 0,
          width: 20,
          height: 20,
          offsetX: 0,
          offsetY: 0
        }
      };
      this.yAxisAnnotation = {
        id: void 0,
        y: 0,
        y2: null,
        strokeDashArray: 1,
        fillColor: "#c2c2c2",
        borderColor: "#c2c2c2",
        borderWidth: 1,
        opacity: 0.3,
        offsetX: 0,
        offsetY: 0,
        width: "100%",
        yAxisIndex: 0,
        label: {
          borderColor: "#c2c2c2",
          borderWidth: 1,
          borderRadius: 2,
          text: void 0,
          textAnchor: "end",
          position: "right",
          offsetX: 0,
          offsetY: -3,
          mouseEnter: void 0,
          mouseLeave: void 0,
          click: void 0,
          style: {
            background: "#fff",
            color: void 0,
            fontSize: "11px",
            fontFamily: void 0,
            fontWeight: 400,
            cssClass: "",
            padding: {
              left: 5,
              right: 5,
              top: 2,
              bottom: 2
            }
          }
        }
      };
      this.xAxisAnnotation = {
        id: void 0,
        x: 0,
        x2: null,
        strokeDashArray: 1,
        fillColor: "#c2c2c2",
        borderColor: "#c2c2c2",
        borderWidth: 1,
        opacity: 0.3,
        offsetX: 0,
        offsetY: 0,
        label: {
          borderColor: "#c2c2c2",
          borderWidth: 1,
          borderRadius: 2,
          text: void 0,
          textAnchor: "middle",
          orientation: "vertical",
          position: "top",
          offsetX: 0,
          offsetY: 0,
          mouseEnter: void 0,
          mouseLeave: void 0,
          click: void 0,
          style: {
            background: "#fff",
            color: void 0,
            fontSize: "11px",
            fontFamily: void 0,
            fontWeight: 400,
            cssClass: "",
            padding: {
              left: 5,
              right: 5,
              top: 2,
              bottom: 2
            }
          }
        }
      };
      this.text = {
        x: 0,
        y: 0,
        text: "",
        textAnchor: "start",
        foreColor: void 0,
        fontSize: "13px",
        fontFamily: void 0,
        fontWeight: 400,
        appendTo: ".apexcharts-annotations",
        backgroundColor: "transparent",
        borderColor: "#c2c2c2",
        borderRadius: 0,
        borderWidth: 0,
        paddingLeft: 4,
        paddingRight: 4,
        paddingTop: 2,
        paddingBottom: 2
      };
    }
    init() {
      return {
        annotations: {
          yaxis: [this.yAxisAnnotation],
          xaxis: [this.xAxisAnnotation],
          points: [this.pointAnnotation],
          texts: [],
          images: [],
          shapes: []
        },
        chart: {
          animations: {
            enabled: true,
            speed: 800,
            animateGradually: {
              delay: 150,
              enabled: true
            },
            dynamicAnimation: {
              enabled: true,
              speed: 350
            }
          },
          background: "",
          locales: [en],
          defaultLocale: "en",
          dropShadow: {
            enabled: false,
            enabledOnSeries: void 0,
            top: 2,
            left: 2,
            blur: 4,
            color: "#000",
            opacity: 0.7
          },
          events: {
            animationEnd: void 0,
            beforeMount: void 0,
            mounted: void 0,
            updated: void 0,
            click: void 0,
            mouseMove: void 0,
            mouseLeave: void 0,
            xAxisLabelClick: void 0,
            legendClick: void 0,
            markerClick: void 0,
            selection: void 0,
            dataPointSelection: void 0,
            dataPointMouseEnter: void 0,
            dataPointMouseLeave: void 0,
            beforeZoom: void 0,
            beforeResetZoom: void 0,
            zoomed: void 0,
            scrolled: void 0,
            brushScrolled: void 0,
            keyDown: void 0,
            keyUp: void 0
          },
          foreColor: "#373d3f",
          fontFamily: "Helvetica, Arial, sans-serif",
          height: "auto",
          parentHeightOffset: 15,
          redrawOnParentResize: true,
          redrawOnWindowResize: true,
          id: void 0,
          group: void 0,
          nonce: void 0,
          offsetX: 0,
          offsetY: 0,
          injectStyleSheet: true,
          selection: {
            enabled: false,
            type: "x",
            // selectedPoints: undefined, // default datapoints that should be selected automatically
            fill: {
              color: "#24292e",
              opacity: 0.1
            },
            stroke: {
              width: 1,
              color: "#24292e",
              opacity: 0.4,
              dashArray: 3
            },
            xaxis: {
              min: void 0,
              max: void 0
            },
            yaxis: {
              min: void 0,
              max: void 0
            }
          },
          sparkline: {
            enabled: false
          },
          brush: {
            enabled: false,
            autoScaleYaxis: true,
            target: void 0,
            targets: void 0
          },
          stacked: false,
          stackOnlyBar: true,
          // mixed chart with stacked bars and line series - incorrect line draw #907
          stackType: "normal",
          toolbar: {
            show: true,
            offsetX: 0,
            offsetY: 0,
            tools: {
              download: true,
              selection: true,
              zoom: true,
              zoomin: true,
              zoomout: true,
              pan: true,
              reset: true,
              customIcons: []
            },
            export: {
              csv: {
                filename: void 0,
                columnDelimiter: ",",
                headerCategory: "category",
                headerValue: "value",
                categoryFormatter: void 0,
                valueFormatter: void 0
              },
              png: {
                filename: void 0
              },
              svg: {
                filename: void 0
              },
              scale: void 0,
              width: void 0
            },
            autoSelected: "zoom"
            // accepts -> zoom, pan, selection
          },
          type: "line",
          width: "100%",
          zoom: {
            enabled: true,
            type: "x",
            autoScaleYaxis: false,
            allowMouseWheelZoom: true,
            zoomedArea: {
              fill: {
                color: "#90CAF9",
                opacity: 0.4
              },
              stroke: {
                color: "#0D47A1",
                opacity: 0.4,
                width: 1
              }
            }
          },
          accessibility: {
            enabled: true,
            description: void 0,
            announcements: {
              enabled: true
            },
            keyboard: {
              enabled: true,
              navigation: {
                enabled: true,
                wrapAround: false
              }
            }
          },
          dataReducer: {
            enabled: false,
            algorithm: "lttb",
            targetPoints: 250,
            threshold: 500
          }
        },
        parsing: {
          x: void 0,
          y: void 0
        },
        plotOptions: {
          line: {
            isSlopeChart: false,
            colors: {
              threshold: 0,
              colorAboveThreshold: void 0,
              colorBelowThreshold: void 0
            }
          },
          area: {
            fillTo: "origin"
          },
          bar: {
            horizontal: false,
            columnWidth: "70%",
            // should be in percent 0 - 100
            barHeight: "70%",
            // should be in percent 0 - 100
            distributed: false,
            borderRadius: 0,
            borderRadiusApplication: "around",
            // [around, end]
            borderRadiusWhenStacked: "last",
            // [all, last]
            rangeBarOverlap: true,
            rangeBarGroupRows: false,
            hideZeroBarsWhenGrouped: false,
            isDumbbell: false,
            dumbbellColors: void 0,
            isFunnel: false,
            isFunnel3d: true,
            colors: {
              ranges: [],
              backgroundBarColors: [],
              backgroundBarOpacity: 1,
              backgroundBarRadius: 0
            },
            dataLabels: {
              position: "top",
              // top, center, bottom
              maxItems: 100,
              hideOverflowingLabels: true,
              orientation: "horizontal",
              total: {
                enabled: false,
                formatter: void 0,
                offsetX: 0,
                offsetY: 0,
                style: {
                  color: "#373d3f",
                  fontSize: "12px",
                  fontFamily: void 0,
                  fontWeight: 600
                }
              }
            }
          },
          bubble: {
            zScaling: true,
            minBubbleRadius: void 0,
            maxBubbleRadius: void 0
          },
          candlestick: {
            colors: {
              upward: "#00B746",
              downward: "#EF403C"
            },
            wick: {
              useFillColor: true
            }
          },
          boxPlot: {
            colors: {
              upper: "#00E396",
              lower: "#008FFB"
            }
          },
          heatmap: {
            radius: 2,
            enableShades: true,
            shadeIntensity: 0.5,
            reverseNegativeShade: false,
            distributed: false,
            useFillColorAsStroke: false,
            colorScale: {
              inverse: false,
              ranges: [],
              min: void 0,
              max: void 0
            }
          },
          treemap: {
            enableShades: true,
            shadeIntensity: 0.5,
            distributed: false,
            reverseNegativeShade: false,
            useFillColorAsStroke: false,
            borderRadius: 4,
            dataLabels: {
              format: "scale"
              // scale | truncate
            },
            colorScale: {
              inverse: false,
              ranges: [],
              min: void 0,
              max: void 0
            },
            seriesTitle: {
              show: true,
              offsetY: 1,
              offsetX: 1,
              borderColor: "#000",
              borderWidth: 1,
              borderRadius: 2,
              style: {
                background: "rgba(0, 0, 0, 0.6)",
                color: "#fff",
                fontSize: "12px",
                fontFamily: void 0,
                fontWeight: 400,
                cssClass: "",
                padding: {
                  left: 6,
                  right: 6,
                  top: 2,
                  bottom: 2
                }
              }
            }
          },
          radialBar: {
            inverseOrder: false,
            startAngle: 0,
            endAngle: 360,
            offsetX: 0,
            offsetY: 0,
            hollow: {
              margin: 5,
              size: "50%",
              background: "transparent",
              image: void 0,
              imageWidth: 150,
              imageHeight: 150,
              imageOffsetX: 0,
              imageOffsetY: 0,
              imageClipped: true,
              position: "front",
              dropShadow: {
                enabled: false,
                top: 0,
                left: 0,
                blur: 3,
                color: "#000",
                opacity: 0.5
              }
            },
            track: {
              show: true,
              startAngle: void 0,
              endAngle: void 0,
              background: "#f2f2f2",
              strokeWidth: "97%",
              opacity: 1,
              margin: 5,
              // margin is in pixels
              dropShadow: {
                enabled: false,
                top: 0,
                left: 0,
                blur: 3,
                color: "#000",
                opacity: 0.5
              }
            },
            dataLabels: {
              show: true,
              name: {
                show: true,
                fontSize: "16px",
                fontFamily: void 0,
                fontWeight: 600,
                color: void 0,
                offsetY: 0,
                /**
                 * @param {any} val
                 */
                formatter(val) {
                  return val;
                }
              },
              value: {
                show: true,
                fontSize: "14px",
                fontFamily: void 0,
                fontWeight: 400,
                color: void 0,
                offsetY: 16,
                /**
                 * @param {any} val
                 */
                formatter(val) {
                  return val + "%";
                }
              },
              total: {
                show: false,
                label: "Total",
                fontSize: "16px",
                fontWeight: 600,
                fontFamily: void 0,
                color: void 0,
                /**
                 * @param {import('../../types/internal').ChartStateW} w
                 */
                formatter(w) {
                  return (
                    /**
                     * @param {number} a
                     * @param {number} b
                     */
                    w.globals.seriesTotals.reduce((a, b) => a + b, 0) / w.seriesData.series.length + "%"
                  );
                }
              }
            },
            barLabels: {
              enabled: false,
              offsetX: 0,
              offsetY: 0,
              useSeriesColors: true,
              fontFamily: void 0,
              fontWeight: 600,
              fontSize: "16px",
              /**
               * @param {any} val
               */
              formatter(val) {
                return val;
              },
              onClick: void 0
            }
          },
          pie: {
            customScale: 1,
            offsetX: 0,
            offsetY: 0,
            startAngle: 0,
            endAngle: 360,
            expandOnClick: true,
            dataLabels: {
              // These are the percentage values which are displayed on slice
              offset: 0,
              // offset by which labels will move outside
              minAngleToShowLabel: 10
            },
            donut: {
              size: "65%",
              background: "transparent",
              labels: {
                // These are the inner labels appearing inside donut
                show: false,
                name: {
                  show: true,
                  fontSize: "16px",
                  fontFamily: void 0,
                  fontWeight: 600,
                  color: void 0,
                  offsetY: -10,
                  /**
                   * @param {any} val
                   */
                  formatter(val) {
                    return val;
                  }
                },
                value: {
                  show: true,
                  fontSize: "20px",
                  fontFamily: void 0,
                  fontWeight: 400,
                  color: void 0,
                  offsetY: 10,
                  /**
                   * @param {any} val
                   */
                  formatter(val) {
                    return val;
                  }
                },
                total: {
                  show: false,
                  showAlways: false,
                  label: "Total",
                  fontSize: "16px",
                  fontWeight: 400,
                  fontFamily: void 0,
                  color: void 0,
                  /**
                   * @param {import('../../types/internal').ChartStateW} w
                   */
                  formatter(w) {
                    return w.globals.seriesTotals.reduce((a, b) => a + b, 0);
                  }
                }
              }
            }
          },
          polarArea: {
            rings: {
              strokeWidth: 1,
              strokeColor: "#e8e8e8"
            },
            spokes: {
              strokeWidth: 1,
              connectorColors: "#e8e8e8"
            }
          },
          radar: {
            size: void 0,
            offsetX: 0,
            offsetY: 0,
            polygons: {
              // strokeColor: '#e8e8e8', // should be deprecated in the minor version i.e 3.2
              strokeWidth: 1,
              strokeColors: "#e8e8e8",
              connectorColors: "#e8e8e8",
              fill: {
                colors: void 0
              }
            }
          }
        },
        colors: void 0,
        dataLabels: {
          enabled: true,
          enabledOnSeries: void 0,
          /**
           * @param {any} val
           */
          formatter(val) {
            return val !== null ? val : "";
          },
          textAnchor: "middle",
          distributed: false,
          offsetX: 0,
          offsetY: 0,
          style: {
            fontSize: "12px",
            fontFamily: void 0,
            fontWeight: 600,
            colors: void 0
          },
          background: {
            enabled: true,
            foreColor: "#fff",
            backgroundColor: void 0,
            borderRadius: 2,
            padding: 4,
            opacity: 0.9,
            borderWidth: 1,
            borderColor: "#fff",
            dropShadow: {
              enabled: false,
              top: 1,
              left: 1,
              blur: 1,
              color: "#000",
              opacity: 0.8
            }
          },
          dropShadow: {
            enabled: false,
            top: 1,
            left: 1,
            blur: 1,
            color: "#000",
            opacity: 0.8
          }
        },
        fill: {
          type: "solid",
          colors: void 0,
          // array of colors
          opacity: 0.85,
          gradient: {
            shade: "dark",
            type: "horizontal",
            shadeIntensity: 0.5,
            gradientToColors: void 0,
            inverseColors: true,
            opacityFrom: 1,
            opacityTo: 1,
            stops: [0, 50, 100],
            colorStops: []
          },
          image: {
            src: [],
            width: void 0,
            // optional
            height: void 0
            // optional
          },
          pattern: {
            style: "squares",
            // String | Array of Strings
            width: 6,
            height: 6,
            strokeWidth: 2
          }
        },
        forecastDataPoints: {
          count: 0,
          fillOpacity: 0.5,
          strokeWidth: void 0,
          dashArray: 4
        },
        grid: {
          show: true,
          borderColor: "#e0e0e0",
          strokeDashArray: 0,
          position: "back",
          xaxis: {
            lines: {
              show: false
            }
          },
          yaxis: {
            lines: {
              show: true
            }
          },
          row: {
            colors: void 0,
            // takes as array which will be repeated on rows
            opacity: 0.5
          },
          column: {
            colors: void 0,
            // takes an array which will be repeated on columns
            opacity: 0.5
          },
          padding: {
            top: 0,
            right: 10,
            bottom: 0,
            left: 12
          }
        },
        labels: [],
        legend: {
          show: true,
          showForSingleSeries: false,
          showForNullSeries: true,
          showForZeroSeries: true,
          floating: false,
          position: "bottom",
          // whether to position legends in 1 of 4
          // direction - top, bottom, left, right
          horizontalAlign: "center",
          // when position top/bottom, you can specify whether to align legends left, right or center
          inverseOrder: false,
          fontSize: "12px",
          fontFamily: void 0,
          fontWeight: 400,
          width: void 0,
          height: void 0,
          formatter: void 0,
          tooltipHoverFormatter: void 0,
          offsetX: -20,
          offsetY: 4,
          customLegendItems: [],
          clusterGroupedSeries: true,
          clusterGroupedSeriesOrientation: "vertical",
          labels: {
            colors: void 0,
            useSeriesColors: false
          },
          markers: {
            size: 7,
            fillColors: void 0,
            strokeWidth: 1,
            shape: void 0,
            offsetX: 0,
            offsetY: 0,
            customHTML: void 0,
            onClick: void 0
          },
          itemMargin: {
            horizontal: 5,
            vertical: 4
          },
          onItemClick: {
            toggleDataSeries: true
          },
          onItemHover: {
            highlightDataSeries: true
          }
        },
        markers: {
          discrete: [],
          size: 0,
          colors: void 0,
          strokeColors: "#fff",
          strokeWidth: 2,
          strokeOpacity: 0.9,
          strokeDashArray: 0,
          fillOpacity: 1,
          shape: "circle",
          offsetX: 0,
          offsetY: 0,
          showNullDataPoints: true,
          onClick: void 0,
          onDblClick: void 0,
          hover: {
            size: void 0,
            sizeOffset: 3
          }
        },
        noData: {
          text: void 0,
          align: "center",
          verticalAlign: "middle",
          offsetX: 0,
          offsetY: 0,
          style: {
            color: void 0,
            fontSize: "14px",
            fontFamily: void 0
          }
        },
        responsive: [],
        // breakpoints should follow ascending order 400, then 700, then 1000
        series: void 0,
        states: {
          hover: {
            filter: {
              type: "lighten"
            }
          },
          active: {
            allowMultipleDataPointsSelection: false,
            filter: {
              type: "darken"
            }
          }
        },
        title: {
          text: void 0,
          align: "left",
          margin: 5,
          offsetX: 0,
          offsetY: 0,
          floating: false,
          style: {
            fontSize: "14px",
            fontWeight: 900,
            fontFamily: void 0,
            color: void 0
          }
        },
        subtitle: {
          text: void 0,
          align: "left",
          margin: 5,
          offsetX: 0,
          offsetY: 30,
          floating: false,
          style: {
            fontSize: "12px",
            fontWeight: 400,
            fontFamily: void 0,
            color: void 0
          }
        },
        stroke: {
          show: true,
          curve: "smooth",
          // "smooth" / "straight" / "monotoneCubic" / "stepline" / "linestep"
          lineCap: "butt",
          // round, butt , square
          width: 2,
          colors: void 0,
          // array of colors
          dashArray: 0,
          // single value or array of values
          fill: {
            type: "solid",
            colors: void 0,
            // array of colors
            opacity: 0.85,
            gradient: {
              shade: "dark",
              type: "horizontal",
              shadeIntensity: 0.5,
              gradientToColors: void 0,
              inverseColors: true,
              opacityFrom: 1,
              opacityTo: 1,
              stops: [0, 50, 100],
              colorStops: []
            }
          }
        },
        tooltip: {
          enabled: true,
          enabledOnSeries: void 0,
          shared: true,
          hideEmptySeries: false,
          followCursor: false,
          // when disabled, the tooltip will show on top of the series instead of mouse position
          intersect: false,
          // when enabled, tooltip will only show when user directly hovers over point
          inverseOrder: false,
          custom: void 0,
          fillSeriesColor: false,
          theme: "light",
          cssClass: "",
          style: {
            fontSize: "12px",
            fontFamily: void 0
          },
          onDatasetHover: {
            highlightDataSeries: false
          },
          x: {
            // x value
            show: true,
            format: "dd MMM",
            // dd/MM, dd MMM yy, dd MMM yyyy
            formatter: void 0
            // a custom user supplied formatter function
          },
          y: {
            formatter: void 0,
            title: {
              /**
               * @param {string} seriesName
               */
              formatter(seriesName) {
                return seriesName ? seriesName + ": " : "";
              }
            }
          },
          z: {
            formatter: void 0,
            title: "Size: "
          },
          marker: {
            show: true,
            fillColors: void 0
          },
          items: {
            display: "flex"
          },
          fixed: {
            enabled: false,
            position: "topRight",
            // topRight, topLeft, bottomRight, bottomLeft
            offsetX: 0,
            offsetY: 0
          }
        },
        xaxis: {
          type: "category",
          categories: [],
          convertedCatToNumeric: false,
          // internal property which should not be altered outside
          offsetX: 0,
          offsetY: 0,
          overwriteCategories: void 0,
          labels: {
            show: true,
            rotate: -45,
            rotateAlways: false,
            hideOverlappingLabels: true,
            trim: false,
            minHeight: void 0,
            maxHeight: 120,
            showDuplicates: true,
            style: {
              colors: [],
              fontSize: "12px",
              fontWeight: 400,
              fontFamily: void 0,
              cssClass: ""
            },
            offsetX: 0,
            offsetY: 0,
            format: void 0,
            formatter: void 0,
            // custom formatter function which will override format
            datetimeUTC: true,
            datetimeFormatter: {
              year: "yyyy",
              month: "MMM 'yy",
              day: "dd MMM",
              hour: "HH:mm",
              minute: "HH:mm:ss",
              second: "HH:mm:ss"
            }
          },
          group: {
            groups: [],
            style: {
              colors: [],
              fontSize: "12px",
              fontWeight: 400,
              fontFamily: void 0,
              cssClass: ""
            }
          },
          axisBorder: {
            show: true,
            color: "#e0e0e0",
            width: "100%",
            height: 1,
            offsetX: 0,
            offsetY: 0
          },
          axisTicks: {
            show: true,
            color: "#e0e0e0",
            height: 6,
            offsetX: 0,
            offsetY: 0
          },
          stepSize: void 0,
          tickAmount: void 0,
          tickPlacement: "on",
          min: void 0,
          max: void 0,
          range: void 0,
          floating: false,
          decimalsInFloat: void 0,
          position: "bottom",
          title: {
            text: void 0,
            offsetX: 0,
            offsetY: 0,
            style: {
              color: void 0,
              fontSize: "12px",
              fontWeight: 900,
              fontFamily: void 0,
              cssClass: ""
            }
          },
          crosshairs: {
            show: true,
            width: 1,
            // tickWidth/barWidth or an integer
            position: "back",
            opacity: 0.9,
            stroke: {
              color: "#b6b6b6",
              width: 1,
              dashArray: 3
            },
            fill: {
              type: "solid",
              // solid, gradient
              color: "#B1B9C4",
              gradient: {
                colorFrom: "#D8E3F0",
                colorTo: "#BED1E6",
                stops: [0, 100],
                opacityFrom: 0.4,
                opacityTo: 0.5
              }
            },
            dropShadow: {
              enabled: false,
              left: 0,
              top: 0,
              blur: 1,
              opacity: 0.8
            }
          },
          tooltip: {
            enabled: true,
            offsetY: 0,
            formatter: void 0,
            style: {
              fontSize: "12px",
              fontFamily: void 0
            }
          }
        },
        yaxis: this.yAxis,
        theme: {
          mode: "",
          palette: "palette1",
          // If defined, it will overwrite globals.colors variable
          monochrome: {
            // monochrome allows you to select just 1 color and fill out the rest with light/dark shade (intensity can be selected)
            enabled: false,
            color: "#008FFB",
            shadeTo: "light",
            shadeIntensity: 0.65
          },
          accessibility: {
            colorBlindMode: ""
            // '' | 'deuteranopia' | 'protanopia' | 'tritanopia' | 'highContrast'
          }
        }
      };
    }
  }
  class Config {
    /**
     * @param {Record<string, any>} opts
     */
    constructor(opts) {
      this.opts = opts;
    }
    /** @param {{responsiveOverride: any}} opts */
    init({ responsiveOverride }) {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
      let opts = this.opts;
      const options2 = new Options();
      const defaults = new Defaults(opts);
      this.chartType = opts.chart.type;
      opts = this.extendYAxis(opts);
      opts = this.extendAnnotations(opts);
      let config = options2.init();
      let newDefaults = {};
      if (opts && typeof opts === "object") {
        let chartDefaults = {};
        const chartTypes = [
          "line",
          "area",
          "bar",
          "candlestick",
          "boxPlot",
          "rangeBar",
          "rangeArea",
          "bubble",
          "scatter",
          "heatmap",
          "treemap",
          "pie",
          "polarArea",
          "donut",
          "radar",
          "radialBar"
        ];
        if (chartTypes.indexOf(opts.chart.type) !== -1) {
          chartDefaults = /** @type {any} */
          defaults[opts.chart.type]();
        } else {
          chartDefaults = defaults.line();
        }
        if ((_b = (_a = opts.plotOptions) == null ? void 0 : _a.bar) == null ? void 0 : _b.isFunnel) {
          chartDefaults = defaults.funnel();
        }
        if (opts.chart.stacked && opts.chart.type === "bar") {
          chartDefaults = defaults.stackedBars();
        }
        if ((_c = opts.chart.brush) == null ? void 0 : _c.enabled) {
          chartDefaults = defaults.brush(chartDefaults);
        }
        if ((_e = (_d = opts.plotOptions) == null ? void 0 : _d.line) == null ? void 0 : _e.isSlopeChart) {
          chartDefaults = defaults.slope();
        }
        if (opts.chart.stacked && opts.chart.stackType === "100%") {
          opts = defaults.stacked100(opts);
        }
        if ((_g = (_f = opts.plotOptions) == null ? void 0 : _f.bar) == null ? void 0 : _g.isDumbbell) {
          opts = defaults.dumbbell(opts);
        }
        this.checkForDarkTheme(Environment.getApex());
        this.checkForDarkTheme(opts);
        opts.xaxis = opts.xaxis || Environment.getApex().xaxis || {};
        if (!responsiveOverride) {
          opts.xaxis.convertedCatToNumeric = false;
        }
        opts = this.checkForCatToNumericXAxis(this.chartType, chartDefaults, opts);
        if (((_h = opts.chart.sparkline) == null ? void 0 : _h.enabled) || ((_j = (_i = Environment.getApex().chart) == null ? void 0 : _i.sparkline) == null ? void 0 : _j.enabled)) {
          chartDefaults = defaults.sparkline(chartDefaults);
        }
        newDefaults = Utils$1.extend(config, chartDefaults);
      }
      const mergedWithDefaultConfig = Utils$1.extend(
        newDefaults,
        Environment.getApex()
      );
      config = Utils$1.extend(mergedWithDefaultConfig, opts);
      config = this.handleUserInputErrors(config);
      return config;
    }
    /**
     * @param {string} chartType
     * @param {Record<string, any>} chartDefaults
     * @param {Record<string, any>} opts
     */
    checkForCatToNumericXAxis(chartType, chartDefaults, opts) {
      var _a, _b;
      const defaults = new Defaults(opts);
      const isBarHorizontal = (chartType === "bar" || chartType === "boxPlot") && ((_b = (_a = opts.plotOptions) == null ? void 0 : _a.bar) == null ? void 0 : _b.horizontal);
      const unsupportedZoom = chartType === "pie" || chartType === "polarArea" || chartType === "donut" || chartType === "radar" || chartType === "radialBar" || chartType === "heatmap";
      const notNumericXAxis = opts.xaxis.type !== "datetime" && opts.xaxis.type !== "numeric";
      const tickPlacement = opts.xaxis.tickPlacement ? opts.xaxis.tickPlacement : chartDefaults.xaxis && chartDefaults.xaxis.tickPlacement;
      if (!isBarHorizontal && !unsupportedZoom && notNumericXAxis && tickPlacement !== "between") {
        opts = defaults.convertCatToNumeric(opts);
      }
      return opts;
    }
    /**
     * @param {Record<string, any>} opts
     * @param {import('../../types/internal').ChartStateW} [w]
     */
    extendYAxis(opts, w) {
      const options2 = new Options();
      if (typeof opts.yaxis === "undefined" || !opts.yaxis || Array.isArray(opts.yaxis) && opts.yaxis.length === 0) {
        opts.yaxis = {};
      }
      const globalApex = Environment.getApex();
      if (opts.yaxis.constructor !== Array && globalApex.yaxis && globalApex.yaxis.constructor !== Array) {
        opts.yaxis = Utils$1.extend(opts.yaxis, globalApex.yaxis);
      }
      if (opts.yaxis.constructor !== Array) {
        opts.yaxis = [Utils$1.extend(options2.yAxis, opts.yaxis)];
      } else {
        opts.yaxis = Utils$1.extendArray(opts.yaxis, options2.yAxis);
      }
      let isLogY = false;
      opts.yaxis.forEach((y) => {
        if (y.logarithmic) {
          isLogY = true;
        }
      });
      let series = opts.series;
      if (w && !series) {
        series = w.config.series;
      }
      if (isLogY && series.length !== opts.yaxis.length && series.length) {
        opts.yaxis = series.map((s, i) => {
          if (!s.name) {
            series[i].name = `series-${i + 1}`;
          }
          if (opts.yaxis[i]) {
            opts.yaxis[i].seriesName = series[i].name;
            return opts.yaxis[i];
          } else {
            const newYaxis = Utils$1.extend(options2.yAxis, opts.yaxis[0]);
            newYaxis.show = false;
            return newYaxis;
          }
        });
      }
      if (isLogY && series.length > 1 && series.length !== opts.yaxis.length) {
        console.warn(
          "A multi-series logarithmic chart should have equal number of series and y-axes"
        );
      }
      return opts;
    }
    // annotations also accepts array, so we need to extend them manually
    /**
     * @param {Record<string, any>} opts
     */
    extendAnnotations(opts) {
      if (typeof opts.annotations === "undefined") {
        opts.annotations = {};
        opts.annotations.yaxis = [];
        opts.annotations.xaxis = [];
        opts.annotations.points = [];
      }
      opts = this.extendYAxisAnnotations(opts);
      opts = this.extendXAxisAnnotations(opts);
      opts = this.extendPointAnnotations(opts);
      return opts;
    }
    /**
     * @param {Record<string, any>} opts
     */
    extendYAxisAnnotations(opts) {
      const options2 = new Options();
      opts.annotations.yaxis = Utils$1.extendArray(
        typeof opts.annotations.yaxis !== "undefined" ? opts.annotations.yaxis : [],
        options2.yAxisAnnotation
      );
      return opts;
    }
    /**
     * @param {Record<string, any>} opts
     */
    extendXAxisAnnotations(opts) {
      const options2 = new Options();
      opts.annotations.xaxis = Utils$1.extendArray(
        typeof opts.annotations.xaxis !== "undefined" ? opts.annotations.xaxis : [],
        options2.xAxisAnnotation
      );
      return opts;
    }
    /**
     * @param {Record<string, any>} opts
     */
    extendPointAnnotations(opts) {
      const options2 = new Options();
      opts.annotations.points = Utils$1.extendArray(
        typeof opts.annotations.points !== "undefined" ? opts.annotations.points : [],
        options2.pointAnnotation
      );
      return opts;
    }
    /**
     * @param {Record<string, any>} opts
     */
    checkForDarkTheme(opts) {
      if (opts.theme && opts.theme.mode === "dark") {
        if (!opts.tooltip) {
          opts.tooltip = {};
        }
        if (opts.tooltip.theme !== "light") {
          opts.tooltip.theme = "dark";
        }
        if (!opts.chart.foreColor) {
          opts.chart.foreColor = "#f6f7f8";
        }
        if (!opts.theme.palette) {
          opts.theme.palette = "palette4";
        }
      }
    }
    /**
     * @param {any} opts
     */
    handleUserInputErrors(opts) {
      const config = opts;
      if (config.tooltip.shared && config.tooltip.intersect) {
        throw new Error(
          "tooltip.shared cannot be enabled when tooltip.intersect is true. Turn off any other option by setting it to false."
        );
      }
      if (config.chart.type === "bar" && config.plotOptions.bar.horizontal) {
        if (config.yaxis.length > 1) {
          throw new Error(
            "Multiple Y Axis for bars are not supported. Switch to column chart by setting plotOptions.bar.horizontal=false"
          );
        }
        if (config.yaxis[0].reversed) {
          config.yaxis[0].opposite = true;
        }
        config.xaxis.tooltip.enabled = false;
        config.yaxis[0].tooltip.enabled = false;
        config.chart.zoom.enabled = false;
      }
      if (config.chart.type === "bar" || config.chart.type === "rangeBar") {
        if (config.tooltip.shared) {
          if (config.xaxis.crosshairs.width === "barWidth" && config.series.length > 1) {
            config.xaxis.crosshairs.width = "tickWidth";
          }
        }
      }
      if (config.chart.type === "candlestick" || config.chart.type === "boxPlot") {
        if (config.yaxis[0].reversed) {
          console.warn(
            `Reversed y-axis in ${config.chart.type} chart is not supported.`
          );
          config.yaxis[0].reversed = false;
        }
      }
      return config;
    }
  }
  const LINE_HEIGHT_RATIO = 1.618;
  const NICE_SCALE_ALLOWED_MAG_MSD = [
    [1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10],
    [1, 1, 2, 5, 5, 5, 10, 10, 10, 10, 10]
  ];
  const NICE_SCALE_DEFAULT_TICKS = [
    1,
    2,
    4,
    4,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    6,
    12,
    12,
    12,
    12,
    12,
    12,
    12,
    12,
    12,
    24
  ];
  class Globals {
    /**
     * @param {any} gl
     */
    initGlobalVars(gl) {
      gl.series = [];
      gl.seriesCandleO = [];
      gl.seriesCandleH = [];
      gl.seriesCandleM = [];
      gl.seriesCandleL = [];
      gl.seriesCandleC = [];
      gl.seriesRangeStart = [];
      gl.seriesRangeEnd = [];
      gl.seriesRange = [];
      gl.seriesPercent = [];
      gl.seriesGoals = [];
      gl.seriesX = [];
      gl.seriesZ = [];
      gl.seriesNames = [];
      gl.seriesTotals = [];
      gl.seriesLog = [];
      gl.seriesColors = [];
      gl.stackedSeriesTotals = [];
      gl.seriesXvalues = [];
      gl.seriesYvalues = [];
      gl.dataWasParsed = false;
      gl.originalSeries = null;
      gl.maxValsInArrayIndex = 0;
      gl.yValueDecimal = 0;
      gl.allSeriesHasEqualX = true;
      gl.labels = [];
      gl.hasXaxisGroups = false;
      gl.groups = [];
      gl.barGroups = [];
      gl.lineGroups = [];
      gl.areaGroups = [];
      gl.hasSeriesGroups = false;
      gl.seriesGroups = [];
      gl.categoryLabels = [];
      gl.timescaleLabels = [];
      gl.noLabelsProvided = false;
      gl.isXNumeric = false;
      gl.skipLastTimelinelabel = false;
      gl.skipFirstTimelinelabel = false;
      gl.isDataXYZ = false;
      gl.isMultiLineX = false;
      gl.isMultipleYAxis = false;
      gl.maxY = -Number.MAX_VALUE;
      gl.minY = Number.MIN_VALUE;
      gl.minYArr = [];
      gl.maxYArr = [];
      gl.maxX = -Number.MAX_VALUE;
      gl.minX = Number.MAX_VALUE;
      gl.initialMaxX = -Number.MAX_VALUE;
      gl.initialMinX = Number.MAX_VALUE;
      gl.maxDate = 0;
      gl.minDate = Number.MAX_VALUE;
      gl.minZ = Number.MAX_VALUE;
      gl.maxZ = -Number.MAX_VALUE;
      gl.minXDiff = Number.MAX_VALUE;
      gl.yAxisScale = [];
      gl.xAxisScale = null;
      gl.xAxisTicksPositions = [];
      gl.xRange = 0;
      gl.yRange = [];
      gl.zRange = 0;
      gl.dataPoints = 0;
      gl.xTickAmount = 0;
      gl.multiAxisTickAmount = 0;
      gl.disableZoomIn = false;
      gl.disableZoomOut = false;
      gl.yLabelsCoords = [];
      gl.yTitleCoords = [];
      gl.barPadForNumericAxis = 0;
      gl.padHorizontal = 0;
      gl.rotateXLabels = false;
      gl.overlappingXLabels = false;
      gl.radialSize = 0;
      gl.barHeight = 0;
      gl.barWidth = 0;
      gl.animationEnded = false;
      gl.resizeTimer = null;
      gl.selectionResizeTimer = null;
      gl.lastWheelExecution = 0;
      gl.delayedElements = [];
      gl.pointsArray = [];
      gl.dataLabelsRects = [];
      gl.lastDrawnDataLabelsIndexes = [];
      gl.textRectsCache = /* @__PURE__ */ new Map();
      gl.domCache = /* @__PURE__ */ new Map();
      gl.dimensionCache = {};
      gl.cachedSelectors = {};
      if (!gl.seriesNS) {
        this._attachNamespaces(gl);
      }
    }
    /**
     * Attach domain-grouped namespace sub-objects onto gl.
     * Each sub-object is a plain object whose properties are defined as
     * getters/setters that read/write the canonical flat properties on gl.
     * This means there is exactly ONE storage location per value — no copies,
     * no sync needed.
     *
     * Namespaces:
     *   gl.series  — parsed series data and chart-type-specific arrays
     *   gl.axes    — axis bounds, scales, ranges, tick state
     *   gl.layout  — SVG/grid dimensions, translations, label sizes
     *   gl.cache   — DOM caches, timers, observers, drawing scratch space
     *
     * Note: interact state lives on w.interact (not gl) — see Base.js.
     * @param {any} gl
     */
    _attachNamespaces(gl) {
      const proxy = (ns, key, nsKey = key) => {
        Object.defineProperty(ns, nsKey, {
          get() {
            return gl[key];
          },
          set(v) {
            gl[key] = v;
          },
          enumerable: true,
          configurable: true
        });
      };
      const seriesNS = {};
      proxy(seriesNS, "series", "data");
      for (const key of [
        "seriesNames",
        "seriesX",
        "seriesZ",
        "seriesXvalues",
        "seriesYvalues",
        "seriesGoals",
        "seriesLog",
        "seriesColors",
        "seriesPercent",
        "seriesTotals",
        "stackedSeriesTotals",
        "seriesCandleO",
        "seriesCandleH",
        "seriesCandleM",
        "seriesCandleL",
        "seriesCandleC",
        "seriesRangeStart",
        "seriesRangeEnd",
        "seriesRange",
        "seriesYAxisMap",
        "seriesYAxisReverseMap",
        "seriesGroups",
        "barGroups",
        "lineGroups",
        "areaGroups",
        "originalSeries",
        "collapsedSeries",
        "collapsedSeriesIndices",
        "ancillaryCollapsedSeries",
        "ancillaryCollapsedSeriesIndices",
        "allSeriesCollapsed",
        "risingSeries",
        "previousPaths",
        "ignoreYAxisIndexes",
        "labels",
        "categoryLabels",
        "timescaleLabels",
        "groups"
      ]) {
        proxy(seriesNS, key);
      }
      Object.defineProperty(gl, "seriesNS", {
        value: seriesNS,
        writable: false,
        enumerable: false,
        configurable: true
      });
      const axesNS = {};
      for (const key of [
        "minX",
        "maxX",
        "initialMinX",
        "initialMaxX",
        "minY",
        "maxY",
        "minYArr",
        "maxYArr",
        "minZ",
        "maxZ",
        "minDate",
        "maxDate",
        "minXDiff",
        "xRange",
        "yRange",
        "zRange",
        "xAxisScale",
        "yAxisScale",
        "xAxisTicksPositions",
        "xTickAmount",
        "multiAxisTickAmount",
        "dataPoints",
        "maxValsInArrayIndex",
        "isXNumeric",
        "isMultipleYAxis",
        "isMultiLineX",
        "isDataXYZ",
        "dataFormatXNumeric",
        "allSeriesHasEqualX",
        "hasNullValues",
        "dataWasParsed",
        "hasXaxisGroups",
        "hasSeriesGroups",
        "skipFirstTimelinelabel",
        "skipLastTimelinelabel",
        "yValueDecimal",
        "invalidLogScale",
        "noLabelsProvided"
      ]) {
        proxy(axesNS, key);
      }
      Object.defineProperty(gl, "axes", {
        value: axesNS,
        writable: false,
        enumerable: false,
        configurable: true
      });
      const layoutNS = {};
      for (const key of [
        "svgWidth",
        "svgHeight",
        "gridWidth",
        "gridHeight",
        "translateX",
        "translateY",
        "translateXAxisX",
        "translateXAxisY",
        "translateYAxisX",
        "xAxisLabelsHeight",
        "xAxisGroupLabelsHeight",
        "xAxisLabelsWidth",
        "yAxisLabelsWidth",
        "yAxisWidths",
        "yLabelsCoords",
        "yTitleCoords",
        "padHorizontal",
        "barPadForNumericAxis",
        "rotateXLabels",
        "scaleX",
        "scaleY",
        "radialSize",
        "defaultLabels",
        "overlappingXLabels"
      ]) {
        proxy(layoutNS, key);
      }
      Object.defineProperty(gl, "layout", {
        value: layoutNS,
        writable: false,
        enumerable: false,
        configurable: true
      });
      const cacheNS = {};
      for (const key of [
        "domCache",
        "dimensionCache",
        "cachedSelectors",
        "textRectsCache",
        "pointsArray",
        "dataLabelsRects",
        "lastDrawnDataLabelsIndexes",
        "delayedElements",
        "resizeTimer",
        "selectionResizeTimer",
        "resizeObserver"
      ]) {
        proxy(cacheNS, key);
      }
      Object.defineProperty(gl, "cache", {
        value: cacheNS,
        writable: false,
        enumerable: false,
        configurable: true
      });
    }
    /**
     * Persistent chart state — set ONCE at chart construction and intentionally NOT
     * reset by initGlobalVars.  These values must survive updateSeries / re-render.
     *
     * Rule: if a value is recalculated fresh on every render it belongs in
     * initGlobalVars instead, not here.
     * @returns {import('../../types/internal').ChartGlobals}
     * @param {Record<string, any>} config
     */
    globalVars(config) {
      const globals = {
        // ── Identity (set once, never changes) ───────────────────────────────────
        chartID: null,
        // full chart ID: "apexcharts-<cuid>"
        cuid: null,
        // random suffix only
        // ── Event registry (accumulates listeners, never reset) ───────────────────
        events: {
          beforeMount: [],
          mounted: [],
          updated: [],
          clicked: [],
          selection: [],
          dataPointSelection: [],
          zoomed: [],
          scrolled: []
        },
        // ── Theme colors (set by Theme module after config merge) ─────────────────
        colors: [],
        fill: { colors: [] },
        stroke: { colors: [] },
        dataLabels: { style: { colors: [] } },
        radarPolygons: { fill: { colors: [] } },
        markers: {
          colors: [],
          size: config.markers.size,
          largestSize: 0
        },
        // ── Device / environment detected once at startup ─────────────────────────
        // Note: isTouchDevice lives on w.interact — see Base.js. Shim installed there.
        LINE_HEIGHT_RATIO,
        // ── Chart-type flags (derived from config, set during Core.mount) ─────────
        axisCharts: true,
        // false for pie/radial/treemap etc.
        isSlopeChart: config.plotOptions.line.isSlopeChart,
        comboCharts: false,
        // true when mixing line + column series
        // ── Config snapshots (backups for zoom-reset / updateOptions) ────────────
        initialConfig: null,
        // deep clone of the original user config
        initialSeries: [],
        lastXAxis: [],
        lastYAxis: [],
        // ── User interaction state (must survive re-renders) ──────────────────────
        // Note: zoomEnabled, panEnabled, selectionEnabled, zoomed, selection,
        //       visibleXRange, selectedDataPoints, mousedown, clientX, clientY,
        //       lastClientPosition, lastWheelExecution, capturedSeriesIndex,
        //       capturedDataPointIndex, disableZoomIn, disableZoomOut, isTouchDevice
        //       live on w.interact — see Base.js. Backward-compat shims installed there.
        // Series collapse state (user-driven, must persist across re-renders)
        allSeriesCollapsed: false,
        collapsedSeries: [],
        collapsedSeriesIndices: [],
        ancillaryCollapsedSeries: [],
        ancillaryCollapsedSeriesIndices: [],
        risingSeries: [],
        // series being re-shown after collapse
        ignoreYAxisIndexes: [],
        // y-axis indices excluded during series collapse
        // ── Lifecycle / update flags ──────────────────────────────────────────────
        isDirty: false,
        // true when user called an update method manually
        isExecCalled: false,
        // true when update came via exec()
        dataChanged: false,
        // true when series data was changed dynamically
        resized: false,
        // true after a container resize
        // ── Data format flags (derived from config/series, stable between renders) ─
        // Note: dataFormatXNumeric lives on w.axisFlags — see Base.js. Shim installed there.
        invalidLogScale: false,
        // true when log scale requested but data is invalid
        hasNullValues: false,
        // true when any series contains null values
        // Persistent data tracking
        columnSeries: null,
        // tracks which series are rendered as bars/columns
        yaxis: null,
        // resolved yaxis config array
        total: 0,
        // running total (used by pie/radial)
        // ── Animation control ─────────────────────────────────────────────────────
        shouldAnimate: true,
        previousPaths: [],
        // paths from previous render — source for enter animation
        // ── SVG viewport (set by Dimensions, but persistent as layout anchor) ─────
        svgWidth: 0,
        svgHeight: 0,
        // Note: gridWidth, gridHeight, translateX, translateY, translateXAxisX,
        // translateXAxisY, xAxisLabelsHeight, xAxisGroupLabelsHeight, xAxisLabelsWidth,
        // rotateXLabels, xAxisHeight, yLabelsCoords, yTitleCoords live on w.layout —
        // see Base.js. Backward-compat shims installed there.
        defaultLabels: false,
        // Note: formatter properties (xLabelFormatter, yLabelFormatters, etc.) live on
        // w.formatters — see Base.js. Backward-compat shims installed there.
        yAxisLabelsWidth: 0,
        scaleX: 1,
        scaleY: 1,
        translateYAxisX: [],
        yAxisWidths: [],
        // ── Instances (created once, replaced only on full re-init) ──────────────
        tooltip: null,
        resizeObserver: null,
        // ── Locale (loaded once; changes only via setLocale()) ───────────────────
        locale: {},
        // ── Method queue (deferred calls during async operations) ────────────────
        memory: {
          methodsToExec: []
        },
        // ── Scale configuration constants — imported from utils/Constants.js ──────
        niceScaleAllowedMagMsd: NICE_SCALE_ALLOWED_MAG_MSD,
        niceScaleDefaultTicks: NICE_SCALE_DEFAULT_TICKS,
        // ── Multi-axis series mapping ─────────────────────────────────────────────
        seriesYAxisMap: [],
        // yAxis index → series indices[]
        seriesYAxisReverseMap: [],
        // series index → yAxis index
        noData: false
        // true when there is nothing to render
      };
      return (
        /** @type {import('../../types/internal').ChartGlobals} */
        /** @type {unknown} */
        globals
      );
    }
    /**
     * @param {Record<string, any>} config
     */
    init(config) {
      const globals = this.globalVars(config);
      this.initGlobalVars(globals);
      globals.initialConfig = Utils$1.extend({}, config);
      globals.initialSeries = Utils$1.clone(config.series);
      globals.lastXAxis = Utils$1.clone(
        /** @type {NonNullable<typeof globals.initialConfig>} */
        globals.initialConfig.xaxis
      );
      globals.lastYAxis = Utils$1.clone(
        /** @type {NonNullable<typeof globals.initialConfig>} */
        globals.initialConfig.yaxis
      );
      return globals;
    }
  }
  class Base {
    /**
     * @param {object} opts
     */
    constructor(opts) {
      this.opts = opts;
    }
    /**
     * Build and return the full chart state object `w`.
     * @returns {import('../types/internal').ChartStateW}
     */
    init() {
      const config = new Config(this.opts).init({ responsiveOverride: false });
      const globals = new Globals().init(config);
      const w = {
        config,
        globals,
        dom: {},
        // DOM node cache — lives here, not inside globals
        interact: {
          // Tool mode (derived from toolbar config at construction, updated by Toolbar)
          zoomEnabled: config.chart.toolbar.autoSelected === "zoom" && config.chart.toolbar.tools.zoom && config.chart.zoom.enabled,
          panEnabled: config.chart.toolbar.autoSelected === "pan" && config.chart.toolbar.tools.pan,
          selectionEnabled: config.chart.toolbar.autoSelected === "selection" && config.chart.toolbar.tools.selection,
          // Zoom / pan state (user-driven, must persist across re-renders)
          zoomed: false,
          selection: void 0,
          visibleXRange: void 0,
          selectedDataPoints: [],
          // Mouse / pointer state
          mousedown: false,
          clientX: null,
          clientY: null,
          lastClientPosition: {},
          lastWheelExecution: 0,
          // Tooltip capture state
          capturedSeriesIndex: -1,
          capturedDataPointIndex: -1,
          // Timescale zoom bounds (reset per render by TimeScale)
          disableZoomIn: false,
          disableZoomOut: false,
          // Device detection (set once at construction)
          isTouchDevice: Environment.isBrowser() ? "ontouchstart" in window || navigator.maxTouchPoints > 0 : false
        },
        formatters: {
          // Populated by Formatters.setLabelFormatters() each render
          xLabelFormatter: void 0,
          yLabelFormatters: [],
          xaxisTooltipFormatter: void 0,
          ttKeyFormatter: void 0,
          ttVal: void 0,
          ttZFormatter: void 0,
          legendFormatter: void 0
        },
        // Candlestick / boxplot OHLC arrays — written by Data.handleCandleStickBoxData()
        // each render; empty for all other chart types.
        candleData: {
          seriesCandleO: [],
          seriesCandleH: [],
          seriesCandleM: [],
          seriesCandleL: [],
          seriesCandleC: []
        },
        // Range chart arrays — written by Data.handleRangeData() each render;
        // empty for all other chart types.
        rangeData: {
          seriesRangeStart: [],
          seriesRangeEnd: [],
          seriesRange: []
        },
        // Label / category data — written by Data.parseData() and TimeScale each render.
        labelData: {
          labels: [],
          categoryLabels: [],
          timescaleLabels: [],
          // written by TimeScale.calculateTimeScaleMinMax()
          hasXaxisGroups: false,
          groups: [],
          seriesGroups: []
        },
        // Axis / parsing behaviour flags — written by Data.parseData() each render.
        axisFlags: {
          isXNumeric: false,
          dataFormatXNumeric: false,
          isDataXYZ: false,
          isRangeData: false,
          isRangeBar: false,
          isMultiLineX: false,
          noLabelsProvided: false,
          dataWasParsed: false
        },
        // Parsed series data — written by Data.parseData() each render.
        // Note: initialSeries and originalSeries are intentionally excluded —
        // they are persistent (survive re-renders) and remain on w.globals.
        seriesData: {
          series: [],
          // main y-values array
          seriesNames: [],
          seriesX: [],
          seriesZ: [],
          seriesColors: [],
          seriesGoals: [],
          stackedSeriesTotals: [],
          stackedSeriesTotalsByGroups: []
        },
        // Grid / axis layout computed by Dimensions.plotCoords() each render.
        // gridWidth/gridHeight/translateX/translateY are also used as starting
        // points by Dimensions on the next render (accumulated values), so the
        // shim must be bidirectional — reads and writes both route correctly.
        layout: {
          gridHeight: 0,
          gridWidth: 0,
          translateX: 0,
          translateY: 0,
          translateXAxisX: 0,
          translateXAxisY: 0,
          rotateXLabels: false,
          xAxisHeight: 0,
          xAxisLabelsHeight: 0,
          xAxisGroupLabelsHeight: 0,
          xAxisLabelsWidth: 0,
          yLabelsCoords: [],
          yTitleCoords: []
        }
      };
      Object.defineProperty(globals, "dom", {
        get() {
          return w.dom;
        },
        set(v) {
          w.dom = v;
        },
        enumerable: false,
        configurable: true
      });
      for (const key of [
        "xLabelFormatter",
        "yLabelFormatters",
        "xaxisTooltipFormatter",
        "ttKeyFormatter",
        "ttVal",
        "ttZFormatter",
        "legendFormatter"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.formatters[key]
            );
          },
          set(v) {
            w.formatters[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of [
        "zoomEnabled",
        "panEnabled",
        "selectionEnabled",
        "zoomed",
        "selection",
        "visibleXRange",
        "selectedDataPoints",
        "mousedown",
        "clientX",
        "clientY",
        "lastClientPosition",
        "lastWheelExecution",
        "capturedSeriesIndex",
        "capturedDataPointIndex",
        "disableZoomIn",
        "disableZoomOut",
        "isTouchDevice"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.interact[key]
            );
          },
          set(v) {
            w.interact[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of [
        "gridHeight",
        "gridWidth",
        "translateX",
        "translateY",
        "translateXAxisX",
        "translateXAxisY",
        "rotateXLabels",
        "xAxisHeight",
        "xAxisLabelsHeight",
        "xAxisGroupLabelsHeight",
        "xAxisLabelsWidth",
        "yLabelsCoords",
        "yTitleCoords"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.layout[key]
            );
          },
          set(v) {
            w.layout[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of [
        "series",
        "seriesNames",
        "seriesX",
        "seriesZ",
        "seriesColors",
        "seriesGoals",
        "stackedSeriesTotals",
        "stackedSeriesTotalsByGroups"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.seriesData[key]
            );
          },
          set(v) {
            w.seriesData[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of [
        "isXNumeric",
        "dataFormatXNumeric",
        "isDataXYZ",
        "isRangeData",
        "isRangeBar",
        "isMultiLineX",
        "noLabelsProvided",
        "dataWasParsed"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.axisFlags[key]
            );
          },
          set(v) {
            w.axisFlags[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of [
        "labels",
        "categoryLabels",
        "timescaleLabels",
        "hasXaxisGroups",
        "groups",
        "seriesGroups"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.labelData[key]
            );
          },
          set(v) {
            w.labelData[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of ["seriesRangeStart", "seriesRangeEnd", "seriesRange"]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.rangeData[key]
            );
          },
          set(v) {
            w.rangeData[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      for (const key of [
        "seriesCandleO",
        "seriesCandleH",
        "seriesCandleM",
        "seriesCandleL",
        "seriesCandleC"
      ]) {
        Object.defineProperty(globals, key, {
          get() {
            return (
              /** @type {Record<string,any>} */
              w.candleData[key]
            );
          },
          set(v) {
            w.candleData[key] = v;
          },
          enumerable: false,
          configurable: true
        });
      }
      return (
        /** @type {import('../types/internal').ChartStateW} */
        /** @type {unknown} */
        w
      );
    }
  }
  class CoreUtils {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
    }
    /**
     * @param {any[]} series
     * @param {string} chartType
     */
    static checkComboSeries(series, chartType) {
      let comboCharts = false;
      let comboBarCount = 0;
      let comboCount = 0;
      if (chartType === void 0) {
        chartType = "line";
      }
      if (series.length && typeof series[0].type !== "undefined") {
        series.forEach((s) => {
          if (s.type === "bar" || s.type === "column" || s.type === "candlestick" || s.type === "boxPlot") {
            comboBarCount++;
          }
          if (typeof s.type !== "undefined" && s.type !== chartType) {
            comboCount++;
          }
        });
      }
      if (comboCount > 0) {
        comboCharts = true;
      }
      return {
        comboBarCount,
        comboCharts
      };
    }
    /**
     * @memberof CoreUtils
     * returns the sum of all individual values in a multiple stacked series
     * Eg. w.seriesData.series = [[32,33,43,12], [2,3,5,1]]
     *  @return [34,36,48,13]
     * @param {number[]} excludedSeriesIndices
     **/
    getStackedSeriesTotals(excludedSeriesIndices = []) {
      const w = this.w;
      const total = [];
      if (w.seriesData.series.length === 0) return total;
      for (let i = 0; i < w.seriesData.series[w.globals.maxValsInArrayIndex].length; i++) {
        let t = 0;
        for (let j = 0; j < w.seriesData.series.length; j++) {
          if (typeof w.seriesData.series[j][i] !== "undefined" && excludedSeriesIndices.indexOf(j) === -1) {
            t += w.seriesData.series[j][i];
          }
        }
        total.push(t);
      }
      return total;
    }
    // get total of the all values inside all series
    /**
     * @param {number | null} [index]
     */
    getSeriesTotalByIndex(index = null) {
      if (index === null) {
        return (
          /** @type {any[]} */
          this.w.config.series.reduce(
            (acc, cur) => acc + cur,
            0
          )
        );
      } else {
        return this.w.seriesData.series[index].reduce(
          (acc, cur) => acc + cur,
          0
        );
      }
    }
    /**
     * @memberof CoreUtils
     * returns the sum of values in a multiple stacked grouped charts
     * Eg. w.seriesData.series = [[32,33,43,12], [2,3,5,1], [43, 23, 34, 22]]
     * series 1 and 2 are in a group, while series 3 is in another group
     *  @return [[34, 36, 48, 12], [43, 23, 34, 22]]
     **/
    getStackedSeriesTotalsByGroups() {
      const w = this.w;
      const total = [];
      w.labelData.seriesGroups.forEach((sg) => {
        const includedIndexes = [];
        w.config.series.forEach((s, si) => {
          if (sg.indexOf(w.seriesData.seriesNames[si]) > -1) {
            includedIndexes.push(si);
          }
        });
        const excludedIndices = w.seriesData.series.map((_, fi) => includedIndexes.indexOf(fi) === -1 ? fi : -1).filter((f) => f !== -1);
        total.push(this.getStackedSeriesTotals(excludedIndices));
      });
      return total;
    }
    setSeriesYAxisMappings() {
      const gl = this.w.globals;
      const cnf = this.w.config;
      let axisSeriesMap = [];
      const seriesYAxisReverseMap = [];
      const unassignedSeriesIndices = [];
      const seriesNameArrayStyle = this.w.seriesData.series.length > cnf.yaxis.length || /**
       * @param {ApexYAxis} a
       */
      cnf.yaxis.some((a) => Array.isArray(a.seriesName));
      cnf.series.forEach((_s, i) => {
        unassignedSeriesIndices.push(i);
        seriesYAxisReverseMap.push(null);
      });
      cnf.yaxis.forEach(
        (_yaxe, yi) => {
          axisSeriesMap[yi] = [];
        }
      );
      const unassignedYAxisIndices = [];
      cnf.yaxis.forEach((yaxe, yi) => {
        let assigned = false;
        if (yaxe.seriesName) {
          let seriesNames = [];
          if (Array.isArray(yaxe.seriesName)) {
            seriesNames = yaxe.seriesName;
          } else {
            seriesNames.push(yaxe.seriesName);
          }
          seriesNames.forEach((name2) => {
            cnf.series.forEach((s, si) => {
              if (
                /** @type {any} */
                s.name === name2
              ) {
                let remove = si;
                if (yi === si || seriesNameArrayStyle) {
                  if (!seriesNameArrayStyle || unassignedSeriesIndices.indexOf(si) > -1) {
                    axisSeriesMap[yi].push([yi, si]);
                  } else {
                    console.warn(
                      "Series '" + /** @type {any} */
                      s.name + "' referenced more than once in what looks like the new style. That is, when using either seriesName: [], or when there are more series than yaxes."
                    );
                  }
                } else {
                  axisSeriesMap[si].push([si, yi]);
                  remove = yi;
                }
                assigned = true;
                remove = unassignedSeriesIndices.indexOf(remove);
                if (remove !== -1) {
                  unassignedSeriesIndices.splice(remove, 1);
                }
              }
            });
          });
        }
        if (!assigned) {
          unassignedYAxisIndices.push(yi);
        }
      });
      axisSeriesMap = axisSeriesMap.map((yaxe) => {
        const ra = [];
        yaxe.forEach((sa) => {
          seriesYAxisReverseMap[sa[1]] = sa[0];
          ra.push(sa[1]);
        });
        return ra;
      });
      let lastUnassignedYAxis = cnf.yaxis.length - 1;
      for (let i = 0; i < unassignedYAxisIndices.length; i++) {
        lastUnassignedYAxis = unassignedYAxisIndices[i];
        axisSeriesMap[lastUnassignedYAxis] = [];
        if (unassignedSeriesIndices) {
          const si = unassignedSeriesIndices[0];
          unassignedSeriesIndices.shift();
          axisSeriesMap[lastUnassignedYAxis].push(si);
          seriesYAxisReverseMap[si] = lastUnassignedYAxis;
        } else {
          break;
        }
      }
      unassignedSeriesIndices.forEach((i) => {
        axisSeriesMap[lastUnassignedYAxis].push(i);
        seriesYAxisReverseMap[i] = lastUnassignedYAxis;
      });
      gl.seriesYAxisMap = axisSeriesMap.map((x) => x);
      gl.seriesYAxisReverseMap = seriesYAxisReverseMap.map((x) => x);
      gl.seriesYAxisMap.forEach((axisSeries, ai) => {
        axisSeries.forEach((si) => {
          if (
            /** @type {any} */
            cnf.series[si] && /** @type {any} */
            cnf.series[si].group === void 0
          ) {
            const _series = (
              /** @type {any} */
              cnf.series[si]
            );
            _series.group = "apexcharts-axis-".concat(ai.toString());
          }
        });
      });
    }
    /**
     * @param {number | null} [index]
     */
    isSeriesNull(index = null) {
      let r = [];
      if (index === null) {
        r = /** @type {any[]} */
        this.w.config.series.filter(
          (d) => d !== null
        );
      } else {
        r = /** @type {Record<string,any>} */
        this.w.config.series[index].data.filter((d) => d !== null);
      }
      return r.length === 0;
    }
    /**
     * @param {number} index
     */
    seriesHaveSameValues(index) {
      return this.w.seriesData.series[index].every(
        (val, i, arr) => val === arr[0]
      );
    }
    /**
     * @param {any[]} labels
     */
    getCategoryLabels(labels) {
      const w = this.w;
      let catLabels = labels.slice();
      if (w.config.xaxis.convertedCatToNumeric) {
        catLabels = labels.map((i) => {
          return w.config.xaxis.labels.formatter(i - w.globals.minX + 1);
        });
      }
      return catLabels;
    }
    // maxValsInArrayIndex is the index of series[] which has the largest number of items
    getLargestSeries() {
      const w = this.w;
      w.globals.maxValsInArrayIndex = w.seriesData.series.map((a) => a.length).indexOf(
        Math.max.apply(
          Math,
          /**
           * @param {number[]} a
           */
          w.seriesData.series.map((a) => a.length)
        )
      );
    }
    getLargestMarkerSize() {
      const w = this.w;
      let size = 0;
      w.globals.markers.size.forEach((m) => {
        size = Math.max(size, m);
      });
      if (w.config.markers.discrete && w.config.markers.discrete.length) {
        w.config.markers.discrete.forEach((m) => {
          size = Math.max(size, m.size);
        });
      }
      if (size > 0) {
        if (w.config.markers.hover.size > 0) {
          size = w.config.markers.hover.size;
        } else {
          size += w.config.markers.hover.sizeOffset;
        }
      }
      w.globals.markers.largestSize = size;
      return size;
    }
    /**
     * @memberof Core
     * returns the sum of all values in a series
     * Eg. w.seriesData.series = [[32,33,43,12], [2,3,5,1]]
     *  @return [120, 11]
     **/
    getSeriesTotals() {
      const w = this.w;
      w.globals.seriesTotals = w.seriesData.series.map((ser) => {
        let total = 0;
        if (Array.isArray(ser)) {
          for (let j = 0; j < ser.length; j++) {
            total += ser[j];
          }
        } else {
          total += ser;
        }
        return total;
      });
    }
    /**
     * @param {number} minX
     * @param {number} maxX
     */
    getSeriesTotalsXRange(minX, maxX) {
      const w = this.w;
      const seriesTotalsXRange = w.seriesData.series.map((ser, index) => {
        let total = 0;
        for (let j = 0; j < ser.length; j++) {
          if (w.seriesData.seriesX[index][j] > minX && w.seriesData.seriesX[index][j] < maxX) {
            total += ser[j];
          }
        }
        return total;
      });
      return seriesTotalsXRange;
    }
    /**
     * @memberof CoreUtils
     * returns the percentage value of all individual values which can be used in a 100% stacked series
     * Eg. w.seriesData.series = [[32, 33, 43, 12], [2, 3, 5, 1]]
     *  @return [[94.11, 91.66, 89.58, 92.30], [5.88, 8.33, 10.41, 7.7]]
     **/
    getPercentSeries() {
      const w = this.w;
      w.globals.seriesPercent = w.seriesData.series.map((ser) => {
        const seriesPercent = [];
        if (Array.isArray(ser)) {
          for (let j = 0; j < ser.length; j++) {
            const total = w.seriesData.stackedSeriesTotals[j];
            let percent = 0;
            if (total) {
              percent = 100 * ser[j] / total;
            }
            seriesPercent.push(percent);
          }
        } else {
          const total = w.globals.seriesTotals.reduce((acc, val) => acc + val, 0);
          const percent = 100 * ser / total;
          seriesPercent.push(percent);
        }
        return seriesPercent;
      });
    }
    getCalculatedRatios() {
      const w = this.w;
      const gl = w.globals;
      const yRatio = [];
      let invertedYRatio = 0;
      let xRatio = 0;
      let invertedXRatio = 0;
      let zRatio = 0;
      let baseLineY = [];
      let baseLineInvertedY = 0.1;
      let baseLineX = 0;
      gl.yRange = [];
      if (gl.isMultipleYAxis) {
        for (let i = 0; i < gl.minYArr.length; i++) {
          gl.yRange.push(Math.abs(gl.minYArr[i] - gl.maxYArr[i]));
          baseLineY.push(0);
        }
      } else {
        gl.yRange.push(Math.abs(gl.minY - gl.maxY));
      }
      gl.xRange = Math.abs(gl.maxX - gl.minX);
      gl.zRange = Math.abs(gl.maxZ - gl.minZ);
      for (let i = 0; i < gl.yRange.length; i++) {
        yRatio.push(gl.yRange[i] / this.w.layout.gridHeight);
      }
      xRatio = gl.xRange / this.w.layout.gridWidth;
      invertedYRatio = /** @type {any} */
      gl.yRange / this.w.layout.gridWidth;
      invertedXRatio = gl.xRange / this.w.layout.gridHeight;
      zRatio = gl.zRange / this.w.layout.gridHeight * 16;
      if (!zRatio) {
        zRatio = 1;
      }
      if (gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0) {
        const _hasNegsGl = (
          /** @type {any} */
          gl
        );
        _hasNegsGl.hasNegs = true;
      }
      if (w.globals.seriesYAxisReverseMap.length > 0) {
        const scaleBaseLineYScale = (y, i) => {
          const yAxis = w.config.yaxis[w.globals.seriesYAxisReverseMap[i]];
          const sign = y < 0 ? -1 : 1;
          y = Math.abs(y);
          if (yAxis.logarithmic) {
            y = this.getBaseLog(yAxis.logBase, y);
          }
          return -sign * y / yRatio[i];
        };
        if (gl.isMultipleYAxis) {
          baseLineY = [];
          for (let i = 0; i < yRatio.length; i++) {
            baseLineY.push(scaleBaseLineYScale(gl.minYArr[i], i));
          }
        } else {
          baseLineY = [];
          baseLineY.push(scaleBaseLineYScale(gl.minY, 0));
          if (gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0) {
            baseLineInvertedY = -gl.minY / invertedYRatio;
            baseLineX = gl.minX / xRatio;
          }
        }
      } else {
        baseLineY = [];
        baseLineY.push(0);
        baseLineInvertedY = 0;
        baseLineX = 0;
      }
      return {
        yRatio,
        invertedYRatio,
        zRatio,
        xRatio,
        invertedXRatio,
        baseLineInvertedY,
        baseLineY,
        baseLineX
      };
    }
    /**
     * @param {any[]} series
     */
    getLogSeries(series) {
      const w = this.w;
      w.globals.seriesLog = series.map((s, i) => {
        const yAxisIndex = w.globals.seriesYAxisReverseMap[i];
        if (w.config.yaxis[yAxisIndex] && w.config.yaxis[yAxisIndex].logarithmic) {
          return s.map((d) => {
            if (d === null) return null;
            return this.getLogVal(w.config.yaxis[yAxisIndex].logBase, d, i);
          });
        } else {
          return s;
        }
      });
      return w.globals.invalidLogScale ? series : w.globals.seriesLog;
    }
    /**
     * @param {number} val
     * @param {number} seriesIndex
     * @returns {number}
     */
    getLogValAtSeriesIndex(val, seriesIndex) {
      if (val === null) return (
        /** @type {any} */
        null
      );
      const w = this.w;
      const yAxisIndex = w.globals.seriesYAxisReverseMap[seriesIndex];
      if (w.config.yaxis[yAxisIndex] && w.config.yaxis[yAxisIndex].logarithmic) {
        return this.getLogVal(
          w.config.yaxis[yAxisIndex].logBase,
          val,
          seriesIndex
        );
      }
      return val;
    }
    /**
     * @param {number} base
     * @param {number} value
     */
    getBaseLog(base, value) {
      return Math.log(value) / Math.log(base);
    }
    /**
     * @param {number} b
     * @param {number} d
     * @param {number} seriesIndex
     */
    getLogVal(b, d, seriesIndex) {
      if (d <= 0) {
        return 0;
      }
      const w = this.w;
      const min_log_val = w.globals.minYArr[seriesIndex] === 0 ? -1 : this.getBaseLog(b, w.globals.minYArr[seriesIndex]);
      const max_log_val = w.globals.maxYArr[seriesIndex] === 0 ? 0 : this.getBaseLog(b, w.globals.maxYArr[seriesIndex]);
      const number_of_height_levels = max_log_val - min_log_val;
      if (d < 1) return d / number_of_height_levels;
      const log_height_value = this.getBaseLog(b, d) - min_log_val;
      return log_height_value / number_of_height_levels;
    }
    /**
     * @param {number[]} yRatio
     */
    getLogYRatios(yRatio) {
      const w = this.w;
      const gl = this.w.globals;
      const _gl = (
        /** @type {any} */
        gl
      );
      _gl.yLogRatio = yRatio.slice();
      _gl.logYRange = /** @type {any[]} */
      gl.yRange.map(
        (_, i) => {
          const yAxisIndex = w.globals.seriesYAxisReverseMap[i];
          if (w.config.yaxis[yAxisIndex] && this.w.config.yaxis[yAxisIndex].logarithmic) {
            let maxY = -Number.MAX_VALUE;
            let minY = Number.MIN_VALUE;
            let range = 1;
            gl.seriesLog.forEach(
              (s, si) => {
                s.forEach((v) => {
                  if (w.config.yaxis[si] && w.config.yaxis[si].logarithmic) {
                    maxY = Math.max(v, maxY);
                    minY = Math.min(v, minY);
                  }
                });
              }
            );
            range = Math.pow(gl.yRange[i], Math.abs(minY - maxY) / gl.yRange[i]);
            _gl.yLogRatio[i] = range / this.w.layout.gridHeight;
            return range;
          }
        }
      );
      return _gl.invalidLogScale ? yRatio.slice() : _gl.yLogRatio;
    }
    // Some config objects can be array - and we need to extend them correctly
    /**
     * @param {any} configInstance
     * @param {Record<string, any>} options
     * @param {import('../types/internal').ChartStateW} w
     */
    static extendArrayProps(configInstance, options2, w) {
      var _a, _b;
      if (options2 == null ? void 0 : options2.yaxis) {
        options2 = configInstance.extendYAxis(options2, w);
      }
      if (options2 == null ? void 0 : options2.annotations) {
        if (options2.annotations.yaxis) {
          options2 = configInstance.extendYAxisAnnotations(options2);
        }
        if ((_a = options2 == null ? void 0 : options2.annotations) == null ? void 0 : _a.xaxis) {
          options2 = configInstance.extendXAxisAnnotations(options2);
        }
        if ((_b = options2 == null ? void 0 : options2.annotations) == null ? void 0 : _b.points) {
          options2 = configInstance.extendPointAnnotations(options2);
        }
      }
      return options2;
    }
    // Series of the same group and type can be stacked together distinct from
    // other series of the same type on the same axis.
    /**
     * @param {Record<string, any>} typeSeries
     * @param {string[]} typeGroups
     * @param {string} type
     * @param {string} chartClass
     */
    drawSeriesByGroup(typeSeries, typeGroups, type, chartClass) {
      const w = this.w;
      const graph = [];
      if (typeSeries.series.length > 0) {
        typeGroups.forEach((gn) => {
          const gs = [];
          const gi = [];
          typeSeries.i.forEach((i, ii) => {
            if (
              /** @type {Record<string,any>} */
              w.config.series[i].group === gn
            ) {
              gs.push(typeSeries.series[ii]);
              gi.push(i);
            }
          });
          gs.length > 0 && graph.push(
            /** @type {any} */
            chartClass.draw(gs, type, gi)
          );
        });
      }
      return graph;
    }
  }
  class Animations {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} [ctx]
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
    }
    /**
     * @param {any} el
     * @param {Record<string, any>} from
     * @param {Record<string, any>} to
     * @param {object} speed
     */
    animateLine(el, from, to, speed) {
      el.attr(from).animate(speed).attr(to);
    }
    /*
     ** Animate radius of a circle element
     * @param {any} el
     * @param {number} speed
     * @param {string} easing
     * @param {Function} cb
     */
    /** @param {any} el @param {any} speed @param {any} easing @param {any} cb */
    animateMarker(el, speed, easing, cb) {
      el.attr({
        opacity: 0
      }).animate(speed).attr({
        opacity: 1
      }).after(() => {
        cb();
      });
    }
    /*
     ** Animate rect properties
     * @param {any} el
     * @param {any} from
     * @param {any} to
     * @param {number} speed
     * @param {Function} fn
     */
    /** @param {any} el @param {any} from @param {any} to @param {any} speed @param {any} fn */
    animateRect(el, from, to, speed, fn) {
      el.attr(from).animate(speed).attr(to).after(() => fn());
    }
    /**
     * @param {Record<string, any>} params
     */
    animatePathsGradually(params) {
      const { el, realIndex, j, fill, pathFrom, pathTo, speed, delay } = params;
      const me = this;
      const w = this.w;
      let delayFactor = 0;
      if (w.config.chart.animations.animateGradually.enabled) {
        delayFactor = w.config.chart.animations.animateGradually.delay;
      }
      if (w.config.chart.animations.dynamicAnimation.enabled && w.globals.dataChanged && w.config.chart.type !== "bar") {
        delayFactor = 0;
      }
      me.morphSVG(
        el,
        realIndex,
        j,
        w.config.chart.type === "line" && !w.globals.comboCharts ? "stroke" : fill,
        pathFrom,
        pathTo,
        speed,
        delay * delayFactor
      );
    }
    showDelayedElements() {
      this.w.globals.delayedElements.forEach((d) => {
        const ele = d.el;
        ele.classList.remove("apexcharts-element-hidden");
        ele.classList.add("apexcharts-hidden-element-shown");
      });
    }
    /**
     * @param {any} el
     */
    animationCompleted(el) {
      const w = this.w;
      if (w.globals.animationEnded) return;
      w.globals.animationEnded = true;
      this.showDelayedElements();
      if (typeof w.config.chart.events.animationEnd === "function") {
        w.config.chart.events.animationEnd(this.ctx, { el, w });
      }
    }
    // SVG.js animation for morphing one path to another
    /**
     * @param {any} el
     * @param {number} realIndex
     * @param {number} j
     * @param {string} fill
     * @param {string} pathFrom
     * @param {string} pathTo
     * @param {number} speed
     * @param {number} delay
     */
    morphSVG(el, realIndex, j, fill, pathFrom, pathTo, speed, delay) {
      const w = this.w;
      if (!pathFrom) {
        pathFrom = el.attr("pathFrom");
      }
      if (!pathTo) {
        pathTo = el.attr("pathTo");
      }
      const disableAnimationForCorrupPath = () => {
        if (w.config.chart.type === "radar") {
          speed = 1;
        }
        return `M 0 ${w.layout.gridHeight}`;
      };
      if (!pathFrom || pathFrom.indexOf("undefined") > -1 || pathFrom.indexOf("NaN") > -1) {
        pathFrom = disableAnimationForCorrupPath();
      }
      if (!pathTo.trim() || pathTo.indexOf("undefined") > -1 || pathTo.indexOf("NaN") > -1) {
        pathTo = disableAnimationForCorrupPath();
      }
      if (!w.globals.shouldAnimate) {
        speed = 1;
      }
      el.plot(pathFrom).animate(1, delay).plot(pathFrom).animate(speed, delay).plot(pathTo).after(() => {
        if (Utils$1.isNumber(j)) {
          if (j === w.seriesData.series[w.globals.maxValsInArrayIndex].length - 2 && w.globals.shouldAnimate) {
            this.animationCompleted(el);
          }
        } else if (fill !== "none" && w.globals.shouldAnimate) {
          if (!w.globals.comboCharts && realIndex === w.seriesData.series.length - 1 || w.globals.comboCharts) {
            this.animationCompleted(el);
          }
        }
        this.showDelayedElements();
      });
    }
  }
  class Filters {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
    }
    // create a re-usable filter which can be appended other filter effects and applied to multiple elements
    /**
     * @param {any} el
     * @param {number} i
     */
    getDefaultFilter(el, i) {
      const w = this.w;
      if (el.unfilter) {
        el.unfilter(true);
      }
      if (w.config.chart.dropShadow.enabled) {
        this.dropShadow(el, w.config.chart.dropShadow, i);
      }
    }
    /**
     * @param {any} el
     * @param {number} i
     * @param {string} filterType
     */
    applyFilter(el, i, filterType) {
      var _a, _b, _c;
      const w = this.w;
      if (el.unfilter) {
        el.unfilter(true);
      }
      if (filterType === "none") {
        this.getDefaultFilter(el, i);
        return;
      }
      const shadowAttr = w.config.chart.dropShadow;
      const brightnessFactor = filterType === "lighten" ? 2 : 0.3;
      if (el.filterWith) {
        el.filterWith((add) => {
          add.colorMatrix({
            type: "matrix",
            values: `
            ${brightnessFactor} 0 0 0 0
            0 ${brightnessFactor} 0 0 0
            0 0 ${brightnessFactor} 0 0
            0 0 0 1 0
          `,
            in: "SourceGraphic",
            result: "brightness"
          });
          if (shadowAttr.enabled) {
            this.addShadow(add, i, shadowAttr, "brightness");
          }
        });
        if (!shadowAttr.noUserSpaceOnUse) {
          (_b = (_a = el.filterer()) == null ? void 0 : _a.node) == null ? void 0 : _b.setAttribute("filterUnits", "userSpaceOnUse");
        }
        this._scaleFilterSize((_c = el.filterer()) == null ? void 0 : _c.node);
      }
    }
    // appends dropShadow to the filter object which can be chained with other filter effects
    /**
     * @param {any} add
     * @param {number} i
     * @param {Record<string, any>} attrs
     * @param {string} source
     */
    addShadow(add, i, attrs, source) {
      var _a;
      const w = this.w;
      let { blur, top, left, color, opacity } = attrs;
      color = Array.isArray(color) ? color[i] : color;
      if (((_a = w.config.chart.dropShadow.enabledOnSeries) == null ? void 0 : _a.length) > 0) {
        if (w.config.chart.dropShadow.enabledOnSeries.indexOf(i) === -1) {
          return add;
        }
      }
      add.offset({
        in: source,
        dx: left,
        dy: top,
        result: "offset"
      });
      add.gaussianBlur({
        in: "offset",
        stdDeviation: blur,
        result: "blur"
      });
      add.flood({
        "flood-color": color,
        "flood-opacity": opacity,
        result: "flood"
      });
      add.composite({
        in: "flood",
        in2: "blur",
        operator: "in",
        result: "shadow"
      });
      add.merge(["shadow", source]);
    }
    // directly adds dropShadow to the element and returns the same element.
    /**
     * @param {any} el
     * @param {Record<string, any>} attrs
     */
    dropShadow(el, attrs, i = 0) {
      var _a, _b, _c, _d, _e;
      const w = this.w;
      if (el.unfilter) {
        el.unfilter(true);
      }
      if (Utils$1.isMsEdge() && w.config.chart.type === "radialBar") {
        return el;
      }
      if (((_a = w.config.chart.dropShadow.enabledOnSeries) == null ? void 0 : _a.length) > 0) {
        if (((_b = w.config.chart.dropShadow.enabledOnSeries) == null ? void 0 : _b.indexOf(i)) === -1) {
          return el;
        }
      }
      if (el.filterWith) {
        el.filterWith((add) => {
          this.addShadow(add, i, attrs, "SourceGraphic");
        });
        if (!attrs.noUserSpaceOnUse) {
          (_d = (_c = el.filterer()) == null ? void 0 : _c.node) == null ? void 0 : _d.setAttribute("filterUnits", "userSpaceOnUse");
        }
        this._scaleFilterSize((_e = el.filterer()) == null ? void 0 : _e.node);
      }
      return el;
    }
    /**
     * @param {any} el
     * @param {number} realIndex
     * @param {number} dataPointIndex
     */
    setSelectionFilter(el, realIndex, dataPointIndex) {
      const w = this.w;
      if (typeof w.interact.selectedDataPoints[realIndex] !== "undefined") {
        if (w.interact.selectedDataPoints[realIndex].indexOf(dataPointIndex) > -1) {
          el.node.setAttribute("selected", true);
          const activeFilter = w.config.states.active.filter;
          if (activeFilter !== "none") {
            this.applyFilter(el, realIndex, activeFilter.type);
          }
        }
      }
    }
    /**
     * @param {any} el
     */
    _scaleFilterSize(el) {
      if (!el) return;
      const setAttributes = (attrs) => {
        for (const key in attrs) {
          if (Object.prototype.hasOwnProperty.call(attrs, key)) {
            el.setAttribute(key, attrs[key]);
          }
        }
      };
      setAttributes({
        width: "200%",
        height: "200%",
        x: "-50%",
        y: "-50%"
      });
    }
  }
  class Graphics {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext | null} ctx
     */
    constructor(w, ctx = null) {
      this.w = w;
      this.ctx = ctx;
    }
    /*****************************************************************************
     *                                                                            *
     *  SVG Path Rounding Function                                                *
     *  Copyright (C) 2014 Yona Appletree                                         *
     *                                                                            *
     *  Licensed under the Apache License, Version 2.0 (the "License");           *
     *  you may not use this file except in compliance with the License.          *
     *  You may obtain a copy of the License at                                   *
     *                                                                            *
     *      http://www.apache.org/licenses/LICENSE-2.0                            *
     *                                                                            *
     *  Unless required by applicable law or agreed to in writing, software       *
     *  distributed under the License is distributed on an "AS IS" BASIS,         *
     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
     *  See the License for the specific language governing permissions and       *
     *  limitations under the License.                                            *
     *                                                                            *
     *****************************************************************************/
    /**
     * SVG Path rounding function. Takes an input path string and outputs a path
     * string where all line-line corners have been rounded. Only supports absolute
     * commands at the moment.
     *
     * @param pathString The SVG input path
     * @param radius The amount to round the corners, either a value in the SVG
     *               coordinate space, or, if useFractionalRadius is true, a value
     *               from 0 to 1.
     * @returns A new SVG path string with the rounding
     * @param {string} pathString
     * @param {number} radius
     */
    roundPathCorners(pathString, radius) {
      if (pathString.indexOf("NaN") > -1) pathString = "";
      function moveTowardsLength(movingPoint, targetPoint, amount) {
        var width = targetPoint.x - movingPoint.x;
        var height = targetPoint.y - movingPoint.y;
        var distance = Math.sqrt(width * width + height * height);
        return moveTowardsFractional(
          movingPoint,
          targetPoint,
          Math.min(1, amount / distance)
        );
      }
      function moveTowardsFractional(movingPoint, targetPoint, fraction) {
        return {
          x: movingPoint.x + (targetPoint.x - movingPoint.x) * fraction,
          y: movingPoint.y + (targetPoint.y - movingPoint.y) * fraction
        };
      }
      function adjustCommand(cmd, newPoint) {
        if (cmd.length > 2) {
          cmd[cmd.length - 2] = newPoint.x;
          cmd[cmd.length - 1] = newPoint.y;
        }
      }
      function pointForCommand(cmd) {
        return {
          x: parseFloat(cmd[cmd.length - 2]),
          y: parseFloat(cmd[cmd.length - 1])
        };
      }
      var pathParts = pathString.split(/[,\s]/).reduce(function(parts, part) {
        var match = part.match(/^([a-zA-Z])(.+)/);
        if (match) {
          parts.push(match[1]);
          parts.push(match[2]);
        } else {
          parts.push(part);
        }
        return parts;
      }, []);
      var commands = pathParts.reduce(function(commands2, part) {
        if (parseFloat(part) == part && commands2.length) {
          commands2[commands2.length - 1].push(part);
        } else {
          commands2.push([part]);
        }
        return commands2;
      }, []);
      var resultCommands = [];
      if (commands.length > 1) {
        var startPoint = pointForCommand(commands[0]);
        var virtualCloseLine = null;
        if (commands[commands.length - 1][0] == "Z" && commands[0].length > 2) {
          virtualCloseLine = ["L", startPoint.x, startPoint.y];
          commands[commands.length - 1] = virtualCloseLine;
        }
        resultCommands.push(commands[0]);
        for (var cmdIndex = 1; cmdIndex < commands.length; cmdIndex++) {
          var prevCmd = resultCommands[resultCommands.length - 1];
          var curCmd = commands[cmdIndex];
          var nextCmd = curCmd == virtualCloseLine ? commands[1] : commands[cmdIndex + 1];
          if (nextCmd && prevCmd && prevCmd.length > 2 && curCmd[0] == "L" && nextCmd.length > 2 && nextCmd[0] == "L") {
            var prevPoint = pointForCommand(prevCmd);
            var curPoint = pointForCommand(curCmd);
            var nextPoint = pointForCommand(nextCmd);
            var curveStart, curveEnd;
            curveStart = moveTowardsLength(curPoint, prevPoint, radius);
            curveEnd = moveTowardsLength(curPoint, nextPoint, radius);
            adjustCommand(curCmd, curveStart);
            curCmd.origPoint = curPoint;
            resultCommands.push(curCmd);
            var startControl = moveTowardsFractional(curveStart, curPoint, 0.5);
            var endControl = moveTowardsFractional(curPoint, curveEnd, 0.5);
            var curveCmd = [
              "C",
              startControl.x,
              startControl.y,
              endControl.x,
              endControl.y,
              curveEnd.x,
              curveEnd.y
            ];
            curveCmd.origPoint = curPoint;
            resultCommands.push(curveCmd);
          } else {
            resultCommands.push(curCmd);
          }
        }
        if (virtualCloseLine) {
          var newStartPoint = pointForCommand(
            resultCommands[resultCommands.length - 1]
          );
          resultCommands.push(["Z"]);
          adjustCommand(resultCommands[0], newStartPoint);
        }
      } else {
        resultCommands = commands;
      }
      return resultCommands.reduce(function(str, c) {
        return str + c.join(" ") + " ";
      }, "");
    }
    /**
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     * @param {number | null} [strokeWidth]
     */
    drawLine(x1, y1, x2, y2, lineColor = "#a8a8a8", dashArray = 0, strokeWidth = null, strokeLineCap = "butt") {
      const w = this.w;
      const line = w.dom.Paper.line().attr({
        x1,
        y1,
        x2,
        y2,
        stroke: lineColor,
        "stroke-dasharray": dashArray,
        "stroke-width": strokeWidth,
        "stroke-linecap": strokeLineCap
      });
      return line;
    }
    /**
     * @param {number | null} [strokeWidth]
     * @param {string | null} [strokeColor]
     */
    drawRect(x1 = 0, y1 = 0, x2 = 0, y2 = 0, radius = 0, color = "#fefefe", opacity = 1, strokeWidth = null, strokeColor = null, strokeDashArray = 0) {
      const w = this.w;
      const rect = w.dom.Paper.rect();
      rect.attr({
        x: x1,
        y: y1,
        width: x2 > 0 ? x2 : 0,
        height: y2 > 0 ? y2 : 0,
        rx: radius,
        ry: radius,
        opacity,
        "stroke-width": strokeWidth !== null ? strokeWidth : 0,
        stroke: strokeColor !== null ? strokeColor : "none",
        "stroke-dasharray": strokeDashArray
      });
      rect.node.setAttribute("fill", color);
      return rect;
    }
    /**
     * @param {string} polygonString
     */
    drawPolygon(polygonString, stroke = "#e1e1e1", strokeWidth = 1, fill = "none") {
      const w = this.w;
      const polygon = w.dom.Paper.polygon(polygonString).attr({
        fill,
        stroke,
        "stroke-width": strokeWidth
      });
      return polygon;
    }
    /**
     * @param {number} radius
     * @param {Record<string, any> | null} attrs
     */
    drawCircle(radius, attrs = null) {
      const w = this.w;
      if (radius < 0) radius = 0;
      const c = w.dom.Paper.circle(radius * 2);
      if (attrs !== null) {
        c.attr(attrs);
      }
      return c;
    }
    /** @param {{ d?: string, stroke?: string, strokeWidth?: number, fill: any, fillOpacity?: number, strokeOpacity?: number, classes?: any, strokeLinecap?: any, strokeDashArray?: number }} opts */
    drawPath({
      d = "",
      stroke = "#a8a8a8",
      strokeWidth = 1,
      fill,
      fillOpacity = 1,
      strokeOpacity = 1,
      classes,
      strokeLinecap = null,
      strokeDashArray = 0
    }) {
      const w = this.w;
      if (strokeLinecap === null) {
        strokeLinecap = w.config.stroke.lineCap;
      }
      if (d.indexOf("undefined") > -1 || d.indexOf("NaN") > -1) {
        d = `M 0 ${w.layout.gridHeight}`;
      }
      const p = w.dom.Paper.path(d).attr({
        fill,
        "fill-opacity": fillOpacity,
        stroke,
        "stroke-opacity": strokeOpacity,
        "stroke-linecap": strokeLinecap,
        "stroke-width": strokeWidth,
        "stroke-dasharray": strokeDashArray,
        class: classes
      });
      return p;
    }
    /**
     * @param {Record<string, any> | null} attrs
     */
    group(attrs = null) {
      const w = this.w;
      const g = w.dom.Paper.group();
      if (attrs !== null) {
        g.attr(attrs);
      }
      return g;
    }
    /**
     * @param {number} x
     * @param {number} y
     */
    move(x, y) {
      const move = ["M", x, y].join(" ");
      return move;
    }
    /**
     * @param {number | null} x
     * @param {number | null} y
     * @param {string | null} hORv
     * @returns {string}
     */
    line(x, y, hORv = null) {
      if (hORv === "H") return [" H", x].join(" ");
      if (hORv === "V") return [" V", y].join(" ");
      return [" L", x, y].join(" ");
    }
    /**
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     * @param {number} x
     * @param {number} y
     */
    curve(x1, y1, x2, y2, x, y) {
      const curve = ["C", x1, y1, x2, y2, x, y].join(" ");
      return curve;
    }
    /**
     * @param {number} x1
     * @param {number} y1
     * @param {number} x
     * @param {number} y
     */
    quadraticCurve(x1, y1, x, y) {
      const curve = ["Q", x1, y1, x, y].join(" ");
      return curve;
    }
    /**
     * @param {number} rx
     * @param {number} ry
     * @param {number} axisRotation
     * @param {number} largeArcFlag
     * @param {number} sweepFlag
     * @param {number} x
     * @param {number} y
     */
    arc(rx, ry, axisRotation, largeArcFlag, sweepFlag, x, y, relative = false) {
      let coord = "A";
      if (relative) coord = "a";
      const arc = [
        coord,
        rx,
        ry,
        axisRotation,
        largeArcFlag,
        sweepFlag,
        x,
        y
      ].join(" ");
      return arc;
    }
    /**
     * @memberof Graphics
     * @param {Record<string, any>} opts
     *  i = series's index
     *  realIndex = realIndex is series's actual index when it was drawn time. After several redraws, the iterating "i" may change in loops, but realIndex doesn't
     *  pathFrom = existing pathFrom to animateTo
     *  pathTo = new Path to which d attr will be animated from pathFrom to pathTo
     *  stroke = line Color
     *  strokeWidth = width of path Line
     *  fill = it can be gradient, single color, pattern or image
     *  animationDelay = how much to delay when starting animation (in milliseconds)
     *  dataChangeSpeed = for dynamic animations, when data changes
     *  className = class attribute to add
     * @return {any} svg.js path object
     **/
    renderPaths({
      j,
      realIndex,
      pathFrom,
      pathTo,
      stroke,
      strokeWidth,
      strokeLinecap,
      fill,
      animationDelay,
      initialSpeed,
      dataChangeSpeed,
      className,
      chartType,
      shouldClipToGrid = true,
      bindEventsOnPaths = true,
      drawShadow = true
    }) {
      const w = this.w;
      const filters = new Filters(this.w);
      const anim = new Animations(
        this.w,
        /** @type {any} */
        void 0
      );
      const initialAnim = this.w.config.chart.animations.enabled;
      const dynamicAnim = initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled;
      if (pathFrom && pathFrom.startsWith("M 0 0") && pathTo) {
        const moveCommand = pathTo.match(/^M\s+[\d.-]+\s+[\d.-]+/);
        if (moveCommand) {
          pathFrom = pathFrom.replace(/^M\s+0\s+0/, moveCommand[0]);
        }
      }
      let d;
      const shouldAnimate = !!(initialAnim && !w.globals.resized || dynamicAnim && w.globals.dataChanged && w.globals.shouldAnimate);
      if (shouldAnimate) {
        d = pathFrom;
      } else {
        d = pathTo;
        w.globals.animationEnded = true;
      }
      const strokeDashArrayOpt = w.config.stroke.dashArray;
      let strokeDashArray = 0;
      if (Array.isArray(strokeDashArrayOpt)) {
        strokeDashArray = strokeDashArrayOpt[realIndex];
      } else {
        strokeDashArray = w.config.stroke.dashArray;
      }
      const el = this.drawPath({
        d,
        stroke,
        strokeWidth,
        fill,
        fillOpacity: 1,
        classes: className,
        strokeLinecap,
        strokeDashArray
      });
      el.attr("index", realIndex);
      if (shouldClipToGrid) {
        if (chartType === "bar" && !w.globals.isBarHorizontal || w.globals.comboCharts) {
          el.attr({
            "clip-path": `url(#gridRectBarMask${w.globals.cuid})`
          });
        } else {
          el.attr({
            "clip-path": `url(#gridRectMask${w.globals.cuid})`
          });
        }
      }
      if (w.config.chart.dropShadow.enabled && drawShadow) {
        filters.dropShadow(el, w.config.chart.dropShadow, realIndex);
      }
      if (bindEventsOnPaths) {
        el.node.addEventListener("mouseenter", this.pathMouseEnter.bind(this, el));
        el.node.addEventListener("mouseleave", this.pathMouseLeave.bind(this, el));
        el.node.addEventListener("mousedown", this.pathMouseDown.bind(this, el));
      }
      el.attr({
        pathTo,
        pathFrom
      });
      const defaultAnimateOpts = {
        el,
        j,
        realIndex,
        pathFrom,
        pathTo,
        fill,
        strokeWidth,
        delay: animationDelay
      };
      if (initialAnim && !w.globals.resized && !w.globals.dataChanged) {
        anim.animatePathsGradually(__spreadProps(__spreadValues({}, defaultAnimateOpts), {
          speed: initialSpeed
        }));
      } else {
        if (w.globals.resized || !w.globals.dataChanged) {
          anim.showDelayedElements();
        }
      }
      if (w.globals.dataChanged && dynamicAnim && shouldAnimate) {
        anim.animatePathsGradually(__spreadProps(__spreadValues({}, defaultAnimateOpts), {
          speed: dataChangeSpeed
        }));
      }
      return el;
    }
    /**
     * @param {string} style
     * @param {number} width
     * @param {number} height
     */
    drawPattern(style, width, height, stroke = "#a8a8a8", strokeWidth = 0) {
      const w = this.w;
      const p = w.dom.Paper.pattern(width, height, (add) => {
        if (style === "horizontalLines") {
          add.line(0, 0, height, 0).stroke({ color: stroke, width: strokeWidth + 1 });
        } else if (style === "verticalLines") {
          add.line(0, 0, 0, width).stroke({ color: stroke, width: strokeWidth + 1 });
        } else if (style === "slantedLines") {
          add.line(0, 0, width, height).stroke({ color: stroke, width: strokeWidth });
        } else if (style === "squares") {
          add.rect(width, height).fill("none").stroke({ color: stroke, width: strokeWidth });
        } else if (style === "circles") {
          add.circle(width).fill("none").stroke({ color: stroke, width: strokeWidth });
        }
      });
      return p;
    }
    /**
     * @param {string} style
     * @param {string} gfrom
     * @param {string} gto
     * @param {number} opacityFrom
     * @param {number} opacityTo
     * @param {number | null} [size]
     * @param {number[] | null} stops
     * @param {any[]} colorStops
     */
    drawGradient(style, gfrom, gto, opacityFrom, opacityTo, size = null, stops = null, colorStops = [], i = 0) {
      const w = this.w;
      let g;
      if (gfrom.length < 9 && gfrom.indexOf("#") === 0) {
        gfrom = Utils$1.hexToRgba(gfrom, opacityFrom);
      }
      if (gto.length < 9 && gto.indexOf("#") === 0) {
        gto = Utils$1.hexToRgba(gto, opacityTo);
      }
      let stop1 = 0;
      let stop2 = 1;
      let stop3 = 1;
      let stop4 = null;
      if (stops !== null) {
        stop1 = typeof stops[0] !== "undefined" ? stops[0] / 100 : 0;
        stop2 = typeof stops[1] !== "undefined" ? stops[1] / 100 : 1;
        stop3 = typeof stops[2] !== "undefined" ? stops[2] / 100 : 1;
        stop4 = typeof stops[3] !== "undefined" ? stops[3] / 100 : null;
      }
      const radial = !!(w.config.chart.type === "donut" || w.config.chart.type === "pie" || w.config.chart.type === "polarArea" || w.config.chart.type === "bubble");
      if (!colorStops || colorStops.length === 0) {
        g = w.dom.Paper.gradient(
          radial ? "radial" : "linear",
          (add) => {
            add.stop(stop1, gfrom, opacityFrom);
            add.stop(stop2, gto, opacityTo);
            add.stop(stop3, gto, opacityTo);
            if (stop4 !== null) {
              add.stop(stop4, gfrom, opacityFrom);
            }
          }
        );
      } else {
        g = w.dom.Paper.gradient(
          radial ? "radial" : "linear",
          (add) => {
            const gradientStops = Array.isArray(colorStops[i]) ? colorStops[i] : colorStops;
            gradientStops.forEach((s) => {
              add.stop(s.offset / 100, s.color, s.opacity);
            });
          }
        );
      }
      if (!radial) {
        if (style === "vertical") {
          g.from(0, 0).to(0, 1);
        } else if (style === "diagonal") {
          g.from(0, 0).to(1, 1);
        } else if (style === "horizontal") {
          g.from(0, 1).to(1, 1);
        } else if (style === "diagonal2") {
          g.from(1, 0).to(0, 1);
        }
      } else {
        const offx = w.layout.gridWidth / 2;
        const offy = w.layout.gridHeight / 2;
        if (w.config.chart.type !== "bubble") {
          g.attr({
            gradientUnits: "userSpaceOnUse",
            cx: offx,
            cy: offy,
            r: size
          });
        } else {
          g.attr({
            cx: 0.5,
            cy: 0.5,
            r: 0.8,
            fx: 0.2,
            fy: 0.2
          });
        }
      }
      return g;
    }
    /** @param {{ text: any, maxWidth: any, fontSize: any, fontFamily?: any }} opts */
    getTextBasedOnMaxWidth({ text, maxWidth, fontSize, fontFamily }) {
      const tRects = this.getTextRects(text, fontSize, fontFamily, "");
      const wordWidth = tRects.width / text.length;
      const wordsBasedOnWidth = Math.floor(maxWidth / wordWidth);
      if (maxWidth < tRects.width) {
        return text.slice(0, wordsBasedOnWidth - 3) + "...";
      }
      return text;
    }
    /**
     * @param {{ x: any, y: any, text: any, textAnchor?: any, fontSize?: any, fontFamily?: any, fontWeight?: any, foreColor?: any, opacity?: any, maxWidth?: any, cssClass?: string, isPlainText?: boolean, dominantBaseline?: string }} opts
     */
    drawText({
      x,
      y,
      text,
      textAnchor,
      fontSize,
      fontFamily,
      fontWeight,
      foreColor,
      opacity,
      maxWidth,
      cssClass = "",
      isPlainText = true,
      dominantBaseline = "auto"
    }) {
      const w = this.w;
      if (typeof text === "undefined") text = "";
      let truncatedText = text;
      if (!textAnchor) {
        textAnchor = "start";
      }
      if (!foreColor || !foreColor.length) {
        foreColor = w.config.chart.foreColor;
      }
      fontFamily = fontFamily || w.config.chart.fontFamily;
      fontSize = fontSize || "11px";
      fontWeight = fontWeight || "regular";
      const commonProps = {
        maxWidth,
        fontSize,
        fontFamily
      };
      let elText;
      if (Array.isArray(text)) {
        elText = w.dom.Paper.text((add) => {
          for (let i = 0; i < text.length; i++) {
            truncatedText = text[i];
            if (maxWidth) {
              truncatedText = this.getTextBasedOnMaxWidth(__spreadValues({
                text: text[i]
              }, commonProps));
            }
            i === 0 ? add.tspan(truncatedText) : add.tspan(truncatedText).newLine();
          }
        });
      } else {
        if (maxWidth) {
          truncatedText = this.getTextBasedOnMaxWidth(__spreadValues({
            text
          }, commonProps));
        }
        elText = isPlainText ? w.dom.Paper.plain(text) : (
          /**
           * @param {any} add
           */
          w.dom.Paper.text((add) => add.tspan(truncatedText))
        );
      }
      elText.attr({
        x,
        y,
        "text-anchor": textAnchor,
        "dominant-baseline": dominantBaseline,
        "font-size": fontSize,
        "font-family": fontFamily,
        "font-weight": fontWeight,
        fill: foreColor,
        class: "apexcharts-text " + cssClass
      });
      elText.node.style.fontFamily = fontFamily;
      elText.node.style.opacity = opacity;
      return elText;
    }
    /**
     * @param {number} x
     * @param {number} y
     * @param {string} type
     * @param {number} size
     */
    getMarkerPath(x, y, type, size) {
      let d = "";
      switch (type) {
        case "cross":
          size = size / 1.4;
          d = `M ${x - size} ${y - size} L ${x + size} ${y + size}  M ${x - size} ${y + size} L ${x + size} ${y - size}`;
          break;
        case "plus":
          size = size / 1.12;
          d = `M ${x - size} ${y} L ${x + size} ${y}  M ${x} ${y - size} L ${x} ${y + size}`;
          break;
        case "star":
        case "sparkle": {
          let points = 5;
          size = size * 1.15;
          if (type === "sparkle") {
            size = size / 1.1;
            points = 4;
          }
          const step = Math.PI / points;
          for (let i = 0; i <= 2 * points; i++) {
            const angle = i * step;
            const radius = i % 2 === 0 ? size : size / 2;
            const xPos = x + radius * Math.sin(angle);
            const yPos = y - radius * Math.cos(angle);
            d += (i === 0 ? "M" : "L") + xPos + "," + yPos;
          }
          d += "Z";
          break;
        }
        case "triangle":
          d = `M ${x} ${y - size} 
             L ${x + size} ${y + size} 
             L ${x - size} ${y + size} 
             Z`;
          break;
        case "square":
        case "rect":
          size = size / 1.125;
          d = `M ${x - size} ${y - size} 
           L ${x + size} ${y - size} 
           L ${x + size} ${y + size} 
           L ${x - size} ${y + size} 
           Z`;
          break;
        case "diamond":
          size = size * 1.05;
          d = `M ${x} ${y - size} 
             L ${x + size} ${y} 
             L ${x} ${y + size} 
             L ${x - size} ${y} 
            Z`;
          break;
        case "line":
          size = size / 1.1;
          d = `M ${x - size} ${y} 
           L ${x + size} ${y}`;
          break;
        case "circle":
        default:
          size = size * 2;
          d = `M ${x}, ${y} 
           m -${size / 2}, 0 
           a ${size / 2},${size / 2} 0 1,0 ${size},0 
           a ${size / 2},${size / 2} 0 1,0 -${size},0`;
          break;
      }
      return d;
    }
    /**
     * @param {number} x - The x-coordinate of the marker
     * @param {number} y - The y-coordinate of the marker
     * @param {string} type - Marker shape type
     * @param {number} size - The size of the marker
     * @param {Record<string, any>} opts - The options for the marker
     * @returns {any} The created marker.
     */
    drawMarkerShape(x, y, type, size, opts) {
      const path = this.drawPath({
        d: this.getMarkerPath(x, y, type, size),
        stroke: opts.pointStrokeColor,
        strokeDashArray: opts.pointStrokeDashArray,
        strokeWidth: opts.pointStrokeWidth,
        fill: opts.pointFillColor,
        fillOpacity: opts.pointFillOpacity,
        strokeOpacity: opts.pointStrokeOpacity
      });
      path.attr({
        cx: x,
        cy: y,
        shape: opts.shape,
        class: opts.class ? opts.class : ""
      });
      return path;
    }
    /**
     * @param {number} x
     * @param {number} y
     * @param {Record<string, any>} opts
     */
    drawMarker(x, y, opts) {
      x = x || 0;
      let size = opts.pSize || 0;
      if (!Utils$1.isNumber(y)) {
        size = 0;
        y = 0;
      }
      return this.drawMarkerShape(x, y, opts == null ? void 0 : opts.shape, size, __spreadValues(__spreadValues({}, opts), opts.shape === "line" || opts.shape === "plus" || opts.shape === "cross" ? {
        pointStrokeColor: opts.pointFillColor,
        pointStrokeOpacity: opts.pointFillOpacity
      } : {}));
    }
    /**
     * @param {any} path
     * @param {Event | null} [e]
     */
    pathMouseEnter(path, e) {
      var _a, _b;
      const w = this.w;
      const filters = new Filters(this.w);
      const i = parseInt((_a = path.node.getAttribute("index")) != null ? _a : "", 10);
      const j = parseInt((_b = path.node.getAttribute("j")) != null ? _b : "", 10);
      if (isNaN(i) || isNaN(j)) return;
      if (typeof w.config.chart.events.dataPointMouseEnter === "function") {
        w.config.chart.events.dataPointMouseEnter(e, this.ctx, {
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
      }
      Graphics._fireEvent(w, "dataPointMouseEnter", [
        e,
        this.ctx,
        { seriesIndex: i, dataPointIndex: j, w }
      ]);
      if (w.config.states.active.filter.type !== "none") {
        if (path.node.getAttribute("selected") === "true") {
          return;
        }
      }
      if (w.config.states.hover.filter.type !== "none") {
        if (!w.interact.isTouchDevice) {
          const hoverFilter = w.config.states.hover.filter;
          filters.applyFilter(path, i, hoverFilter.type);
        }
      }
    }
    /**
     * @param {any} path
     * @param {Event | null} [e]
     */
    pathMouseLeave(path, e) {
      var _a, _b;
      const w = this.w;
      const filters = new Filters(this.w);
      const i = parseInt((_a = path.node.getAttribute("index")) != null ? _a : "", 10);
      const j = parseInt((_b = path.node.getAttribute("j")) != null ? _b : "", 10);
      if (isNaN(i) || isNaN(j)) return;
      if (typeof w.config.chart.events.dataPointMouseLeave === "function") {
        w.config.chart.events.dataPointMouseLeave(e, this.ctx, {
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
      }
      Graphics._fireEvent(w, "dataPointMouseLeave", [
        e,
        this.ctx,
        { seriesIndex: i, dataPointIndex: j, w }
      ]);
      if (w.config.states.active.filter.type !== "none") {
        if (path.node.getAttribute("selected") === "true") {
          return;
        }
      }
      if (w.config.states.hover.filter.type !== "none") {
        filters.getDefaultFilter(path, i);
      }
    }
    /**
     * @param {any} path
     * @param {Event | null} e
     */
    pathMouseDown(path, e) {
      var _a, _b;
      const w = this.w;
      const filters = new Filters(this.w);
      const i = parseInt((_a = path.node.getAttribute("index")) != null ? _a : "", 10);
      const j = parseInt((_b = path.node.getAttribute("j")) != null ? _b : "", 10);
      if (isNaN(i) || isNaN(j)) return;
      let selected = "false";
      if (path.node.getAttribute("selected") === "true") {
        path.node.setAttribute("selected", "false");
        const index = w.interact.selectedDataPoints[i].indexOf(j);
        if (index > -1) {
          w.interact.selectedDataPoints[i].splice(index, 1);
        }
      } else {
        if (!w.config.states.active.allowMultipleDataPointsSelection && w.interact.selectedDataPoints.length > 0) {
          w.interact.selectedDataPoints = [];
          const elPaths = w.dom.Paper.find(
            ".apexcharts-series path:not(.apexcharts-decoration-element)"
          );
          const elCircles = w.dom.Paper.find(
            ".apexcharts-series circle:not(.apexcharts-decoration-element), .apexcharts-series rect:not(.apexcharts-decoration-element)"
          );
          const deSelect = (els) => {
            Array.prototype.forEach.call(els, (el) => {
              el.node.setAttribute("selected", "false");
              filters.getDefaultFilter(el, i);
            });
          };
          deSelect(elPaths);
          deSelect(elCircles);
        }
        path.node.setAttribute("selected", "true");
        selected = "true";
        if (typeof w.interact.selectedDataPoints[i] === "undefined") {
          w.interact.selectedDataPoints[i] = [];
        }
        w.interact.selectedDataPoints[i].push(j);
      }
      if (selected === "true") {
        const activeFilter = w.config.states.active.filter;
        if (activeFilter !== "none") {
          filters.applyFilter(path, i, activeFilter.type);
        } else {
          if (w.config.states.hover.filter !== "none") {
            if (!w.interact.isTouchDevice) {
              const hoverFilter = w.config.states.hover.filter;
              filters.applyFilter(path, i, hoverFilter.type);
            }
          }
        }
      } else {
        if (w.config.states.active.filter.type !== "none") {
          if (w.config.states.hover.filter.type !== "none" && !w.interact.isTouchDevice) {
            const hoverFilter = w.config.states.hover.filter;
            filters.applyFilter(path, i, hoverFilter.type);
          } else {
            filters.getDefaultFilter(path, i);
          }
        }
      }
      if (typeof w.config.chart.events.dataPointSelection === "function") {
        w.config.chart.events.dataPointSelection(e, this.ctx, {
          selectedDataPoints: w.interact.selectedDataPoints,
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
      }
      if (e) {
        Graphics._fireEvent(w, "dataPointSelection", [
          e,
          this.ctx,
          {
            selectedDataPoints: w.interact.selectedDataPoints,
            seriesIndex: i,
            dataPointIndex: j,
            w
          }
        ]);
      }
    }
    /**
     * @param {any} el
     * @returns {{ x: number, y: number }}
     */
    rotateAroundCenter(el) {
      let coord = (
        /** @type {any} */
        {}
      );
      if (el && typeof el.getBBox === "function") {
        coord = el.getBBox();
      }
      const x = coord.x + coord.width / 2;
      const y = coord.y + coord.height / 2;
      return {
        x,
        y
      };
    }
    /**
     * Sets up event delegation on a parent group element.
     * Uses mouseover/mouseout (which bubble) to simulate mouseenter/mouseleave
     * on matching child elements, reducing per-element listener overhead.
     * @param {any} parentGroup
     * @param {string} targetSelector
     */
    setupEventDelegation(parentGroup, targetSelector) {
      let currentHovered = null;
      parentGroup.node.addEventListener("mouseover", (e) => {
        const targetNode = Graphics._findDelegateTarget(
          e.target,
          parentGroup.node,
          targetSelector
        );
        if (!targetNode || targetNode === currentHovered) return;
        if (currentHovered && /** @type {any} */
        currentHovered.instance) {
          this.pathMouseLeave(
            /** @type {any} */
            currentHovered.instance,
            e
          );
        }
        currentHovered = targetNode;
        if (targetNode.instance) {
          this.pathMouseEnter(targetNode.instance, e);
        }
      });
      parentGroup.node.addEventListener("mouseout", (e) => {
        if (!currentHovered) return;
        const relatedNode = e.relatedTarget ? Graphics._findDelegateTarget(
          e.relatedTarget,
          parentGroup.node,
          targetSelector
        ) : null;
        if (relatedNode !== currentHovered) {
          if (currentHovered && /** @type {any} */
          currentHovered.instance) {
            this.pathMouseLeave(
              /** @type {any} */
              currentHovered.instance,
              e
            );
          }
          currentHovered = null;
        }
      });
      parentGroup.node.addEventListener("mousedown", (e) => {
        const targetNode = Graphics._findDelegateTarget(
          e.target,
          parentGroup.node,
          targetSelector
        );
        if (targetNode && targetNode.instance) {
          this.pathMouseDown(targetNode.instance, e);
        }
      });
    }
    // Fire a named event from w.globals.events without requiring a ctx reference.
    // Mirrors Events.fireEvent() but reads the registry directly from w so that
    // pathMouseEnter/Leave/Down work even when this.ctx is null (Graphics instances
    // created without a ctx arg for drawing-only use cases).
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {string} name
     * @param {any[]} args
     */
    static _fireEvent(w, name2, args) {
      const evs = w.globals.events;
      if (!evs || !Object.prototype.hasOwnProperty.call(evs, name2)) return;
      const handlers = (
        /** @type {Record<string,any>} */
        evs[name2]
      );
      for (let i = 0; i < handlers.length; i++) {
        handlers[i].apply(null, args);
      }
    }
    /**
     * @param {any} node
     * @param {Record<string, any>} boundary
     * @param {string} selector
     */
    static _findDelegateTarget(node, boundary, selector) {
      while (node && node !== boundary && node !== document) {
        if (node.matches && node.matches(selector)) return node;
        node = node.parentNode;
      }
      return null;
    }
    /**
     * @param {any} el
     * @param {Record<string, any>} attrs
     */
    static setAttrs(el, attrs) {
      for (const key in attrs) {
        if (Object.prototype.hasOwnProperty.call(attrs, key)) {
          el.setAttribute(key, attrs[key]);
        }
      }
    }
    /**
     * @param {string} text
     * @param {string} fontSize
     * @param {string | null | undefined} [fontFamily]
     * @param {string} [transform]
     * @returns {{ width: number, height: number }}
     */
    getTextRects(text, fontSize, fontFamily, transform, useBBox = true) {
      const w = this.w;
      const cacheKey = [text, fontSize, fontFamily, transform, useBBox].join("\0");
      const cache = w.globals.textRectsCache;
      if (cache && cache.has(cacheKey)) {
        return (
          /** @type {{ width: number, height: number }} */
          cache.get(cacheKey)
        );
      }
      const virtualText = this.drawText({
        x: -200,
        y: -200,
        text,
        textAnchor: "start",
        fontSize,
        fontFamily,
        foreColor: "#fff",
        opacity: 0
      });
      if (transform) {
        virtualText.attr("transform", transform);
      }
      w.dom.Paper.add(virtualText);
      let rect = virtualText.bbox();
      if (!useBBox) {
        rect = virtualText.node.getBoundingClientRect();
      }
      virtualText.remove();
      const result = {
        width: rect.width,
        height: rect.height
      };
      if (cache) {
        cache.set(cacheKey, result);
      }
      return result;
    }
    /**
     * append ... to long text
     * http://stackoverflow.com/questions/9241315/trimming-text-to-a-given-pixel-width-in-svg
     * @memberof Graphics
     * @param {Record<string, any>} textObj
     * @param {string} textString
     * @param {number} width
     **/
    placeTextWithEllipsis(textObj, textString, width) {
      if (typeof textObj.getComputedTextLength !== "function") return;
      textObj.textContent = textString;
      if (textString.length > 0) {
        if (textObj.getComputedTextLength() >= width / 1.1) {
          for (let x = textString.length - 3; x > 0; x -= 3) {
            if (textObj.getSubStringLength(0, x) <= width / 1.1) {
              textObj.textContent = textString.substring(0, x) + "...";
              return;
            }
          }
          textObj.textContent = ".";
        }
      }
    }
  }
  const SVGNS = "http://www.w3.org/2000/svg";
  class Point {
    /**
     * @param {number|{x:number,y:number}} x
     * @param {number} [y]
     */
    constructor(x, y) {
      if (typeof x === "object") {
        this.x = x.x;
        this.y = x.y;
      } else {
        this.x = x || 0;
        this.y = y || 0;
      }
    }
    /**
     * @param {Matrix} matrix
     */
    transform(matrix) {
      return matrix.apply(this);
    }
    clone() {
      return new Point(this.x, this.y);
    }
  }
  class Matrix {
    /**
     * @param {number} a
     * @param {number} b
     * @param {number} c
     * @param {number} d
     * @param {number} e
     * @param {number} f
     */
    constructor(a, b, c, d, e, f) {
      this.a = a != null ? a : 1;
      this.b = b != null ? b : 0;
      this.c = c != null ? c : 0;
      this.d = d != null ? d : 1;
      this.e = e != null ? e : 0;
      this.f = f != null ? f : 0;
    }
    /**
     * @param {number} deg
     */
    rotate(deg) {
      const rad = deg * Math.PI / 180;
      const cos = Math.cos(rad);
      const sin = Math.sin(rad);
      return this.multiply(new Matrix(cos, sin, -sin, cos, 0, 0));
    }
    /**
     * @param {number} sx
     * @param {number} sy
     */
    scale(sx, sy) {
      return this.multiply(new Matrix(sx, 0, 0, sy != null ? sy : sx, 0, 0));
    }
    /**
     * @param {Matrix} m
     */
    multiply(m) {
      return new Matrix(
        this.a * m.a + this.c * m.b,
        this.b * m.a + this.d * m.b,
        this.a * m.c + this.c * m.d,
        this.b * m.c + this.d * m.d,
        this.a * m.e + this.c * m.f + this.e,
        this.b * m.e + this.d * m.f + this.f
      );
    }
    /**
     * @param {Point} point
     */
    apply(point) {
      return new Point(
        this.a * point.x + this.c * point.y + this.e,
        this.b * point.x + this.d * point.y + this.f
      );
    }
  }
  class Box {
    /**
     * @param {number} x
     * @param {number} y
     * @param {number} w
     * @param {number} h
     */
    constructor(x, y, w, h) {
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
      this.width = w;
      this.height = h;
      this.x2 = x + w;
      this.y2 = y + h;
    }
  }
  class Fill {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this.opts = null;
      this.seriesIndex = 0;
      this.patternIDs = [];
    }
    /**
     * @param {Record<string, any>} params
     */
    clippedImgArea(params) {
      const w = this.w;
      const cnf = w.config;
      const svgW = parseInt(String(w.layout.gridWidth), 10);
      const svgH = parseInt(String(w.layout.gridHeight), 10);
      const size = svgW > svgH ? svgW : svgH;
      const fillImg = params.image;
      let imgWidth = 0;
      let imgHeight = 0;
      if (typeof params.width === "undefined" && typeof params.height === "undefined") {
        if (cnf.fill.image.width !== void 0 && cnf.fill.image.height !== void 0) {
          imgWidth = cnf.fill.image.width + 1;
          imgHeight = cnf.fill.image.height;
        } else {
          imgWidth = size + 1;
          imgHeight = size;
        }
      } else {
        imgWidth = params.width;
        imgHeight = params.height;
      }
      const elPattern = BrowserAPIs.createElementNS(SVGNS, "pattern");
      Graphics.setAttrs(elPattern, {
        id: params.patternID,
        patternUnits: params.patternUnits ? params.patternUnits : "userSpaceOnUse",
        width: imgWidth + "px",
        height: imgHeight + "px"
      });
      const elImage = BrowserAPIs.createElementNS(SVGNS, "image");
      elPattern.appendChild(elImage);
      const SVGLib = Environment.isBrowser() ? (
        /** @type {any} */
        window.SVG
      ) : (
        /** @type {any} */
        global.SVG
      );
      elImage.setAttributeNS(SVGLib.xlink, "href", fillImg);
      Graphics.setAttrs(elImage, {
        x: 0,
        y: 0,
        preserveAspectRatio: "none",
        width: imgWidth + "px",
        height: imgHeight + "px"
      });
      elImage.style.opacity = params.opacity;
      w.dom.elDefs.node.appendChild(elPattern);
    }
    /**
     * @param {Record<string, any>} opts
     */
    getSeriesIndex(opts) {
      const w = this.w;
      const cType = w.config.chart.type;
      if ((cType === "bar" || cType === "rangeBar") && w.config.plotOptions.bar.distributed || cType === "heatmap" || cType === "treemap") {
        this.seriesIndex = opts.seriesNumber;
      } else {
        this.seriesIndex = opts.seriesNumber % w.seriesData.series.length;
      }
      return this.seriesIndex;
    }
    /**
     * @param {number[]} data
     * @param {Record<string, any>} multiColorConfig
     */
    computeColorStops(data, multiColorConfig) {
      const w = this.w;
      let maxPositive = null;
      let minNegative = null;
      for (const value of data) {
        if (value >= multiColorConfig.threshold) {
          if (maxPositive === null || value > maxPositive) {
            maxPositive = value;
          }
        } else {
          if (minNegative === null || value < minNegative) {
            minNegative = value;
          }
        }
      }
      if (maxPositive === null) {
        maxPositive = multiColorConfig.threshold;
      }
      if (minNegative === null) {
        minNegative = multiColorConfig.threshold;
      }
      let totalRange = maxPositive - multiColorConfig.threshold + (multiColorConfig.threshold - minNegative);
      if (totalRange === 0) {
        totalRange = 1;
      }
      const negativePercentage = (multiColorConfig.threshold - minNegative) / totalRange * 100;
      let offset = 100 - negativePercentage;
      offset = Math.max(0, Math.min(offset, 100));
      return [
        {
          offset,
          color: multiColorConfig.colorAboveThreshold,
          opacity: w.config.fill.opacity
        },
        {
          offset: 0,
          color: multiColorConfig.colorBelowThreshold,
          opacity: w.config.fill.opacity
        }
      ];
    }
    /**
     * @param {Record<string, any>} opts
     */
    fillPath(opts) {
      var _a, _b, _c, _d;
      const w = this.w;
      this.opts = opts;
      const cnf = this.w.config;
      let pathFill;
      let patternFill, gradientFill;
      this.seriesIndex = this.getSeriesIndex(opts);
      const drawMultiColorLine = cnf.plotOptions.line.colors.colorAboveThreshold && cnf.plotOptions.line.colors.colorBelowThreshold;
      const fillColors = this.getFillColors();
      let fillColor = fillColors[this.seriesIndex];
      if (w.seriesData.seriesColors[this.seriesIndex] !== void 0) {
        fillColor = w.seriesData.seriesColors[this.seriesIndex];
      }
      if (typeof fillColor === "function") {
        fillColor = fillColor({
          seriesIndex: this.seriesIndex,
          dataPointIndex: opts.dataPointIndex,
          value: opts.value,
          w
        });
      }
      const fillType = opts.fillType ? opts.fillType : this.getFillType(this.seriesIndex);
      let fillOpacity = Array.isArray(cnf.fill.opacity) ? cnf.fill.opacity[this.seriesIndex] : cnf.fill.opacity;
      const useGradient = fillType === "gradient" || drawMultiColorLine;
      if (opts.color) {
        fillColor = opts.color;
      }
      const seriesItem = (
        /** @type {Record<string,any>} */
        w.config.series[this.seriesIndex]
      );
      if ((_b = (_a = seriesItem == null ? void 0 : seriesItem.data) == null ? void 0 : _a[opts.dataPointIndex]) == null ? void 0 : _b.fillColor) {
        fillColor = (_d = (_c = seriesItem == null ? void 0 : seriesItem.data) == null ? void 0 : _c[opts.dataPointIndex]) == null ? void 0 : _d.fillColor;
      }
      if (!fillColor) {
        fillColor = "#fff";
        console.warn("undefined color - ApexCharts");
      }
      if (opts.opacity !== void 0 && opts.opacity !== null) fillOpacity = opts.opacity;
      let defaultColor = fillColor;
      if (Utils$1.isCSSVariable(fillColor)) {
        defaultColor = Utils$1.applyOpacityToColor(fillColor, fillOpacity);
      } else if (fillColor.indexOf("rgb") === -1) {
        if (fillColor.indexOf("#") === -1) {
          defaultColor = fillColor;
        } else if (fillColor.length < 9) {
          defaultColor = Utils$1.hexToRgba(fillColor, fillOpacity);
        }
      } else {
        if (fillColor.indexOf("rgba") > -1) {
          fillOpacity = Utils$1.getOpacityFromRGBA(fillColor);
        } else {
          defaultColor = Utils$1.hexToRgba(Utils$1.rgb2hex(fillColor), fillOpacity);
        }
      }
      const resolvedFillColor = Utils$1.isCSSVariable(fillColor) ? Utils$1.getThemeColor(fillColor) : fillColor;
      if (fillType === "pattern") {
        patternFill = this.handlePatternFill({
          fillConfig: opts.fillConfig,
          patternFill,
          fillColor: resolvedFillColor,
          defaultColor
        });
      }
      if (useGradient) {
        const colorStops = cnf.fill.gradient.colorStops ? [...cnf.fill.gradient.colorStops] : [];
        let type = cnf.fill.gradient.type;
        if (drawMultiColorLine) {
          colorStops[this.seriesIndex] = this.computeColorStops(
            w.seriesData.series[this.seriesIndex],
            cnf.plotOptions.line.colors
          );
          type = "vertical";
        }
        gradientFill = this.handleGradientFill({
          type,
          fillConfig: opts.fillConfig,
          fillColor: resolvedFillColor,
          fillOpacity,
          colorStops,
          i: this.seriesIndex
        });
      }
      if (fillType === "image") {
        const imgSrc = cnf.fill.image.src;
        const patternID = opts.patternID ? opts.patternID : "";
        const patternKey = `pattern${w.globals.cuid}${opts.seriesNumber + 1}${patternID}`;
        if (this.patternIDs.indexOf(patternKey) === -1) {
          this.clippedImgArea({
            opacity: fillOpacity,
            image: Array.isArray(imgSrc) ? opts.seriesNumber < imgSrc.length ? imgSrc[opts.seriesNumber] : imgSrc[0] : imgSrc,
            width: opts.width ? opts.width : void 0,
            height: opts.height ? opts.height : void 0,
            patternUnits: opts.patternUnits,
            patternID: patternKey
          });
          this.patternIDs.push(patternKey);
        }
        pathFill = `url(#${patternKey})`;
      } else if (useGradient) {
        pathFill = gradientFill;
      } else if (fillType === "pattern") {
        pathFill = patternFill;
      } else {
        pathFill = defaultColor;
      }
      if (opts.solid) {
        pathFill = defaultColor;
      }
      return pathFill;
    }
    /**
     * @param {number} seriesIndex
     */
    getFillType(seriesIndex) {
      const w = this.w;
      if (Array.isArray(w.config.fill.type)) {
        return w.config.fill.type[seriesIndex];
      } else {
        return w.config.fill.type;
      }
    }
    getFillColors() {
      const w = this.w;
      const cnf = w.config;
      const opts = this.opts;
      let fillColors = [];
      if (w.globals.comboCharts) {
        if (
          /** @type {Record<string,any>} */
          w.config.series[this.seriesIndex].type === "line"
        ) {
          if (Array.isArray(w.globals.stroke.colors)) {
            fillColors = w.globals.stroke.colors;
          } else {
            fillColors.push(w.globals.stroke.colors);
          }
        } else {
          if (Array.isArray(w.globals.fill.colors)) {
            fillColors = w.globals.fill.colors;
          } else {
            fillColors.push(w.globals.fill.colors);
          }
        }
      } else {
        if (cnf.chart.type === "line") {
          if (Array.isArray(w.globals.stroke.colors)) {
            fillColors = w.globals.stroke.colors;
          } else {
            fillColors.push(w.globals.stroke.colors);
          }
        } else {
          if (Array.isArray(w.globals.fill.colors)) {
            fillColors = w.globals.fill.colors;
          } else {
            fillColors.push(w.globals.fill.colors);
          }
        }
      }
      if (typeof opts.fillColors !== "undefined") {
        fillColors = [];
        if (Array.isArray(opts.fillColors)) {
          fillColors = opts.fillColors.slice();
        } else {
          fillColors.push(opts.fillColors);
        }
      }
      return fillColors;
    }
    /** @param {{fillConfig: any, patternFill: any, fillColor: any, defaultColor: any}} opts */
    handlePatternFill({ fillConfig, patternFill, fillColor, defaultColor }) {
      let fillCnf = this.w.config.fill;
      if (fillConfig) {
        fillCnf = fillConfig;
      }
      const opts = this.opts;
      const graphics = new Graphics(this.w);
      const patternStrokeWidth = Array.isArray(fillCnf.pattern.strokeWidth) ? fillCnf.pattern.strokeWidth[this.seriesIndex] : fillCnf.pattern.strokeWidth;
      const patternLineColor = fillColor;
      if (Array.isArray(fillCnf.pattern.style)) {
        if (typeof fillCnf.pattern.style[opts.seriesNumber] !== "undefined") {
          const pf = graphics.drawPattern(
            fillCnf.pattern.style[opts.seriesNumber],
            fillCnf.pattern.width,
            fillCnf.pattern.height,
            patternLineColor,
            patternStrokeWidth
          );
          patternFill = pf;
        } else {
          patternFill = defaultColor;
        }
      } else {
        patternFill = graphics.drawPattern(
          fillCnf.pattern.style,
          fillCnf.pattern.width,
          fillCnf.pattern.height,
          patternLineColor,
          patternStrokeWidth
        );
      }
      return patternFill;
    }
    handleGradientFill({
      type,
      fillColor,
      fillOpacity,
      fillConfig,
      colorStops,
      i
    }) {
      let fillCnf = this.w.config.fill;
      if (fillConfig) {
        fillCnf = __spreadValues(__spreadValues({}, fillCnf), fillConfig);
      }
      const opts = this.opts;
      const graphics = new Graphics(this.w);
      const utils = new Utils$1();
      type = type || fillCnf.gradient.type;
      let gradientFrom = fillColor;
      let gradientTo;
      let opacityFrom = fillCnf.gradient.opacityFrom === void 0 ? fillOpacity : Array.isArray(fillCnf.gradient.opacityFrom) ? fillCnf.gradient.opacityFrom[i] : fillCnf.gradient.opacityFrom;
      if (gradientFrom.indexOf("rgba") > -1) {
        opacityFrom = Utils$1.getOpacityFromRGBA(gradientFrom);
      }
      let opacityTo = fillCnf.gradient.opacityTo === void 0 ? fillOpacity : Array.isArray(fillCnf.gradient.opacityTo) ? fillCnf.gradient.opacityTo[i] : fillCnf.gradient.opacityTo;
      if (fillCnf.gradient.gradientToColors === void 0 || fillCnf.gradient.gradientToColors.length === 0) {
        if (fillCnf.gradient.shade === "dark") {
          gradientTo = utils.shadeColor(
            parseFloat(fillCnf.gradient.shadeIntensity) * -1,
            fillColor.indexOf("rgb") > -1 ? Utils$1.rgb2hex(fillColor) : fillColor
          );
        } else {
          gradientTo = utils.shadeColor(
            parseFloat(fillCnf.gradient.shadeIntensity),
            fillColor.indexOf("rgb") > -1 ? Utils$1.rgb2hex(fillColor) : fillColor
          );
        }
      } else {
        if (fillCnf.gradient.gradientToColors[opts.seriesNumber]) {
          const gToColor = fillCnf.gradient.gradientToColors[opts.seriesNumber];
          gradientTo = gToColor;
          if (gToColor.indexOf("rgba") > -1) {
            opacityTo = Utils$1.getOpacityFromRGBA(gToColor);
          }
        } else {
          gradientTo = fillColor;
        }
      }
      if (fillCnf.gradient.gradientFrom) {
        gradientFrom = fillCnf.gradient.gradientFrom;
      }
      if (fillCnf.gradient.gradientTo) {
        gradientTo = fillCnf.gradient.gradientTo;
      }
      if (fillCnf.gradient.inverseColors) {
        const t = gradientFrom;
        gradientFrom = gradientTo;
        gradientTo = t;
      }
      if (gradientFrom.indexOf("rgb") > -1) {
        gradientFrom = Utils$1.rgb2hex(gradientFrom);
      }
      if (gradientTo.indexOf("rgb") > -1) {
        gradientTo = Utils$1.rgb2hex(gradientTo);
      }
      return graphics.drawGradient(
        type,
        gradientFrom,
        gradientTo,
        opacityFrom,
        opacityTo,
        opts.size,
        fillCnf.gradient.stops,
        colorStops,
        i
      );
    }
  }
  class Markers {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this._filters = new Filters(this.w);
      this._graphics = new Graphics(this.w, this.ctx);
    }
    setGlobalMarkerSize() {
      const w = this.w;
      w.globals.markers.size = Array.isArray(w.config.markers.size) ? w.config.markers.size : [w.config.markers.size];
      if (w.globals.markers.size.length > 0) {
        if (w.globals.markers.size.length < w.seriesData.series.length + 1) {
          for (let i = 0; i <= w.seriesData.series.length; i++) {
            if (typeof w.globals.markers.size[i] === "undefined") {
              w.globals.markers.size.push(w.globals.markers.size[0]);
            }
          }
        }
      } else {
        w.globals.markers.size = w.config.series.map(
          () => (
            /** @type {number} */
            w.config.markers.size
          )
        );
      }
    }
    /** @param {{ pointsPos?: any, seriesIndex?: any, j?: any, pSize?: any, alwaysDrawMarker?: boolean, isVirtualPoint?: boolean }} opts */
    plotChartMarkers({
      pointsPos,
      seriesIndex,
      j,
      pSize,
      alwaysDrawMarker = false,
      isVirtualPoint = false
    }) {
      const w = this.w;
      const i = seriesIndex;
      const p = pointsPos;
      let elMarkersWrap = null;
      const graphics = new Graphics(this.w);
      const hasDiscreteMarkers = w.config.markers.discrete && w.config.markers.discrete.length;
      if (Array.isArray(p.x)) {
        for (let q = 0; q < p.x.length; q++) {
          let markerElement;
          let dataPointIndex = j;
          let invalidMarker = !Utils$1.isNumber(p.y[q]);
          if (w.globals.markers.largestSize === 0 && w.globals.hasNullValues && w.seriesData.series[i][j + 1] !== null && !isVirtualPoint) {
            invalidMarker = true;
          }
          if (j === 1 && q === 0) dataPointIndex = 0;
          if (j === 1 && q === 1) dataPointIndex = 1;
          let markerClasses = "apexcharts-marker";
          if ((w.config.chart.type === "line" || w.config.chart.type === "area") && !w.globals.comboCharts && !w.config.tooltip.intersect) {
            markerClasses += " no-pointer-events";
          }
          const shouldMarkerDraw = Array.isArray(w.config.markers.size) ? w.globals.markers.size[seriesIndex] > 0 : w.config.markers.size > 0;
          if (shouldMarkerDraw || alwaysDrawMarker || hasDiscreteMarkers) {
            if (!invalidMarker) {
              markerClasses += ` w${Utils$1.randomId()}`;
            }
            const opts = this.getMarkerConfig({
              cssClass: markerClasses,
              seriesIndex,
              dataPointIndex
            });
            const _si = (
              /** @type {Record<string,any>} */
              w.config.series[i]
            );
            if (_si.data[dataPointIndex]) {
              if (_si.data[dataPointIndex].fillColor) {
                opts.pointFillColor = _si.data[dataPointIndex].fillColor;
              }
              if (_si.data[dataPointIndex].strokeColor) {
                opts.pointStrokeColor = _si.data[dataPointIndex].strokeColor;
              }
            }
            if (typeof pSize !== "undefined") {
              opts.pSize = pSize;
            }
            if (p.x[q] < -w.globals.markers.largestSize || p.x[q] > w.layout.gridWidth + w.globals.markers.largestSize || p.y[q] < -w.globals.markers.largestSize || p.y[q] > w.layout.gridHeight + w.globals.markers.largestSize) {
              opts.pSize = 0;
            }
            if (!invalidMarker) {
              const shouldCreateMarkerWrap = w.globals.markers.size[seriesIndex] > 0 || alwaysDrawMarker || hasDiscreteMarkers;
              if (shouldCreateMarkerWrap && !elMarkersWrap) {
                elMarkersWrap = graphics.group({
                  class: alwaysDrawMarker || hasDiscreteMarkers ? "" : "apexcharts-series-markers"
                });
                elMarkersWrap.attr(
                  "clip-path",
                  `url(#gridRectMarkerMask${w.globals.cuid})`
                );
                this.setupMarkerDelegation(elMarkersWrap);
              }
              markerElement = graphics.drawMarker(p.x[q], p.y[q], opts);
              markerElement.attr("rel", dataPointIndex);
              markerElement.attr("j", dataPointIndex);
              markerElement.attr("index", seriesIndex);
              markerElement.node.setAttribute("default-marker-size", opts.pSize);
              this._filters.setSelectionFilter(
                markerElement,
                seriesIndex,
                dataPointIndex
              );
              if (elMarkersWrap) {
                elMarkersWrap.add(markerElement);
              }
            }
          } else {
            if (typeof w.globals.pointsArray[seriesIndex] === "undefined")
              w.globals.pointsArray[seriesIndex] = [];
            w.globals.pointsArray[seriesIndex].push([p.x[q], p.y[q]]);
          }
        }
      }
      return elMarkersWrap;
    }
    /** @param {{cssClass: any, seriesIndex: any, dataPointIndex?: any, radius?: any, size?: any, strokeWidth?: any}} opts */
    getMarkerConfig({
      cssClass,
      seriesIndex,
      dataPointIndex = null,
      radius = null,
      size = null,
      strokeWidth = null
    }) {
      const w = this.w;
      const pStyle = this.getMarkerStyle(seriesIndex);
      let pSize = size === null ? w.globals.markers.size[seriesIndex] : size;
      const m = w.config.markers;
      if (dataPointIndex !== null && m.discrete.length) {
        m.discrete.map((marker) => {
          if (marker.seriesIndex === seriesIndex && marker.dataPointIndex === dataPointIndex) {
            pStyle.pointStrokeColor = marker.strokeColor;
            pStyle.pointFillColor = marker.fillColor;
            pSize = marker.size;
            pStyle.pointShape = marker.shape;
          }
        });
      }
      return {
        pSize: radius === null ? pSize : radius,
        pRadius: radius !== null ? radius : m.radius,
        pointStrokeWidth: strokeWidth !== null ? strokeWidth : Array.isArray(m.strokeWidth) ? m.strokeWidth[seriesIndex] : m.strokeWidth,
        pointStrokeColor: pStyle.pointStrokeColor,
        pointFillColor: pStyle.pointFillColor,
        shape: pStyle.pointShape || (Array.isArray(m.shape) ? m.shape[seriesIndex] : m.shape),
        class: cssClass,
        pointStrokeOpacity: Array.isArray(m.strokeOpacity) ? m.strokeOpacity[seriesIndex] : m.strokeOpacity,
        pointStrokeDashArray: Array.isArray(m.strokeDashArray) ? m.strokeDashArray[seriesIndex] : m.strokeDashArray,
        pointFillOpacity: Array.isArray(m.fillOpacity) ? m.fillOpacity[seriesIndex] : m.fillOpacity,
        seriesIndex
      };
    }
    /**
     * @param {any} parentGroup
     */
    setupMarkerDelegation(parentGroup) {
      const w = this.w;
      const selector = ".apexcharts-marker";
      this._graphics.setupEventDelegation(parentGroup, selector);
      parentGroup.node.addEventListener("click", (e) => {
        if (w.config.markers.onClick) {
          const targetNode = Graphics._findDelegateTarget(
            e.target,
            parentGroup.node,
            selector
          );
          if (targetNode) w.config.markers.onClick(e);
        }
      });
      parentGroup.node.addEventListener("dblclick", (e) => {
        if (w.config.markers.onDblClick) {
          const targetNode = Graphics._findDelegateTarget(
            e.target,
            parentGroup.node,
            selector
          );
          if (targetNode) w.config.markers.onDblClick(e);
        }
      });
      parentGroup.node.addEventListener(
        "touchstart",
        (e) => {
          const targetNode = Graphics._findDelegateTarget(
            e.target,
            parentGroup.node,
            selector
          );
          if (targetNode && targetNode.instance) {
            this._graphics.pathMouseDown(targetNode.instance, e);
          }
        },
        { passive: true }
      );
    }
    /**
     * @param {any} marker
     */
    addEvents(marker) {
      const w = this.w;
      marker.node.addEventListener(
        "mouseenter",
        this._graphics.pathMouseEnter.bind(this.ctx, marker)
      );
      marker.node.addEventListener(
        "mouseleave",
        this._graphics.pathMouseLeave.bind(this.ctx, marker)
      );
      marker.node.addEventListener(
        "mousedown",
        this._graphics.pathMouseDown.bind(this.ctx, marker)
      );
      marker.node.addEventListener("click", w.config.markers.onClick);
      marker.node.addEventListener("dblclick", w.config.markers.onDblClick);
      marker.node.addEventListener(
        "touchstart",
        this._graphics.pathMouseDown.bind(this.ctx, marker),
        { passive: true }
      );
    }
    /**
     * @returns {any}
     * @param {number} seriesIndex
     */
    getMarkerStyle(seriesIndex) {
      const w = this.w;
      const colors = w.globals.markers.colors;
      const strokeColors = w.config.markers.strokeColor || w.config.markers.strokeColors;
      const pointStrokeColor = Array.isArray(strokeColors) ? strokeColors[seriesIndex] : strokeColors;
      const pointFillColor = Array.isArray(colors) ? colors[seriesIndex] : colors;
      return {
        pointStrokeColor,
        pointFillColor
      };
    }
  }
  class Scatter {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.ctx = ctx;
      this.w = w;
      this.initialAnim = this.w.config.chart.animations.enabled;
      this.anim = new Animations(this.w);
      this.filters = new Filters(this.w);
      this.fill = new Fill(this.w);
      this.markers = new Markers(this.w, this.ctx);
      this.graphics = new Graphics(this.w);
    }
    /**
     * @param {Element} elSeries
     * @param {number} j
     * @param {Record<string, any>} opts
     */
    draw(elSeries, j, opts) {
      const w = this.w;
      const graphics = this.graphics;
      const realIndex = opts.realIndex;
      const pointsPos = opts.pointsPos;
      const zRatio = opts.zRatio;
      const elPointsMain = opts.elParent;
      const elPointsWrap = graphics.group({
        class: `apexcharts-series-markers apexcharts-series-${w.config.chart.type}`
      });
      elPointsWrap.attr("clip-path", `url(#gridRectMarkerMask${w.globals.cuid})`);
      this.markers.setupMarkerDelegation(elPointsWrap);
      if (Array.isArray(pointsPos.x)) {
        for (let q = 0; q < pointsPos.x.length; q++) {
          let dataPointIndex = j + 1;
          let shouldDraw = true;
          if (j === 0 && q === 0) dataPointIndex = 0;
          if (j === 0 && q === 1) dataPointIndex = 1;
          let radius = w.globals.markers.size[realIndex];
          if (zRatio !== Infinity) {
            const bubble = w.config.plotOptions.bubble;
            radius = w.seriesData.seriesZ[realIndex][dataPointIndex];
            if (bubble.zScaling) {
              radius /= zRatio;
            }
            if (bubble.minBubbleRadius && radius < bubble.minBubbleRadius) {
              radius = bubble.minBubbleRadius;
            }
            if (bubble.maxBubbleRadius && radius > bubble.maxBubbleRadius) {
              radius = bubble.maxBubbleRadius;
            }
          }
          const x = pointsPos.x[q];
          const y = pointsPos.y[q];
          radius = radius || 0;
          if (y === null || typeof w.seriesData.series[realIndex][dataPointIndex] === "undefined") {
            shouldDraw = false;
          }
          if (shouldDraw) {
            const point = this.drawPoint(
              x,
              y,
              radius,
              realIndex,
              dataPointIndex,
              j
            );
            elPointsWrap.add(point);
          }
          elPointsMain.add(elPointsWrap);
        }
      }
    }
    /**
     * @param {number} x
     * @param {number} y
     * @param {number} radius
     * @param {number} realIndex
     * @param {number} dataPointIndex
     * @param {number} j
     */
    drawPoint(x, y, radius, realIndex, dataPointIndex, j) {
      const w = this.w;
      const i = realIndex;
      const anim = this.anim;
      const filters = this.filters;
      const fill = this.fill;
      const markers = this.markers;
      const graphics = this.graphics;
      const markerConfig = markers.getMarkerConfig({
        cssClass: "apexcharts-marker",
        seriesIndex: i,
        dataPointIndex,
        radius: w.config.chart.type === "bubble" || w.globals.comboCharts && w.config.series[realIndex] && /** @type {Record<string,any>} */
        w.config.series[realIndex].type === "bubble" ? radius : null
      });
      let pathFillCircle = fill.fillPath({
        seriesNumber: realIndex,
        dataPointIndex,
        color: markerConfig.pointFillColor,
        patternUnits: "objectBoundingBox",
        value: w.seriesData.series[realIndex][j]
      });
      const el = graphics.drawMarker(x, y, markerConfig);
      const _si = (
        /** @type {Record<string,any>} */
        w.config.series[i]
      );
      if (_si.data[dataPointIndex]) {
        if (_si.data[dataPointIndex].fillColor) {
          pathFillCircle = _si.data[dataPointIndex].fillColor;
        }
      }
      el.attr({
        fill: pathFillCircle
      });
      if (w.config.chart.dropShadow.enabled) {
        const dropShadow = w.config.chart.dropShadow;
        filters.dropShadow(el, dropShadow, realIndex);
      }
      if (this.initialAnim && !w.globals.dataChanged && !w.globals.resized) {
        const speed = w.config.chart.animations.speed;
        anim.animateMarker(
          el,
          speed,
          /** @type {any} */
          w.globals.easing,
          () => {
            window.setTimeout(() => {
              anim.animationCompleted(el);
            }, 100);
          }
        );
      } else {
        w.globals.animationEnded = true;
      }
      el.attr({
        rel: dataPointIndex,
        j: dataPointIndex,
        index: realIndex,
        "default-marker-size": markerConfig.pSize
      });
      filters.setSelectionFilter(el, realIndex, dataPointIndex);
      el.node.classList.add("apexcharts-marker");
      return el;
    }
    /**
     * @param {number} y
     */
    centerTextInBubble(y) {
      const w = this.w;
      y = y + parseInt(w.config.dataLabels.style.fontSize, 10) / 4;
      return {
        y
      };
    }
  }
  class DataLabels {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext | null} ctx
     */
    constructor(w, ctx = null) {
      this.w = w;
      this.ctx = ctx;
    }
    // When there are many datalabels to be printed, and some of them overlaps each other in the same series, this method will take care of that
    // Also, when datalabels exceeds the drawable area and get clipped off, we need to adjust and move some pixels to make them visible again
    /**
     * @param {number} x
     * @param {number} y
     * @param {any} val
     * @param {number} i
     * @param {number} dataPointIndex
     * @param {boolean} alwaysDrawDataLabel
     * @param {string} fontSize
     */
    dataLabelsCorrection(x, y, val, i, dataPointIndex, alwaysDrawDataLabel, fontSize) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      let drawnextLabel = false;
      const textRects = (
        /** @type {any} */
        graphics.getTextRects(val, fontSize)
      );
      const width = textRects.width;
      const height = textRects.height;
      if (y < 0) y = 0;
      if (y > w.layout.gridHeight + height) y = w.layout.gridHeight + height / 2;
      if (typeof /** @type {any} */
      w.globals.dataLabelsRects[i] === "undefined") {
        w.globals.dataLabelsRects[i] = [];
      }
      w.globals.dataLabelsRects[i].push({
        x,
        y,
        width,
        height
      });
      const len = (
        /** @type {any} */
        w.globals.dataLabelsRects[i].length - 2
      );
      const lastDrawnIndex = typeof w.globals.lastDrawnDataLabelsIndexes[i] !== "undefined" ? w.globals.lastDrawnDataLabelsIndexes[i][w.globals.lastDrawnDataLabelsIndexes[i].length - 1] : 0;
      if (typeof /** @type {any} */
      w.globals.dataLabelsRects[i][len] !== "undefined") {
        const lastDataLabelRect = (
          /** @type {any} */
          w.globals.dataLabelsRects[i][lastDrawnIndex]
        );
        if (
          // next label forward and x not intersecting
          x > lastDataLabelRect.x + lastDataLabelRect.width || y > lastDataLabelRect.y + lastDataLabelRect.height || y + height < lastDataLabelRect.y || x + width < lastDataLabelRect.x
        ) {
          drawnextLabel = true;
        }
      }
      if (dataPointIndex === 0 || alwaysDrawDataLabel) {
        drawnextLabel = true;
      }
      return {
        x,
        y,
        textRects,
        drawnextLabel
      };
    }
    /** @param {{type: any, pos: any, i: any, j: any, isRangeStart: any, strokeWidth?: any}} opts */
    drawDataLabel({ type, pos, i, j, isRangeStart, strokeWidth = 2 }) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const dataLabelsConfig = w.config.dataLabels;
      let x = 0;
      let y = 0;
      let dataPointIndex = j;
      let elDataLabelsWrap = null;
      const seriesCollapsed = w.globals.collapsedSeriesIndices.indexOf(i) !== -1;
      if (seriesCollapsed || !dataLabelsConfig.enabled || !Array.isArray(pos.x)) {
        return elDataLabelsWrap;
      }
      elDataLabelsWrap = graphics.group({
        class: "apexcharts-data-labels"
      });
      for (let q = 0; q < pos.x.length; q++) {
        x = pos.x[q] + dataLabelsConfig.offsetX;
        y = pos.y[q] + dataLabelsConfig.offsetY + strokeWidth;
        if (!isNaN(x)) {
          if (j === 1 && q === 0) dataPointIndex = 0;
          if (j === 1 && q === 1) dataPointIndex = 1;
          let val = w.seriesData.series[i][dataPointIndex];
          if (type === "rangeArea") {
            if (isRangeStart) {
              val = w.rangeData.seriesRangeStart[i][dataPointIndex];
            } else {
              val = w.rangeData.seriesRangeEnd[i][dataPointIndex];
            }
          }
          let text = "";
          const getText = (v) => {
            return w.config.dataLabels.formatter(v, {
              seriesIndex: i,
              dataPointIndex,
              w
            });
          };
          if (w.config.chart.type === "bubble") {
            val = w.seriesData.seriesZ[i][dataPointIndex];
            text = getText(val);
            y = pos.y[q];
            const scatter = new Scatter(
              this.w,
              /** @type {import('../types/internal').ChartContext} */
              this.ctx
            );
            const centerTextInBubbleCoords = scatter.centerTextInBubble(y);
            y = centerTextInBubbleCoords.y;
          } else {
            if (typeof val !== "undefined") {
              text = getText(val);
            }
          }
          let textAnchor = w.config.dataLabels.textAnchor;
          if (w.globals.isSlopeChart) {
            if (dataPointIndex === 0) {
              textAnchor = "end";
            } else if (dataPointIndex === /** @type {Record<string,any>} */
            w.config.series[i].data.length - 1) {
              textAnchor = "start";
            } else {
              textAnchor = "middle";
            }
          }
          this.plotDataLabelsText({
            x,
            y,
            text,
            i,
            j: dataPointIndex,
            parent: elDataLabelsWrap,
            offsetCorrection: true,
            dataLabelsConfig: w.config.dataLabels,
            textAnchor
          });
        }
      }
      return elDataLabelsWrap;
    }
    /**
     * @param {Record<string, any>} opts
     */
    plotDataLabelsText(opts) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      let {
        x,
        y,
        i,
        j,
        text,
        textAnchor,
        fontSize,
        parent,
        dataLabelsConfig,
        color,
        alwaysDrawDataLabel,
        offsetCorrection,
        className
      } = opts;
      let dataLabelText = null;
      if (Array.isArray(w.config.dataLabels.enabledOnSeries)) {
        if (w.config.dataLabels.enabledOnSeries.indexOf(i) < 0) {
          return dataLabelText;
        }
      }
      let correctedLabels = {
        x,
        y,
        drawnextLabel: true,
        textRects: null
      };
      if (offsetCorrection) {
        correctedLabels = this.dataLabelsCorrection(
          x,
          y,
          text,
          i,
          j,
          alwaysDrawDataLabel,
          parseInt(
            /** @type {any} */
            dataLabelsConfig.style.fontSize,
            10
          ).toString()
        );
      }
      if (!w.interact.zoomed) {
        x = correctedLabels.x;
        y = correctedLabels.y;
      }
      if (correctedLabels.textRects) {
        const barPad = w.globals.barPadForNumericAxis || 0;
        if (x < -(barPad + 20) - /** @type {any} */
        correctedLabels.textRects.width || x > w.layout.gridWidth + /** @type {any} */
        correctedLabels.textRects.width + barPad + 30) {
          text = "";
        }
      }
      let dataLabelColor = w.globals.dataLabels.style.colors[i];
      if ((w.config.chart.type === "bar" || w.config.chart.type === "rangeBar") && w.config.plotOptions.bar.distributed || w.config.dataLabels.distributed) {
        dataLabelColor = w.globals.dataLabels.style.colors[j];
      }
      if (typeof dataLabelColor === "function") {
        dataLabelColor = /** @type {any} */
        dataLabelColor({
          series: w.seriesData.series,
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
      }
      if (color) {
        dataLabelColor = color;
      }
      let offX = dataLabelsConfig.offsetX;
      let offY = dataLabelsConfig.offsetY;
      if (w.config.chart.type === "bar" || w.config.chart.type === "rangeBar") {
        offX = 0;
        offY = 0;
      }
      if (w.globals.isSlopeChart) {
        if (j !== 0) {
          offX = dataLabelsConfig.offsetX * -2 + 5;
        }
        if (j !== 0 && j !== /** @type {Record<string,any>} */
        w.config.series[i].data.length - 1) {
          offX = 0;
        }
      }
      if (correctedLabels.drawnextLabel) {
        if (textAnchor === "middle") {
          if (x === w.layout.gridWidth) {
            textAnchor = "end";
          }
        }
        dataLabelText = graphics.drawText({
          x: x + offX,
          y: y + offY,
          foreColor: dataLabelColor,
          textAnchor: textAnchor || dataLabelsConfig.textAnchor,
          text,
          fontSize: fontSize || dataLabelsConfig.style.fontSize,
          fontFamily: dataLabelsConfig.style.fontFamily,
          fontWeight: dataLabelsConfig.style.fontWeight || "normal"
        });
        dataLabelText.attr({
          class: className || "apexcharts-datalabel",
          cx: x,
          cy: y
        });
        if (dataLabelsConfig.dropShadow.enabled) {
          const textShadow = dataLabelsConfig.dropShadow;
          const filters = new Filters(this.w);
          filters.dropShadow(dataLabelText, textShadow);
        }
        parent.add(dataLabelText);
        if (typeof w.globals.lastDrawnDataLabelsIndexes[i] === "undefined") {
          w.globals.lastDrawnDataLabelsIndexes[i] = [];
        }
        w.globals.lastDrawnDataLabelsIndexes[i].push(j);
      }
      return dataLabelText;
    }
    /**
     * @param {Element} el
     * @param {{x: number, y: number, width: number, height: number}} coords
     */
    addBackgroundToDataLabel(el, coords) {
      const w = this.w;
      const bCnf = w.config.dataLabels.background;
      const paddingH = bCnf.padding;
      const paddingV = bCnf.padding / 2;
      const width = coords.width;
      const height = coords.height;
      const graphics = new Graphics(this.w);
      const elRect = graphics.drawRect(
        coords.x - paddingH,
        coords.y - paddingV / 2,
        width + paddingH * 2,
        height + paddingV,
        bCnf.borderRadius,
        w.config.chart.background === "transparent" || !w.config.chart.background ? "#fff" : w.config.chart.background,
        bCnf.opacity,
        bCnf.borderWidth,
        bCnf.borderColor
      );
      if (bCnf.dropShadow.enabled) {
        const filters = new Filters(this.w);
        filters.dropShadow(elRect, bCnf.dropShadow);
      }
      return elRect;
    }
    dataLabelsBackground() {
      var _a;
      const w = this.w;
      if (w.config.chart.type === "bubble") return;
      const elDataLabels = w.dom.baseEl.querySelectorAll(
        ".apexcharts-datalabels text"
      );
      for (let i = 0; i < elDataLabels.length; i++) {
        const el = elDataLabels[i];
        const coords = (
          /** @type {SVGGraphicsElement} */
          el.getBBox()
        );
        let elRect = null;
        if (coords.width && coords.height) {
          elRect = this.addBackgroundToDataLabel(el, coords);
        }
        if (elRect) {
          (_a = el.parentNode) == null ? void 0 : _a.insertBefore(elRect.node, el);
          const background = w.config.dataLabels.background.backgroundColor || el.getAttribute("fill");
          const shouldAnim = w.config.chart.animations.enabled && !w.globals.resized && !w.globals.dataChanged;
          if (shouldAnim) {
            elRect.animate().attr({ fill: background });
          } else {
            elRect.attr({ fill: background });
          }
          el.setAttribute("fill", w.config.dataLabels.background.foreColor);
        }
      }
    }
    bringForward() {
      const w = this.w;
      const elDataLabelsNodes = w.dom.baseEl.querySelectorAll(
        ".apexcharts-datalabels"
      );
      const elSeries = w.dom.baseEl.querySelector(
        ".apexcharts-plot-series:last-child"
      );
      for (let i = 0; i < elDataLabelsNodes.length; i++) {
        if (elSeries) {
          elSeries.insertBefore(elDataLabelsNodes[i], elSeries.nextSibling);
        }
      }
    }
  }
  class PerformanceCache {
    /**
     * Invalidate all caches
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     */
    static invalidateAll(w) {
      if (!w || !w.globals) return;
      if (w.globals.cachedSelectors) {
        w.globals.cachedSelectors = {};
      }
      if (w.globals.domCache) {
        w.globals.domCache.clear();
      }
      w.globals.dimensionCache = {};
    }
    /**
     * Invalidate dimension cache only
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     */
    static invalidateDimensions(w) {
      if (!w || !w.globals) return;
      w.globals.dimensionCache = {};
    }
    /**
     * Invalidate selector cache only
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     */
    static invalidateSelectors(w) {
      if (!w || !w.globals) return;
      if (w.globals.cachedSelectors) {
        w.globals.cachedSelectors = {};
      }
    }
    /**
     * Get cached selector result or compute and cache it
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     * @param {string} key - Cache key
     * @param {Function} queryFn - Function to execute if not cached
     * @returns {*} Cached or newly computed result
     */
    static getCachedSelector(w, key, queryFn) {
      if (!w || !w.globals) return queryFn();
      if (!w.globals.cachedSelectors) {
        w.globals.cachedSelectors = {};
      }
      if (!w.globals.cachedSelectors[key]) {
        w.globals.cachedSelectors[key] = queryFn();
      }
      return w.globals.cachedSelectors[key];
    }
    /**
     * Get cached dimension or compute and cache it
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     * @param {string} key - Cache key
     * @param {Function} computeFn - Function to compute dimensions
     * @param {number} maxAge - Maximum cache age in milliseconds (default: 1000ms)
     * @returns {*} Cached or newly computed dimensions
     */
    static getCachedDimension(w, key, computeFn, maxAge = 1e3) {
      if (!w || !w.globals) return computeFn();
      if (!w.globals.dimensionCache) {
        w.globals.dimensionCache = {};
      }
      const cache = w.globals.dimensionCache[key];
      const now = Date.now();
      if (cache && cache.lastUpdate && now - cache.lastUpdate < maxAge) {
        return cache.value;
      }
      const value = computeFn();
      w.globals.dimensionCache[key] = {
        value,
        lastUpdate: now
      };
      return value;
    }
    /**
     * Cache a DOM element reference
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     * @param {string} key - Cache key
     * @param {Element} element - DOM element to cache
     */
    static cacheDOMElement(w, key, element) {
      if (!w || !w.globals) return;
      if (!w.globals.domCache) {
        w.globals.domCache = /* @__PURE__ */ new Map();
      }
      w.globals.domCache.set(key, element);
    }
    /**
     * Get cached DOM element
     * @param {import('../types/internal').ChartStateW} w - ApexCharts state object
     * @param {string} key - Cache key
     * @returns {Element|null} Cached element or null
     */
    static getCachedDOMElement(w, key) {
      if (!w || !w.globals || !w.globals.domCache) return null;
      return w.globals.domCache.get(key) || null;
    }
  }
  class AxesUtils {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     */
    constructor(w, { theme = null, timeScale = null } = {}) {
      this.w = w;
      this.theme = theme;
      this.timeScale = timeScale;
    }
    // Based on the formatter function, get the label text and position
    /**
     * @param {any[]} labels
     * @param {Array<Record<string, any>>} timescaleLabels
     * @param {number} x
     * @param {number} i
     * @param {any[]} drawnLabels
     */
    getLabel(labels, timescaleLabels, x, i, drawnLabels = [], fontSize = "12px", isLeafGroup = true) {
      const w = this.w;
      const rawLabel = typeof labels[i] === "undefined" ? "" : labels[i];
      let label = rawLabel;
      const xlbFormatter = w.formatters.xLabelFormatter;
      const customFormatter = w.config.xaxis.labels.formatter;
      let isBold = false;
      const xFormat = new Formatters(this.w);
      const timestamp = rawLabel;
      if (isLeafGroup) {
        label = /** @type {any} */
        xFormat.xLabelFormat(
          xlbFormatter,
          rawLabel,
          timestamp,
          {
            i,
            dateFormatter: new DateTime(this.w).formatDate,
            w
          }
        );
        if (customFormatter !== void 0) {
          label = customFormatter(rawLabel, labels[i], {
            i,
            dateFormatter: new DateTime(this.w).formatDate,
            w
          });
        }
      }
      const determineHighestUnit = (unit) => {
        let highestUnit = null;
        timescaleLabels.forEach((t) => {
          if (t.unit === "month") {
            highestUnit = "year";
          } else if (t.unit === "day") {
            highestUnit = "month";
          } else if (t.unit === "hour") {
            highestUnit = "day";
          } else if (t.unit === "minute") {
            highestUnit = "hour";
          }
        });
        return highestUnit === unit;
      };
      if (timescaleLabels.length > 0) {
        isBold = determineHighestUnit(timescaleLabels[i].unit);
        x = timescaleLabels[i].position;
        label = timescaleLabels[i].value;
      } else {
        if (w.config.xaxis.type === "datetime" && customFormatter === void 0) {
          label = "";
        }
      }
      if (typeof label === "undefined") label = "";
      label = Array.isArray(label) ? label : label.toString();
      const graphics = new Graphics(this.w);
      let textRect = {};
      if (w.layout.rotateXLabels && isLeafGroup) {
        textRect = graphics.getTextRects(
          label,
          parseInt(fontSize, 10).toString(),
          null,
          `rotate(${w.config.xaxis.labels.rotate} 0 0)`,
          false
        );
      } else {
        textRect = graphics.getTextRects(label, parseInt(fontSize, 10).toString());
      }
      const allowDuplicatesInTimeScale = !w.config.xaxis.labels.showDuplicates && this.timeScale;
      if (!Array.isArray(label) && (String(label) === "NaN" || drawnLabels.indexOf(label) >= 0 && allowDuplicatesInTimeScale)) {
        label = "";
      }
      return {
        x,
        text: label,
        textRect,
        isBold
      };
    }
    /**
     * @param {number} i
     * @param {any} label
     * @param {number} labelsLen
     */
    checkLabelBasedOnTickamount(i, label, labelsLen) {
      const w = this.w;
      let ticks = w.config.xaxis.tickAmount;
      if (ticks === "dataPoints") ticks = Math.round(w.layout.gridWidth / 120);
      if (ticks > labelsLen) return label;
      const tickMultiple = Math.round(labelsLen / (ticks + 1));
      if (i % tickMultiple === 0) {
        return label;
      } else {
        label.text = "";
      }
      return label;
    }
    /**
     * @param {number} i
     * @param {any} label
     * @param {number} labelsLen
     * @param {any[]} drawnLabels
     * @param {Array<Record<string, any>>} drawnLabelsRects
     */
    checkForOverflowingLabels(i, label, labelsLen, drawnLabels, drawnLabelsRects) {
      const w = this.w;
      if (i === 0) {
        if (w.globals.skipFirstTimelinelabel) {
          label.text = "";
        }
      }
      if (i === labelsLen - 1) {
        if (w.globals.skipLastTimelinelabel) {
          label.text = "";
        }
      }
      if (w.config.xaxis.labels.hideOverlappingLabels && drawnLabels.length > 0) {
        const prev = drawnLabelsRects[drawnLabelsRects.length - 1];
        if (w.config.xaxis.labels.trim && w.config.xaxis.type !== "datetime") {
          return label;
        }
        if (
          /** @type {any} */
          label.x < prev.textRect.width / (w.layout.rotateXLabels ? Math.abs(w.config.xaxis.labels.rotate) / 12 : 1.01) + prev.x
        ) {
          label.text = "";
        }
      }
      return label;
    }
    /**
     * @param {number} i
     * @param {any[]} labels
     */
    checkForReversedLabels(i, labels) {
      const w = this.w;
      if (w.config.yaxis[i] && w.config.yaxis[i].reversed) {
        labels.reverse();
      }
      return labels;
    }
    /**
     * @param {number} index
     */
    yAxisAllSeriesCollapsed(index) {
      const gl = this.w.globals;
      return !gl.seriesYAxisMap[index].some((si) => {
        return gl.collapsedSeriesIndices.indexOf(si) === -1;
      });
    }
    // Method to translate annotation.yAxisIndex values from
    // seriesName-as-a-string values to seriesName-as-an-array values (old style
    // series mapping to new style).
    /**
     * @param {number} index
     */
    translateYAxisIndex(index) {
      const w = this.w;
      const gl = w.globals;
      const yaxis = w.config.yaxis;
      const newStyle = w.seriesData.series.length > yaxis.length || /**
       * @param {Record<string, any>} a
       */
      yaxis.some((a) => Array.isArray(a.seriesName));
      if (newStyle) {
        return index;
      } else {
        return gl.seriesYAxisReverseMap[index];
      }
    }
    /**
     * @param {number} index
     */
    isYAxisHidden(index) {
      const w = this.w;
      const yaxis = w.config.yaxis[index];
      if (!yaxis.show || this.yAxisAllSeriesCollapsed(index)) {
        return true;
      }
      if (!yaxis.showForNullSeries) {
        const seriesIndices = w.globals.seriesYAxisMap[index];
        const coreUtils = new CoreUtils(this.w);
        return seriesIndices.every((si) => coreUtils.isSeriesNull(si));
      }
      return false;
    }
    // get the label color for y-axis
    // realIndex is the actual series index, while i is the tick Index
    /**
     * @param {string[]} yColors
     * @param {number} realIndex
     */
    getYAxisForeColor(yColors, realIndex) {
      var _a;
      const w = this.w;
      if (Array.isArray(yColors) && w.globals.yAxisScale[realIndex]) {
        (_a = this.theme) == null ? void 0 : _a.pushExtraColors(
          yColors,
          w.globals.yAxisScale[realIndex].result.length,
          false
        );
      }
      return yColors;
    }
    /**
     * @param {number} x
     * @param {number} tickAmount
     * @param {Record<string, any>} axisBorder
     * @param {Record<string, any>} axisTicks
     * @param {number} realIndex
     * @param {any} labelsDivider
     * @param {any} elYaxis
     */
    drawYAxisTicks(x, tickAmount, axisBorder, axisTicks, realIndex, labelsDivider, elYaxis) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      let tY = w.layout.translateY + w.config.yaxis[realIndex].labels.offsetY;
      if (w.globals.isBarHorizontal) {
        tY = 0;
      } else if (w.config.chart.type === "heatmap") {
        tY += labelsDivider / 2;
      }
      if (axisTicks.show && tickAmount > 0) {
        if (w.config.yaxis[realIndex].opposite === true) x = x + axisTicks.width;
        for (let i = tickAmount; i >= 0; i--) {
          const elTick = graphics.drawLine(
            x + axisBorder.offsetX - axisTicks.width + axisTicks.offsetX,
            tY + axisTicks.offsetY,
            x + axisBorder.offsetX + axisTicks.offsetX,
            tY + axisTicks.offsetY,
            axisTicks.color
          );
          elYaxis.add(elTick);
          tY += labelsDivider;
        }
      }
    }
  }
  class XAxis {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     * @param {any} [elgrid]
     */
    constructor(w, ctx, elgrid) {
      this.w = w;
      this.ctx = ctx;
      this.elgrid = elgrid;
      this.axesUtils = new AxesUtils(w, {
        theme: ctx.theme,
        timeScale: ctx.timeScale
      });
      this.xaxisLabels = w.labelData.labels.slice();
      if (w.labelData.timescaleLabels.length > 0 && !w.globals.isBarHorizontal) {
        this.xaxisLabels = w.labelData.timescaleLabels.slice();
      }
      if (w.config.xaxis.overwriteCategories) {
        this.xaxisLabels = w.config.xaxis.overwriteCategories;
      }
      this.drawnLabels = [];
      this.drawnLabelsRects = [];
      if (w.config.xaxis.position === "top") {
        this.offY = 0;
      } else {
        this.offY = w.layout.gridHeight;
      }
      this.offY = this.offY + w.config.xaxis.axisBorder.offsetY;
      this.isCategoryBarHorizontal = w.config.chart.type === "bar" && w.config.plotOptions.bar.horizontal;
      this.xaxisFontSize = w.config.xaxis.labels.style.fontSize;
      this.xaxisFontFamily = w.config.xaxis.labels.style.fontFamily;
      this.xaxisForeColors = w.config.xaxis.labels.style.colors;
      this.xaxisBorderWidth = w.config.xaxis.axisBorder.width;
      if (this.isCategoryBarHorizontal) {
        this.xaxisBorderWidth = w.config.yaxis[0].axisBorder.width.toString();
      }
      if (String(this.xaxisBorderWidth).indexOf("%") > -1) {
        this.xaxisBorderWidth = w.layout.gridWidth * parseInt(this.xaxisBorderWidth, 10) / 100;
      } else {
        this.xaxisBorderWidth = parseInt(this.xaxisBorderWidth, 10);
      }
      this.xaxisBorderHeight = w.config.xaxis.axisBorder.height;
      this.yaxis = w.config.yaxis[0];
    }
    drawXaxis() {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const elXaxis = graphics.group({
        class: "apexcharts-xaxis",
        transform: `translate(${w.config.xaxis.offsetX}, ${w.config.xaxis.offsetY})`
      });
      const elXaxisTexts = graphics.group({
        class: "apexcharts-xaxis-texts-g",
        transform: `translate(${w.layout.translateXAxisX}, ${w.layout.translateXAxisY})`
      });
      elXaxis.add(elXaxisTexts);
      let labels = [];
      for (let i = 0; i < this.xaxisLabels.length; i++) {
        labels.push(this.xaxisLabels[i]);
      }
      this.drawXAxisLabelAndGroup(
        true,
        graphics,
        elXaxisTexts,
        labels,
        w.axisFlags.isXNumeric,
        (i, colWidth) => colWidth
      );
      if (w.labelData.hasXaxisGroups) {
        const labelsGroup = w.labelData.groups;
        labels = [];
        for (let i = 0; i < labelsGroup.length; i++) {
          labels.push(labelsGroup[i].title);
        }
        const overwriteStyles = (
          /** @type {any} */
          {}
        );
        if (w.config.xaxis.group.style) {
          overwriteStyles.xaxisFontSize = w.config.xaxis.group.style.fontSize;
          overwriteStyles.xaxisFontFamily = w.config.xaxis.group.style.fontFamily;
          overwriteStyles.xaxisForeColors = w.config.xaxis.group.style.colors;
          overwriteStyles.fontWeight = w.config.xaxis.group.style.fontWeight;
          overwriteStyles.cssClass = w.config.xaxis.group.style.cssClass;
        }
        this.drawXAxisLabelAndGroup(
          false,
          graphics,
          elXaxisTexts,
          labels,
          false,
          (i, colWidth) => labelsGroup[i].cols * colWidth,
          overwriteStyles
        );
      }
      if (w.config.xaxis.title.text !== void 0) {
        const elXaxisTitle = graphics.group({
          class: "apexcharts-xaxis-title"
        });
        const elXAxisTitleText = graphics.drawText({
          x: w.layout.gridWidth / 2 + w.config.xaxis.title.offsetX,
          y: this.offY + parseFloat(this.xaxisFontSize) + (w.config.xaxis.position === "bottom" ? w.layout.xAxisLabelsHeight : -w.layout.xAxisLabelsHeight - 10) + w.config.xaxis.title.offsetY,
          text: w.config.xaxis.title.text,
          textAnchor: "middle",
          fontSize: w.config.xaxis.title.style.fontSize,
          fontFamily: w.config.xaxis.title.style.fontFamily,
          fontWeight: w.config.xaxis.title.style.fontWeight,
          foreColor: w.config.xaxis.title.style.color,
          cssClass: "apexcharts-xaxis-title-text " + w.config.xaxis.title.style.cssClass
        });
        elXaxisTitle.add(elXAxisTitleText);
        elXaxis.add(elXaxisTitle);
      }
      if (w.config.xaxis.axisBorder.show) {
        const offX = w.globals.barPadForNumericAxis;
        const elHorzLine = graphics.drawLine(
          w.globals.padHorizontal + w.config.xaxis.axisBorder.offsetX - offX,
          this.offY,
          this.xaxisBorderWidth + offX,
          this.offY,
          w.config.xaxis.axisBorder.color,
          0,
          this.xaxisBorderHeight
        );
        if (this.elgrid && this.elgrid.elGridBorders && w.config.grid.show) {
          this.elgrid.elGridBorders.add(elHorzLine);
        } else {
          elXaxis.add(elHorzLine);
        }
      }
      return elXaxis;
    }
    /**
     * @param {Record<string, any>} [overwriteStyles]
     * @param {boolean} isLeafGroup
     * @param {import('../Graphics').default} graphics
     * @param {any} elXaxisTexts
     * @param {any[]} labels
     * @param {boolean} isXNumeric
     * @param {any} colWidthCb
     */
    drawXAxisLabelAndGroup(isLeafGroup, graphics, elXaxisTexts, labels, isXNumeric, colWidthCb, overwriteStyles = {}) {
      const drawnLabels = [];
      const drawnLabelsRects = [];
      const w = this.w;
      const xaxisFontSize = overwriteStyles.xaxisFontSize || this.xaxisFontSize;
      const xaxisFontFamily = overwriteStyles.xaxisFontFamily || this.xaxisFontFamily;
      const xaxisForeColors = overwriteStyles.xaxisForeColors || this.xaxisForeColors;
      const fontWeight = overwriteStyles.fontWeight || w.config.xaxis.labels.style.fontWeight;
      const cssClass = overwriteStyles.cssClass || w.config.xaxis.labels.style.cssClass;
      let colWidth;
      let xPos = w.globals.padHorizontal;
      const labelsLen = labels.length;
      let dataPoints = w.config.xaxis.type === "category" ? w.globals.dataPoints : labelsLen;
      if (dataPoints === 0 && labelsLen > dataPoints) dataPoints = labelsLen;
      if (isXNumeric) {
        const len = Math.max(
          Number(w.config.xaxis.tickAmount) || 1,
          dataPoints > 1 ? dataPoints - 1 : dataPoints
        );
        colWidth = w.layout.gridWidth / Math.min(len, labelsLen - 1);
        xPos = xPos + colWidthCb(0, colWidth) / 2 + w.config.xaxis.labels.offsetX;
      } else {
        colWidth = w.layout.gridWidth / dataPoints;
        xPos = xPos + colWidthCb(0, colWidth) + w.config.xaxis.labels.offsetX;
      }
      for (let i = 0; i <= labelsLen - 1; i++) {
        let x = xPos - colWidthCb(i, colWidth) / 2 + w.config.xaxis.labels.offsetX;
        if (i === 0 && labelsLen === 1 && colWidth / 2 === xPos && dataPoints === 1) {
          x = w.layout.gridWidth / 2;
        }
        let label = this.axesUtils.getLabel(
          labels,
          w.labelData.timescaleLabels,
          x,
          i,
          drawnLabels,
          xaxisFontSize,
          isLeafGroup
        );
        let offsetYCorrection = 28;
        if (w.layout.rotateXLabels && isLeafGroup) {
          offsetYCorrection = 22;
        }
        if (w.config.xaxis.title.text && w.config.xaxis.position === "top") {
          offsetYCorrection += parseFloat(w.config.xaxis.title.style.fontSize) + 2;
        }
        if (!isLeafGroup) {
          offsetYCorrection = offsetYCorrection + parseFloat(xaxisFontSize) + (w.layout.xAxisLabelsHeight - w.layout.xAxisGroupLabelsHeight) + (w.layout.rotateXLabels ? 10 : 0);
        }
        const isCategoryTickAmounts = typeof w.config.xaxis.tickAmount !== "undefined" && w.config.xaxis.tickAmount !== "dataPoints" && w.config.xaxis.type !== "datetime";
        if (isCategoryTickAmounts) {
          label = this.axesUtils.checkLabelBasedOnTickamount(i, label, labelsLen);
        } else {
          label = this.axesUtils.checkForOverflowingLabels(
            i,
            label,
            labelsLen,
            drawnLabels,
            drawnLabelsRects
          );
        }
        const getCatForeColor = () => {
          return isLeafGroup && w.config.xaxis.convertedCatToNumeric ? xaxisForeColors[w.globals.minX + i - 1] : xaxisForeColors[i];
        };
        if (w.config.xaxis.labels.show) {
          const elText = graphics.drawText({
            x: label.x,
            y: this.offY + w.config.xaxis.labels.offsetY + offsetYCorrection - (w.config.xaxis.position === "top" ? w.layout.xAxisHeight + w.config.xaxis.axisTicks.height - 2 : 0),
            text: label.text,
            textAnchor: "middle",
            fontWeight: label.isBold ? 600 : fontWeight,
            fontSize: xaxisFontSize,
            fontFamily: xaxisFontFamily,
            foreColor: Array.isArray(xaxisForeColors) ? getCatForeColor() : xaxisForeColors,
            isPlainText: false,
            cssClass: (isLeafGroup ? "apexcharts-xaxis-label " : "apexcharts-xaxis-group-label ") + cssClass
          });
          elXaxisTexts.add(elText);
          elText.on("click", (e) => {
            if (typeof w.config.chart.events.xAxisLabelClick === "function") {
              const opts = Object.assign({}, w, {
                labelIndex: i
              });
              w.config.chart.events.xAxisLabelClick(e, this.ctx, opts);
            }
          });
          if (isLeafGroup) {
            const elTooltipTitle = BrowserAPIs.createElementNS(SVGNS, "title");
            elTooltipTitle.textContent = Array.isArray(label.text) ? label.text.join(" ") : label.text;
            elText.node.appendChild(elTooltipTitle);
            if (label.text !== "") {
              drawnLabels.push(label.text);
              drawnLabelsRects.push(label);
            }
          }
        }
        if (i < labelsLen - 1) {
          xPos = xPos + colWidthCb(i + 1, colWidth);
        }
      }
    }
    // this actually becomes the vertical axis (for bar charts)
    /**
     * @param {number} realIndex
     */
    drawXaxisInversed(realIndex) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const translateYAxisX = w.config.yaxis[0].opposite ? w.globals.translateYAxisX[realIndex] : 0;
      const elYaxis = graphics.group({
        class: "apexcharts-yaxis apexcharts-xaxis-inversed",
        rel: realIndex
      });
      const elYaxisTexts = graphics.group({
        class: "apexcharts-yaxis-texts-g apexcharts-xaxis-inversed-texts-g",
        transform: "translate(" + translateYAxisX + ", 0)"
      });
      elYaxis.add(elYaxisTexts);
      const labels = [];
      if (w.config.yaxis[realIndex].show) {
        for (let i = 0; i < this.xaxisLabels.length; i++) {
          labels.push(this.xaxisLabels[i]);
        }
      }
      const colHeight = w.layout.gridHeight / labels.length;
      let yPos = -(colHeight / 2.2);
      const lbFormatter = w.formatters.yLabelFormatters[0];
      const ylabels = w.config.yaxis[0].labels;
      if (ylabels.show) {
        for (let i = 0; i <= labels.length - 1; i++) {
          let label = typeof labels[i] === "undefined" ? "" : labels[i];
          label = lbFormatter(label, {
            seriesIndex: realIndex,
            dataPointIndex: i,
            w
          });
          const yColors = this.axesUtils.getYAxisForeColor(
            ylabels.style.colors,
            realIndex
          );
          const getForeColor = () => {
            return Array.isArray(yColors) ? yColors[i] : yColors;
          };
          let multiY = 0;
          if (Array.isArray(label)) {
            multiY = label.length / 2 * parseInt(ylabels.style.fontSize, 10);
          }
          let offsetX = ylabels.offsetX - 15;
          let textAnchor = "end";
          if (this.yaxis.opposite) {
            textAnchor = "start";
          }
          if (w.config.yaxis[0].labels.align === "left") {
            offsetX = ylabels.offsetX;
            textAnchor = "start";
          } else if (w.config.yaxis[0].labels.align === "center") {
            offsetX = ylabels.offsetX;
            textAnchor = "middle";
          } else if (w.config.yaxis[0].labels.align === "right") {
            textAnchor = "end";
          }
          const elLabel = graphics.drawText({
            x: offsetX,
            y: yPos + colHeight + ylabels.offsetY - multiY,
            text: label,
            textAnchor,
            foreColor: getForeColor(),
            fontSize: ylabels.style.fontSize,
            fontFamily: ylabels.style.fontFamily,
            fontWeight: ylabels.style.fontWeight,
            isPlainText: false,
            cssClass: "apexcharts-yaxis-label " + ylabels.style.cssClass,
            maxWidth: ylabels.maxWidth
          });
          elYaxisTexts.add(elLabel);
          elLabel.on("click", (e) => {
            if (typeof w.config.chart.events.xAxisLabelClick === "function") {
              const opts = Object.assign({}, w, {
                labelIndex: i
              });
              w.config.chart.events.xAxisLabelClick(e, this.ctx, opts);
            }
          });
          const elTooltipTitle = BrowserAPIs.createElementNS(SVGNS, "title");
          elTooltipTitle.textContent = Array.isArray(label) ? label.join(" ") : label;
          elLabel.node.appendChild(elTooltipTitle);
          if (w.config.yaxis[realIndex].labels.rotate !== 0) {
            const labelRotatingCenter = graphics.rotateAroundCenter(elLabel.node);
            elLabel.node.setAttribute(
              "transform",
              `rotate(${w.config.yaxis[realIndex].labels.rotate} 0 ${labelRotatingCenter.y})`
            );
          }
          yPos = yPos + colHeight;
        }
      }
      if (w.config.yaxis[0].title.text !== void 0) {
        const elXaxisTitle = graphics.group({
          class: "apexcharts-yaxis-title apexcharts-xaxis-title-inversed",
          transform: "translate(" + translateYAxisX + ", 0)"
        });
        const elXAxisTitleText = graphics.drawText({
          x: w.config.yaxis[0].title.offsetX,
          y: w.layout.gridHeight / 2 + w.config.yaxis[0].title.offsetY,
          text: w.config.yaxis[0].title.text,
          textAnchor: "middle",
          foreColor: w.config.yaxis[0].title.style.color,
          fontSize: w.config.yaxis[0].title.style.fontSize,
          fontWeight: w.config.yaxis[0].title.style.fontWeight,
          fontFamily: w.config.yaxis[0].title.style.fontFamily,
          cssClass: "apexcharts-yaxis-title-text " + w.config.yaxis[0].title.style.cssClass
        });
        elXaxisTitle.add(elXAxisTitleText);
        elYaxis.add(elXaxisTitle);
      }
      let offX = 0;
      if (this.isCategoryBarHorizontal && w.config.yaxis[0].opposite) {
        offX = w.layout.gridWidth;
      }
      const axisBorder = w.config.xaxis.axisBorder;
      if (axisBorder.show) {
        const elVerticalLine = graphics.drawLine(
          w.globals.padHorizontal + axisBorder.offsetX + offX,
          1 + axisBorder.offsetY,
          w.globals.padHorizontal + axisBorder.offsetX + offX,
          w.layout.gridHeight + axisBorder.offsetY,
          axisBorder.color,
          0
        );
        if (this.elgrid && this.elgrid.elGridBorders && w.config.grid.show) {
          this.elgrid.elGridBorders.add(elVerticalLine);
        } else {
          elYaxis.add(elVerticalLine);
        }
      }
      if (w.config.yaxis[0].axisTicks.show) {
        this.axesUtils.drawYAxisTicks(
          offX,
          labels.length,
          w.config.yaxis[0].axisBorder,
          w.config.yaxis[0].axisTicks,
          0,
          colHeight,
          elYaxis
        );
      }
      return elYaxis;
    }
    /**
     * @param {number} x1
     * @param {number} y2
     * @param {any} appendToElement
     */
    drawXaxisTicks(x1, y2, appendToElement) {
      const w = this.w;
      const x2 = x1;
      if (x1 < 0 || x1 - 2 > w.layout.gridWidth) return;
      const y1 = this.offY + w.config.xaxis.axisTicks.offsetY;
      y2 = y2 + y1 + w.config.xaxis.axisTicks.height;
      if (w.config.xaxis.position === "top") {
        y2 = y1 - w.config.xaxis.axisTicks.height;
      }
      if (w.config.xaxis.axisTicks.show) {
        const graphics = new Graphics(this.w);
        const line = graphics.drawLine(
          x1 + w.config.xaxis.axisTicks.offsetX,
          y1 + w.config.xaxis.offsetY,
          x2 + w.config.xaxis.axisTicks.offsetX,
          y2 + w.config.xaxis.offsetY,
          w.config.xaxis.axisTicks.color
        );
        appendToElement.add(line);
        line.node.classList.add("apexcharts-xaxis-tick");
      }
    }
    getXAxisTicksPositions() {
      const w = this.w;
      const xAxisTicksPositions = [];
      const xCount = this.xaxisLabels.length;
      let x1 = w.globals.padHorizontal;
      if (w.labelData.timescaleLabels.length > 0) {
        for (let i = 0; i < xCount; i++) {
          x1 = this.xaxisLabels[i].position;
          xAxisTicksPositions.push(x1);
        }
      } else {
        const xCountForCategoryCharts = xCount;
        for (let i = 0; i < xCountForCategoryCharts; i++) {
          let x1Count = xCountForCategoryCharts;
          if (w.axisFlags.isXNumeric && w.config.chart.type !== "bar") {
            x1Count -= 1;
          }
          x1 = x1 + w.layout.gridWidth / x1Count;
          xAxisTicksPositions.push(x1);
        }
      }
      return xAxisTicksPositions;
    }
    // to rotate x-axis labels or to put ... for longer text in xaxis
    xAxisLabelCorrections() {
      var _a, _b, _c;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const xAxis = w.dom.baseEl.querySelector(".apexcharts-xaxis-texts-g");
      const xAxisTexts = w.dom.baseEl.querySelectorAll(
        ".apexcharts-xaxis-texts-g text:not(.apexcharts-xaxis-group-label)"
      );
      const yAxisTextsInversed = w.dom.baseEl.querySelectorAll(
        ".apexcharts-yaxis-inversed text"
      );
      const xAxisTextsInversed = w.dom.baseEl.querySelectorAll(
        ".apexcharts-xaxis-inversed-texts-g text tspan"
      );
      if (w.layout.rotateXLabels || w.config.xaxis.labels.rotateAlways) {
        for (let xat = 0; xat < xAxisTexts.length; xat++) {
          const textRotatingCenter = graphics.rotateAroundCenter(xAxisTexts[xat]);
          textRotatingCenter.y = textRotatingCenter.y - 1;
          textRotatingCenter.x = textRotatingCenter.x + 1;
          xAxisTexts[xat].setAttribute(
            "transform",
            `rotate(${w.config.xaxis.labels.rotate} ${textRotatingCenter.x} ${textRotatingCenter.y})`
          );
          xAxisTexts[xat].setAttribute("text-anchor", `end`);
          xAxis == null ? void 0 : xAxis.setAttribute("transform", `translate(0, ${-10})`);
          const tSpan = xAxisTexts[xat].childNodes;
          if (w.config.xaxis.labels.trim) {
            Array.prototype.forEach.call(tSpan, (ts) => {
              graphics.placeTextWithEllipsis(
                ts,
                ts.textContent,
                w.layout.xAxisLabelsHeight - (w.config.legend.position === "bottom" ? 20 : 10)
              );
            });
          }
        }
      } else {
        const width = w.layout.gridWidth / (w.labelData.labels.length + 1);
        for (let xat = 0; xat < xAxisTexts.length; xat++) {
          const tSpan = xAxisTexts[xat].childNodes;
          if (w.config.xaxis.labels.trim && w.config.xaxis.type !== "datetime") {
            Array.prototype.forEach.call(tSpan, (ts) => {
              graphics.placeTextWithEllipsis(ts, ts.textContent, width);
            });
          }
        }
      }
      if (yAxisTextsInversed.length > 0) {
        const firstLabelPosX = (
          /** @type {SVGGraphicsElement} */
          yAxisTextsInversed[yAxisTextsInversed.length - 1].getBBox()
        );
        const lastLabelPosX = (
          /** @type {SVGGraphicsElement} */
          yAxisTextsInversed[0].getBBox()
        );
        if (firstLabelPosX.x < -20) {
          (_a = yAxisTextsInversed[yAxisTextsInversed.length - 1].parentNode) == null ? void 0 : _a.removeChild(
            yAxisTextsInversed[yAxisTextsInversed.length - 1]
          );
        }
        if (lastLabelPosX.x + lastLabelPosX.width > w.layout.gridWidth && !w.globals.isBarHorizontal) {
          (_b = yAxisTextsInversed[0].parentNode) == null ? void 0 : _b.removeChild(yAxisTextsInversed[0]);
        }
        for (let xat = 0; xat < xAxisTextsInversed.length; xat++) {
          graphics.placeTextWithEllipsis(
            xAxisTextsInversed[xat],
            (_c = xAxisTextsInversed[xat].textContent) != null ? _c : "",
            w.config.yaxis[0].labels.maxWidth - (w.config.yaxis[0].title.text ? parseFloat(w.config.yaxis[0].title.style.fontSize) * 2 : 0) - 15
          );
        }
      }
    }
    // renderXAxisBands() {
    //   let w = this.w;
    //   let plotBand = document.createElementNS(SVGNS, 'rect')
    //   w.dom.elGraphical.add(plotBand)
    // }
  }
  class Grid {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.xaxisLabels = w.labelData.labels.slice();
      this.axesUtils = new AxesUtils(ctx.w, {
        theme: ctx.theme,
        timeScale: ctx.timeScale
      });
      this.isRangeBar = w.rangeData.seriesRange.length && w.globals.isBarHorizontal;
      if (w.labelData.timescaleLabels.length > 0) {
        this.xaxisLabels = w.labelData.timescaleLabels.slice();
      }
    }
    /**
     * @param {any} elGrid
     */
    drawGridArea(elGrid = null) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      if (!elGrid) {
        elGrid = graphics.group({ class: "apexcharts-grid" });
      }
      const elVerticalLine = graphics.drawLine(
        w.globals.padHorizontal,
        1,
        w.globals.padHorizontal,
        w.layout.gridHeight,
        "transparent"
      );
      const elHorzLine = graphics.drawLine(
        w.globals.padHorizontal,
        w.layout.gridHeight,
        w.layout.gridWidth,
        w.layout.gridHeight,
        "transparent"
      );
      elGrid.add(elHorzLine);
      elGrid.add(elVerticalLine);
      return elGrid;
    }
    drawGrid() {
      const gl = this.w.globals;
      if (gl.axisCharts) {
        const elgrid = this.renderGrid();
        this.drawGridArea(elgrid.el);
        return elgrid;
      }
      return null;
    }
    createGridMask() {
      const w = this.w;
      const gl = w.globals;
      const graphics = new Graphics(this.w);
      const strokeSize = Array.isArray(w.config.stroke.width) ? Math.max(...w.config.stroke.width) : w.config.stroke.width;
      const createClipPath = (id) => {
        const clipPath = BrowserAPIs.createElementNS(SVGNS, "clipPath");
        clipPath.setAttribute("id", id);
        return clipPath;
      };
      w.dom.elGridRectMask = createClipPath(`gridRectMask${gl.cuid}`);
      w.dom.elGridRectBarMask = createClipPath(`gridRectBarMask${gl.cuid}`);
      w.dom.elGridRectMarkerMask = createClipPath(`gridRectMarkerMask${gl.cuid}`);
      w.dom.elForecastMask = createClipPath(`forecastMask${gl.cuid}`);
      w.dom.elNonForecastMask = createClipPath(`nonForecastMask${gl.cuid}`);
      const hasBar = ["bar", "rangeBar", "candlestick", "boxPlot"].includes(
        w.config.chart.type
      ) || w.globals.comboBarCount > 0;
      let barWidthLeft = 0;
      let barWidthRight = 0;
      if (hasBar && w.axisFlags.isXNumeric && !w.globals.isBarHorizontal) {
        barWidthLeft = Math.max(
          w.config.grid.padding.left,
          gl.barPadForNumericAxis
        );
        barWidthRight = Math.max(
          w.config.grid.padding.right,
          gl.barPadForNumericAxis
        );
      }
      w.dom.elGridRect = graphics.drawRect(
        -strokeSize / 2 - 2,
        -strokeSize / 2 - 2,
        w.layout.gridWidth + strokeSize + 4,
        w.layout.gridHeight + strokeSize + 4,
        0,
        "#fff"
      );
      w.dom.elGridRectBar = graphics.drawRect(
        -strokeSize / 2 - barWidthLeft - 2,
        -strokeSize / 2 - 2,
        w.layout.gridWidth + strokeSize + barWidthRight + barWidthLeft + 4,
        w.layout.gridHeight + strokeSize + 4,
        0,
        "#fff"
      );
      const markerSize = w.globals.markers.largestSize;
      w.dom.elGridRectMarker = graphics.drawRect(
        Math.min(-strokeSize / 2 - barWidthLeft - 2, -markerSize),
        -markerSize,
        w.layout.gridWidth + Math.max(strokeSize + barWidthRight + barWidthLeft + 4, markerSize * 2),
        w.layout.gridHeight + markerSize * 2,
        0,
        "#fff"
      );
      w.dom.elGridRectMask.appendChild(w.dom.elGridRect.node);
      w.dom.elGridRectBarMask.appendChild(w.dom.elGridRectBar.node);
      w.dom.elGridRectMarkerMask.appendChild(w.dom.elGridRectMarker.node);
      const defs = w.dom.elDefs.node;
      defs.appendChild(w.dom.elGridRectMask);
      defs.appendChild(w.dom.elGridRectBarMask);
      defs.appendChild(w.dom.elGridRectMarkerMask);
      defs.appendChild(w.dom.elForecastMask);
      defs.appendChild(w.dom.elNonForecastMask);
    }
    /** @param {{i: any, x1: any, y1: any, x2: any, y2: any, xCount: any, parent: any}} opts */
    _drawGridLines({ i, x1, y1, x2, y2, xCount, parent }) {
      const w = this.w;
      const shouldDraw = () => {
        if (i === 0 && w.globals.skipFirstTimelinelabel) return false;
        if (i === xCount - 1 && w.globals.skipLastTimelinelabel && !w.config.xaxis.labels.formatter)
          return false;
        if (w.config.chart.type === "radar") return false;
        return true;
      };
      if (shouldDraw()) {
        if (w.config.grid.xaxis.lines.show) {
          this._drawGridLine({ i, x1, y1, x2, y2, xCount, parent });
        }
        let y_2 = 0;
        if (w.labelData.hasXaxisGroups && w.config.xaxis.tickPlacement === "between") {
          const groups = w.labelData.groups;
          if (groups) {
            let gacc = 0;
            for (let gi = 0; gacc < i && gi < groups.length; gi++) {
              gacc += groups[gi].cols;
            }
            if (gacc === i) {
              y_2 = w.layout.xAxisLabelsHeight * 0.6;
            }
          }
        }
        const xAxis = new XAxis(this.w, this.ctx);
        xAxis.drawXaxisTicks(x1, y_2, w.dom.elGraphical);
      }
    }
    /** @param {{i: any, x1: any, y1: any, x2: any, y2: any, xCount: any, parent: any}} opts */
    _drawGridLine({ i, x1, y1, x2, y2, xCount, parent }) {
      const w = this.w;
      const isHorzLine = parent.node.classList.contains(
        "apexcharts-gridlines-horizontal"
      );
      const offX = w.globals.barPadForNumericAxis;
      const excludeBorders = y1 === 0 && y2 === 0 || x1 === 0 && x2 === 0 || y1 === w.layout.gridHeight && y2 === w.layout.gridHeight || w.globals.isBarHorizontal && (i === 0 || i === xCount - 1);
      const graphics = new Graphics(this.w);
      const line = graphics.drawLine(
        x1 - (isHorzLine ? offX : 0),
        y1,
        x2 + (isHorzLine ? offX : 0),
        y2,
        w.config.grid.borderColor,
        w.config.grid.strokeDashArray
      );
      line.node.classList.add("apexcharts-gridline");
      if (excludeBorders && w.config.grid.show) {
        this.elGridBorders.add(line);
      } else {
        parent.add(line);
      }
    }
    /** @param {{c: any, x1: any, y1: any, x2: any, y2: any, type: any}} opts */
    _drawGridBandRect({ c, x1, y1, x2, y2, type }) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const offX = w.globals.barPadForNumericAxis;
      const color = w.config.grid[type].colors[c];
      const rect = graphics.drawRect(
        x1 - (type === "row" ? offX : 0),
        y1,
        x2 + (type === "row" ? offX * 2 : 0),
        y2,
        0,
        color,
        w.config.grid[type].opacity
      );
      this.elg.add(rect);
      rect.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
      rect.node.classList.add(`apexcharts-grid-${type}`);
    }
    /** @param {{xCount: any, tickAmount: any}} opts */
    _drawXYLines({ xCount, tickAmount }) {
      var _a;
      const w = this.w;
      const datetimeLines = ({ xC, x1, y1, x2, y2 }) => {
        for (let i = 0; i < xC; i++) {
          x1 = /** @type {any} */
          this.xaxisLabels[i].position;
          x2 = /** @type {any} */
          this.xaxisLabels[i].position;
          this._drawGridLines({
            i,
            x1,
            y1,
            x2,
            y2,
            xCount,
            parent: this.elgridLinesV
          });
        }
      };
      const categoryLines = ({ xC, x1, y1, x2, y2 }) => {
        for (let i = 0; i < xC + (w.axisFlags.isXNumeric ? 0 : 1); i++) {
          if (i === 0 && xC === 1 && w.globals.dataPoints === 1) {
            x1 = w.layout.gridWidth / 2;
            x2 = x1;
          }
          this._drawGridLines({
            i,
            x1,
            y1,
            x2,
            y2,
            xCount,
            parent: this.elgridLinesV
          });
          x1 += w.layout.gridWidth / (w.axisFlags.isXNumeric ? xC - 1 : xC);
          x2 = x1;
        }
      };
      if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) {
        const x1 = w.globals.padHorizontal;
        const y1 = 0;
        let x2;
        const y2 = w.layout.gridHeight;
        if (w.labelData.timescaleLabels.length) {
          datetimeLines({ xC: xCount, x1, y1, x2, y2 });
        } else {
          if (w.axisFlags.isXNumeric) {
            xCount = (_a = w.globals.xAxisScale) == null ? void 0 : _a.result.length;
          }
          categoryLines({ xC: xCount, x1, y1, x2, y2 });
        }
      }
      if (w.config.grid.yaxis.lines.show) {
        const x1 = 0;
        let y1 = 0;
        let y2 = 0;
        const x2 = w.layout.gridWidth;
        let tA = tickAmount + 1;
        if (this.isRangeBar) {
          tA = w.labelData.labels.length;
        }
        for (let i = 0; i < tA + (this.isRangeBar ? 1 : 0); i++) {
          this._drawGridLine({
            i,
            xCount: tA + (this.isRangeBar ? 1 : 0),
            x1,
            y1,
            x2,
            y2,
            parent: this.elgridLinesH
          });
          y1 += w.layout.gridHeight / (this.isRangeBar ? tA : tickAmount);
          y2 = y1;
        }
      }
    }
    /** @param {{ xCount?: any, tickAmount?: any }} opts */
    _drawInvertedXYLines({ xCount }) {
      const w = this.w;
      if (w.config.grid.xaxis.lines.show || w.config.xaxis.axisTicks.show) {
        let x1 = w.globals.padHorizontal;
        const y1 = 0;
        let x2;
        const y2 = w.layout.gridHeight;
        for (let i = 0; i < xCount + 1; i++) {
          if (w.config.grid.xaxis.lines.show) {
            this._drawGridLine({
              i,
              xCount: xCount + 1,
              x1,
              y1,
              x2,
              y2,
              parent: this.elgridLinesV
            });
          }
          const xAxis = new XAxis(this.w, this.ctx);
          xAxis.drawXaxisTicks(x1, 0, w.dom.elGraphical);
          x1 += w.layout.gridWidth / xCount;
          x2 = x1;
        }
      }
      if (w.config.grid.yaxis.lines.show) {
        const x1 = 0;
        let y1 = 0;
        let y2 = 0;
        const x2 = w.layout.gridWidth;
        for (let i = 0; i < w.globals.dataPoints + 1; i++) {
          this._drawGridLine({
            i,
            xCount: w.globals.dataPoints + 1,
            x1,
            y1,
            x2,
            y2,
            parent: this.elgridLinesH
          });
          y1 += w.layout.gridHeight / w.globals.dataPoints;
          y2 = y1;
        }
      }
    }
    renderGrid() {
      var _a, _b, _c;
      const w = this.w;
      const gl = w.globals;
      const graphics = new Graphics(this.w);
      this.elg = graphics.group({ class: "apexcharts-grid" });
      this.elgridLinesH = graphics.group({
        class: "apexcharts-gridlines-horizontal"
      });
      this.elgridLinesV = graphics.group({
        class: "apexcharts-gridlines-vertical"
      });
      this.elGridBorders = graphics.group({ class: "apexcharts-grid-borders" });
      this.elg.add(this.elgridLinesH);
      this.elg.add(this.elgridLinesV);
      if (!w.config.grid.show) {
        this.elgridLinesV.hide();
        this.elgridLinesH.hide();
        this.elGridBorders.hide();
      }
      let gridAxisIndex = 0;
      while (gridAxisIndex < gl.seriesYAxisMap.length && gl.ignoreYAxisIndexes.includes(gridAxisIndex)) {
        gridAxisIndex++;
      }
      if (gridAxisIndex === gl.seriesYAxisMap.length) {
        gridAxisIndex = 0;
      }
      let yTickAmount = gl.yAxisScale[gridAxisIndex].result.length - 1;
      let xCount;
      if (!gl.isBarHorizontal || this.isRangeBar) {
        xCount = this.xaxisLabels.length;
        if (this.isRangeBar) {
          yTickAmount = w.labelData.labels.length;
          if (w.config.xaxis.tickAmount && w.config.xaxis.labels.formatter) {
            xCount = w.config.xaxis.tickAmount;
          }
          if (((_c = (_b = (_a = gl.yAxisScale) == null ? void 0 : _a[gridAxisIndex]) == null ? void 0 : _b.result) == null ? void 0 : _c.length) > 0 && w.config.xaxis.type !== "datetime") {
            xCount = gl.yAxisScale[gridAxisIndex].result.length - 1;
          }
        }
        this._drawXYLines({ xCount, tickAmount: yTickAmount });
      } else {
        xCount = yTickAmount;
        yTickAmount = gl.xTickAmount;
        this._drawInvertedXYLines({ xCount, tickAmount: yTickAmount });
      }
      this.drawGridBands(xCount, yTickAmount);
      return {
        el: this.elg,
        elGridBorders: this.elGridBorders,
        xAxisTickWidth: w.layout.gridWidth / xCount
      };
    }
    /**
     * @param {number} xCount
     * @param {number} tickAmount
     */
    drawGridBands(xCount, tickAmount) {
      var _a, _b, _c, _d, _e;
      const w = this.w;
      const drawBands = (type, count, x1, y1, x2, y2) => {
        for (let i = 0, c = 0; i < count; i++, c++) {
          if (c >= w.config.grid[type].colors.length) {
            c = 0;
          }
          this._drawGridBandRect({ c, x1, y1, x2, y2, type });
          y1 += w.layout.gridHeight / tickAmount;
        }
      };
      if (((_a = w.config.grid.row.colors) == null ? void 0 : _a.length) > 0) {
        drawBands(
          "row",
          tickAmount,
          0,
          0,
          w.layout.gridWidth,
          w.layout.gridHeight / tickAmount
        );
      }
      if (((_b = w.config.grid.column.colors) == null ? void 0 : _b.length) > 0) {
        let xc = !w.globals.isBarHorizontal && w.config.xaxis.tickPlacement === "on" && (w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) ? xCount - 1 : xCount;
        if (w.axisFlags.isXNumeric) {
          xc = ((_d = (_c = w.globals.xAxisScale) == null ? void 0 : _c.result.length) != null ? _d : 1) - 1;
        }
        let x1 = w.globals.padHorizontal;
        const y1 = 0;
        let x2 = w.globals.padHorizontal + w.layout.gridWidth / xc;
        const y2 = w.layout.gridHeight;
        for (let i = 0, c = 0; i < xCount; i++, c++) {
          if (c >= w.config.grid.column.colors.length) {
            c = 0;
          }
          if (w.config.xaxis.type === "datetime") {
            x1 = /** @type {any} */
            this.xaxisLabels[i].position;
            x2 = /** @type {any} */
            (((_e = this.xaxisLabels[i + 1]) == null ? void 0 : _e.position) || w.layout.gridWidth) - /** @type {any} */
            this.xaxisLabels[i].position;
          }
          this._drawGridBandRect({ c, x1, y1, x2, y2, type: "column" });
          x1 += w.layout.gridWidth / xc;
        }
      }
    }
  }
  class Scales {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this.coreUtils = new CoreUtils(this.w);
    }
    // http://stackoverflow.com/questions/326679/choosing-an-attractive-linear-scale-for-a-graphs-y-axis
    // This routine creates the Y axis values for a graph.
    /**
     * @param {number} yMin
     * @param {number} yMax
     */
    niceScale(yMin, yMax, index = 0) {
      const jsPrecision = 1e-11;
      const w = this.w;
      const gl = w.globals;
      let axisCnf;
      let maxTicks;
      let gotMin;
      let gotMax;
      if (gl.isBarHorizontal) {
        axisCnf = w.config.xaxis;
        maxTicks = Math.max((gl.svgWidth - 100) / 25, 2);
      } else {
        axisCnf = w.config.yaxis[index];
        maxTicks = Math.max((gl.svgHeight - 100) / 15, 2);
      }
      if (!Utils$1.isNumber(maxTicks)) {
        maxTicks = 10;
      }
      gotMin = axisCnf.min !== void 0 && axisCnf.min !== null;
      gotMax = axisCnf.max !== void 0 && axisCnf.min !== null;
      let gotStepSize = axisCnf.stepSize !== void 0 && axisCnf.stepSize !== null;
      let gotTickAmount = axisCnf.tickAmount !== void 0 && axisCnf.tickAmount !== null;
      let ticks = gotTickAmount ? axisCnf.tickAmount : NICE_SCALE_DEFAULT_TICKS[Math.min(
        Math.round(maxTicks / 2),
        NICE_SCALE_DEFAULT_TICKS.length - 1
      )];
      if (gl.isMultipleYAxis && !gotTickAmount && gl.multiAxisTickAmount > 0) {
        ticks = gl.multiAxisTickAmount;
        gotTickAmount = true;
      }
      if (ticks === "dataPoints") {
        ticks = gl.dataPoints - 1;
      } else {
        ticks = Math.abs(Math.round(ticks));
      }
      if (yMin === Number.MIN_VALUE && yMax === 0 || !Utils$1.isNumber(yMin) && !Utils$1.isNumber(yMax) || yMin === Number.MIN_VALUE && yMax === -Number.MAX_VALUE) {
        yMin = Utils$1.isNumber(axisCnf.min) ? axisCnf.min : 0;
        yMax = Utils$1.isNumber(axisCnf.max) ? axisCnf.max : yMin + ticks;
        gl.allSeriesCollapsed = false;
      }
      if (yMin > yMax) {
        console.warn(
          "axis.min cannot be greater than axis.max: swapping min and max"
        );
        const temp = yMax;
        yMax = yMin;
        yMin = temp;
      } else if (yMin === yMax) {
        yMin = yMin === 0 ? 0 : yMin - 1;
        yMax = yMax === 0 ? 2 : yMax + 1;
      }
      const result = [];
      if (ticks < 1) {
        ticks = 1;
      }
      let tiks = ticks;
      let range = Math.abs(yMax - yMin);
      const proximityRatio = 0.15;
      if (!gotMin && yMin > 0 && yMin / range < proximityRatio) {
        yMin = 0;
        gotMin = true;
      }
      if (!gotMax && yMax < 0 && -yMax / range < proximityRatio) {
        yMax = 0;
        gotMax = true;
      }
      range = Math.abs(yMax - yMin);
      let stepSize = range / tiks;
      let niceStep = stepSize;
      const mag = Math.floor(Math.log10(niceStep));
      const magPow = Math.pow(10, mag);
      let magMsd = Math.ceil(niceStep / magPow);
      magMsd = NICE_SCALE_ALLOWED_MAG_MSD[gl.yValueDecimal === 0 ? 0 : 1][magMsd];
      niceStep = magMsd * magPow;
      stepSize = niceStep;
      if (gl.isBarHorizontal && axisCnf.stepSize && axisCnf.type !== "datetime") {
        stepSize = axisCnf.stepSize;
        gotStepSize = true;
      } else if (gotStepSize) {
        stepSize = axisCnf.stepSize;
      }
      if (gotStepSize) {
        if (axisCnf.forceNiceScale) {
          const stepMag = Math.floor(Math.log10(stepSize));
          stepSize *= Math.pow(10, mag - stepMag);
        }
      }
      if (gotMin && gotMax) {
        let crudeStep = range / tiks;
        if (gotTickAmount) {
          if (gotStepSize) {
            if (Utils$1.mod(range, stepSize) != 0) {
              const gcdStep = Utils$1.getGCD(stepSize, crudeStep);
              if (crudeStep / gcdStep < 10) {
                stepSize = gcdStep;
              } else {
                stepSize = crudeStep;
              }
            } else {
              if (Utils$1.mod(stepSize, crudeStep) == 0) {
                stepSize = crudeStep;
              } else {
                crudeStep = stepSize;
                gotTickAmount = false;
              }
            }
          } else {
            stepSize = crudeStep;
          }
        } else {
          if (gotStepSize) {
            if (Utils$1.mod(range, stepSize) == 0) {
              crudeStep = stepSize;
            } else {
              stepSize = crudeStep;
            }
          } else {
            if (Utils$1.mod(range, stepSize) == 0) {
              crudeStep = stepSize;
            } else {
              tiks = Math.ceil(range / stepSize);
              crudeStep = range / tiks;
              const gcdStep = Utils$1.getGCD(range, stepSize);
              if (range / gcdStep < maxTicks) {
                crudeStep = gcdStep;
              }
              stepSize = crudeStep;
            }
          }
        }
        tiks = Math.round(range / stepSize);
      } else {
        if (!gotMin && !gotMax) {
          if (gl.isMultipleYAxis && gotTickAmount) {
            const tMin = stepSize * Math.floor(yMin / stepSize);
            let tMax = tMin + stepSize * tiks;
            if (tMax < yMax) {
              stepSize *= 2;
            }
            yMin = tMin;
            tMax = yMax;
            yMax = yMin + stepSize * tiks;
            range = Math.abs(yMax - yMin);
            if (yMin > 0 && yMin < Math.abs(tMax - yMax)) {
              yMin = 0;
              yMax = stepSize * tiks;
            }
            if (yMax < 0 && -yMax < Math.abs(tMin - yMin)) {
              yMax = 0;
              yMin = -stepSize * tiks;
            }
          } else {
            yMin = stepSize * Math.floor(yMin / stepSize);
            yMax = stepSize * Math.ceil(yMax / stepSize);
          }
        } else if (gotMax) {
          if (gotTickAmount) {
            yMin = yMax - stepSize * tiks;
          } else {
            const yMinPrev = yMin;
            yMin = stepSize * Math.floor(yMin / stepSize);
            if (Math.abs(yMax - yMin) / Utils$1.getGCD(range, stepSize) > maxTicks) {
              yMin = yMax - stepSize * ticks;
              yMin += stepSize * Math.floor((yMinPrev - yMin) / stepSize);
            }
          }
        } else if (gotMin) {
          if (gotTickAmount) {
            yMax = yMin + stepSize * tiks;
          } else {
            const yMaxPrev = yMax;
            yMax = stepSize * Math.ceil(yMax / stepSize);
            if (Math.abs(yMax - yMin) / Utils$1.getGCD(range, stepSize) > maxTicks) {
              yMax = yMin + stepSize * ticks;
              yMax += stepSize * Math.ceil((yMaxPrev - yMax) / stepSize);
            }
          }
        }
        range = Math.abs(yMax - yMin);
        stepSize = Utils$1.getGCD(range, stepSize);
        tiks = Math.round(range / stepSize);
      }
      if (!gotTickAmount && !(gotMin || gotMax)) {
        tiks = Math.ceil((range - jsPrecision) / (stepSize + jsPrecision));
        if (tiks > 16 && Utils$1.getPrimeFactors(tiks).length < 2) {
          tiks++;
        }
      }
      if (!gotTickAmount && axisCnf.forceNiceScale && gl.yValueDecimal === 0 && tiks > range) {
        tiks = range;
        stepSize = Math.round(range / tiks);
      }
      if (tiks > maxTicks && (!(gotTickAmount || gotStepSize) || axisCnf.forceNiceScale)) {
        const pf = Utils$1.getPrimeFactors(tiks);
        const last = pf.length - 1;
        let tt = tiks;
        reduceLoop: for (var xFactors = 0; xFactors < last; xFactors++) {
          for (var lowest = 0; lowest <= last - xFactors; lowest++) {
            const stop = Math.min(lowest + xFactors, last);
            let t = tt;
            let div = 1;
            for (var next = lowest; next <= stop; next++) {
              div *= pf[next];
            }
            t /= div;
            if (t < maxTicks) {
              tt = t;
              break reduceLoop;
            }
          }
        }
        if (tt === tiks) {
          stepSize = range;
        } else {
          stepSize = range / tt;
        }
        tiks = Math.round(range / stepSize);
      }
      if (gl.isMultipleYAxis && gl.multiAxisTickAmount == 0 && gl.ignoreYAxisIndexes.indexOf(index) < 0) {
        gl.multiAxisTickAmount = tiks;
      }
      let val = yMin - stepSize;
      const err = stepSize * jsPrecision;
      do {
        val += stepSize;
        result.push(Utils$1.stripNumber(val, 7));
      } while (yMax - val > err);
      return {
        result,
        niceMin: result[0],
        niceMax: result[result.length - 1]
      };
    }
    /** @param {number} yMin @param {number} yMax @param {number|string} ticks @param {number} index @param {number|undefined} step */
    linearScale(yMin, yMax, ticks = 10, index = 0, step = void 0) {
      const range = Math.abs(yMax - yMin);
      let result = [];
      if (yMin === yMax) {
        result = [yMin];
        return {
          result,
          niceMin: result[0],
          niceMax: result[result.length - 1]
        };
      }
      ticks = this._adjustTicksForSmallRange(ticks, index, range);
      if (
        /** @type {any} */
        ticks === "dataPoints"
      ) {
        ticks = this.w.globals.dataPoints - 1;
      }
      const ticksNum = (
        /** @type {number} */
        ticks
      );
      if (!step) {
        step = range / ticksNum;
      }
      const MIN_PRECISION = 2;
      if (step !== 0 && isFinite(step)) {
        const magnitude = Math.floor(Math.log10(Math.abs(step)));
        const precision = Math.max(MIN_PRECISION, -magnitude + MIN_PRECISION);
        const multiplier = Math.pow(10, precision);
        step = Math.round((step + Number.EPSILON) * multiplier) / multiplier;
      }
      let tickCount = ticks === Number.MAX_VALUE ? 5 : ticksNum;
      if (ticks === Number.MAX_VALUE) {
        step = 1;
      }
      let v = yMin;
      while (tickCount >= 0) {
        result.push(v);
        v = Utils$1.preciseAddition(v, step);
        tickCount -= 1;
      }
      return {
        result,
        niceMin: result[0],
        niceMax: result[result.length - 1]
      };
    }
    /**
     * @param {number} yMin
     * @param {number} yMax
     * @param {number} base
     */
    logarithmicScaleNice(yMin, yMax, base) {
      if (yMax <= 0) yMax = Math.max(yMin, base);
      if (yMin <= 0) yMin = Math.min(yMax, base);
      const logs = [];
      const logMax = Math.ceil(Math.log(yMax) / Math.log(base) + 1);
      const logMin = Math.floor(Math.log(yMin) / Math.log(base));
      for (let i = logMin; i < logMax; i++) {
        logs.push(Math.pow(base, i));
      }
      return {
        result: logs,
        niceMin: logs[0],
        niceMax: logs[logs.length - 1]
      };
    }
    /**
     * @param {number} yMin
     * @param {number} yMax
     * @param {number} base
     */
    logarithmicScale(yMin, yMax, base) {
      if (yMax <= 0) yMax = Math.max(yMin, base);
      if (yMin <= 0) yMin = Math.min(yMax, base);
      const logs = [];
      const logMax = Math.log(yMax) / Math.log(base);
      const logMin = Math.log(yMin) / Math.log(base);
      const logRange = logMax - logMin;
      const ticks = Math.round(logRange);
      const logTickSpacing = logRange / ticks;
      for (let i = 0, logTick = logMin; i < ticks; i++, logTick += logTickSpacing) {
        logs.push(Math.pow(base, logTick));
      }
      logs.push(Math.pow(base, logMax));
      return {
        result: logs,
        niceMin: yMin,
        niceMax: yMax
      };
    }
    /**
     * @param {number | string} ticks
     * @param {number} index
     * @param {number} range
     */
    _adjustTicksForSmallRange(ticks, index, range) {
      let newTicks = ticks;
      if (typeof index !== "undefined" && this.w.config.yaxis[index].labels.formatter && this.w.config.yaxis[index].tickAmount === void 0) {
        const formattedVal = Number(
          this.w.config.yaxis[index].labels.formatter(1)
        );
        if (Utils$1.isNumber(formattedVal) && this.w.globals.yValueDecimal === 0) {
          newTicks = Math.ceil(range);
        }
      }
      return newTicks < ticks ? newTicks : ticks;
    }
    /**
     * @param {number} index
     * @param {number} minY
     * @param {number} maxY
     */
    setYScaleForIndex(index, minY, maxY) {
      const gl = this.w.globals;
      const cnf = this.w.config;
      const y = gl.isBarHorizontal ? cnf.xaxis : cnf.yaxis[index];
      if (typeof gl.yAxisScale[index] === "undefined") {
        gl.yAxisScale[index] = [];
      }
      const range = Math.abs(maxY - minY);
      if (y.logarithmic && range <= 5) {
        gl.invalidLogScale = true;
      }
      if (y.logarithmic && range > 5) {
        gl.allSeriesCollapsed = false;
        gl.yAxisScale[index] = y.forceNiceScale ? this.logarithmicScaleNice(minY, maxY, y.logBase) : this.logarithmicScale(minY, maxY, y.logBase);
      } else {
        if (maxY === -Number.MAX_VALUE || !Utils$1.isNumber(maxY) || minY === Number.MAX_VALUE || !Utils$1.isNumber(minY)) {
          gl.yAxisScale[index] = this.niceScale(
            Number.MIN_VALUE,
            0,
            index
          );
        } else {
          gl.allSeriesCollapsed = false;
          gl.yAxisScale[index] = this.niceScale(
            minY,
            maxY,
            index
          );
        }
      }
    }
    /**
     * @param {number} minX
     * @param {number} maxX
     */
    setXScale(minX, maxX) {
      const w = this.w;
      const gl = w.globals;
      if (maxX === -Number.MAX_VALUE || !Utils$1.isNumber(maxX)) {
        gl.xAxisScale = this.linearScale(0, 10, 10);
      } else {
        const ticks = gl.xTickAmount;
        gl.xAxisScale = this.linearScale(
          minX,
          maxX,
          ticks,
          0,
          w.config.xaxis.max === void 0 ? w.config.xaxis.stepSize : void 0
        );
      }
      return gl.xAxisScale;
    }
    scaleMultipleYAxes() {
      const cnf = this.w.config;
      const gl = this.w.globals;
      this.coreUtils.setSeriesYAxisMappings();
      const axisSeriesMap = gl.seriesYAxisMap;
      const minYArr = gl.minYArr;
      const maxYArr = gl.maxYArr;
      gl.allSeriesCollapsed = true;
      gl.barGroups = [];
      axisSeriesMap.forEach((axisSeries, ai) => {
        const groupNames = [];
        axisSeries.forEach((as) => {
          var _a;
          const group = (
            /** @type {Record<string,any>} */
            (_a = cnf.series[as]) == null ? void 0 : _a.group
          );
          if (groupNames.indexOf(group) < 0) {
            groupNames.push(group);
          }
        });
        if (axisSeries.length > 0) {
          let minY = Number.MAX_VALUE;
          let maxY = -Number.MAX_VALUE;
          let lowestY = minY;
          let highestY = maxY;
          let seriesType;
          let seriesGroupName;
          if (cnf.chart.stacked) {
            const mapSeries = new Array(gl.dataPoints).fill(0);
            const sumSeries = [];
            const posSeries = [];
            const negSeries = [];
            groupNames.forEach(() => {
              sumSeries.push(mapSeries.map(() => Number.MIN_VALUE));
              posSeries.push(mapSeries.map(() => Number.MIN_VALUE));
              negSeries.push(mapSeries.map(() => Number.MIN_VALUE));
            });
            for (let i = 0; i < axisSeries.length; i++) {
              if (!seriesType && /** @type {Record<string,any>} */
              cnf.series[axisSeries[i]].type) {
                seriesType = /** @type {Record<string,any>} */
                cnf.series[axisSeries[i]].type;
              }
              const si = axisSeries[i];
              if (
                /** @type {Record<string,any>} */
                cnf.series[si].group
              ) {
                seriesGroupName = /** @type {Record<string,any>} */
                cnf.series[si].group;
              } else {
                seriesGroupName = "axis-".concat(ai.toString());
              }
              const collapsed = !(gl.collapsedSeriesIndices.indexOf(si) < 0 && gl.ancillaryCollapsedSeriesIndices.indexOf(si) < 0);
              if (!collapsed) {
                gl.allSeriesCollapsed = false;
                groupNames.forEach((gn, gni) => {
                  if (
                    /** @type {Record<string,any>} */
                    cnf.series[si].group === gn
                  ) {
                    for (let j = 0; j < this.w.seriesData.series[si].length; j++) {
                      const val = this.w.seriesData.series[si][j];
                      if (val >= 0) {
                        posSeries[gni][j] += val;
                      } else {
                        negSeries[gni][j] += val;
                      }
                      sumSeries[gni][j] += val;
                      lowestY = Math.min(lowestY, val);
                      highestY = Math.max(highestY, val);
                    }
                  }
                });
              }
              if (seriesType === "bar" || seriesType === "column") {
                gl.barGroups.push(seriesGroupName);
              }
            }
            if (!seriesType) {
              seriesType = cnf.chart.type;
            }
            if (seriesType === "bar" || seriesType === "column") {
              groupNames.forEach((gn, gni) => {
                minY = Math.min(minY, Math.min.apply(null, negSeries[gni]));
                maxY = Math.max(maxY, Math.max.apply(null, posSeries[gni]));
              });
            } else {
              groupNames.forEach((gn, gni) => {
                lowestY = Math.min(lowestY, Math.min.apply(null, sumSeries[gni]));
                highestY = Math.max(
                  highestY,
                  Math.max.apply(null, sumSeries[gni])
                );
              });
              minY = lowestY;
              maxY = highestY;
            }
            if (minY === Number.MIN_VALUE && maxY === Number.MIN_VALUE) {
              maxY = -Number.MAX_VALUE;
            }
          } else {
            for (let i = 0; i < axisSeries.length; i++) {
              const si = axisSeries[i];
              minY = Math.min(minY, minYArr[si]);
              maxY = Math.max(maxY, maxYArr[si]);
              const collapsed = !(gl.collapsedSeriesIndices.indexOf(si) < 0 && gl.ancillaryCollapsedSeriesIndices.indexOf(si) < 0);
              if (!collapsed) {
                gl.allSeriesCollapsed = false;
              }
            }
          }
          if (cnf.yaxis[ai].min !== void 0) {
            if (typeof cnf.yaxis[ai].min === "function") {
              minY = cnf.yaxis[ai].min(minY);
            } else {
              minY = cnf.yaxis[ai].min;
            }
          }
          if (cnf.yaxis[ai].max !== void 0) {
            if (typeof cnf.yaxis[ai].max === "function") {
              maxY = cnf.yaxis[ai].max(maxY);
            } else {
              maxY = cnf.yaxis[ai].max;
            }
          }
          gl.barGroups = gl.barGroups.filter((v, i, a) => a.indexOf(v) === i);
          this.setYScaleForIndex(ai, minY, maxY);
          axisSeries.forEach((si) => {
            minYArr[si] = gl.yAxisScale[ai].niceMin;
            maxYArr[si] = gl.yAxisScale[ai].niceMax;
          });
        } else {
          this.setYScaleForIndex(ai, 0, -Number.MAX_VALUE);
        }
      });
    }
  }
  class Range {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this.scales = new Scales(this.w);
    }
    init() {
      this.setYRange();
      this.setXRange();
      this.setZRange();
    }
    /**
     * @param {number} startingSeriesIndex
     * @param {number | null} [endingSeriesIndex]
     */
    getMinYMaxY(startingSeriesIndex, lowestY = Number.MAX_VALUE, highestY = -Number.MAX_VALUE, endingSeriesIndex = null) {
      var _a, _b, _c, _d, _e;
      const cnf = this.w.config;
      const gl = this.w.globals;
      let maxY = -Number.MAX_VALUE;
      let minY = Number.MIN_VALUE;
      if (endingSeriesIndex === null) {
        endingSeriesIndex = startingSeriesIndex + 1;
      }
      const series = this.w.seriesData.series;
      let seriesMin = series;
      let seriesMax = series;
      if (cnf.chart.type === "candlestick") {
        seriesMin = this.w.candleData.seriesCandleL;
        seriesMax = this.w.candleData.seriesCandleH;
      } else if (cnf.chart.type === "boxPlot") {
        seriesMin = this.w.candleData.seriesCandleO;
        seriesMax = this.w.candleData.seriesCandleC;
      } else if (this.w.axisFlags.isRangeData) {
        seriesMin = this.w.rangeData.seriesRangeStart;
        seriesMax = this.w.rangeData.seriesRangeEnd;
      }
      let autoScaleYaxis = false;
      if (this.w.seriesData.seriesX.length >= endingSeriesIndex) {
        const brush = (
          /** @type {any} */
          (_a = gl.brushSource) == null ? void 0 : _a.w.config.chart.brush
        );
        if (cnf.chart.zoom.enabled && cnf.chart.zoom.autoScaleYaxis || (brush == null ? void 0 : brush.enabled) && (brush == null ? void 0 : brush.autoScaleYaxis)) {
          autoScaleYaxis = true;
        }
      }
      for (let i = startingSeriesIndex; i < endingSeriesIndex; i++) {
        gl.dataPoints = Math.max(gl.dataPoints, series[i].length);
        const seriesType = (
          /** @type {Record<string,any>} */
          cnf.series[i].type
        );
        if (this.w.labelData.categoryLabels.length) {
          gl.dataPoints = this.w.labelData.categoryLabels.filter(
            (label) => typeof label !== "undefined"
          ).length;
        }
        if (this.w.labelData.labels.length && cnf.xaxis.type !== "datetime" && /**
         * @param {number} a
         * @param {number[]} c
         */
        this.w.seriesData.series.reduce((a, c) => a + c.length, 0) !== 0) {
          gl.dataPoints = Math.max(gl.dataPoints, this.w.labelData.labels.length);
        }
        let firstXIndex = 0;
        let lastXIndex = series[i].length - 1;
        if (autoScaleYaxis) {
          if (cnf.xaxis.min) {
            for (; firstXIndex < lastXIndex && this.w.seriesData.seriesX[i][firstXIndex] < cnf.xaxis.min; firstXIndex++) {
            }
          }
          if (cnf.xaxis.max) {
            for (; lastXIndex > firstXIndex && this.w.seriesData.seriesX[i][lastXIndex] > cnf.xaxis.max; lastXIndex--) {
            }
          }
        }
        for (let j = firstXIndex; j <= lastXIndex && j < this.w.seriesData.series[i].length; j++) {
          let val = series[i][j];
          if (val !== null && Utils$1.isNumber(val)) {
            if (typeof ((_b = seriesMax[i]) == null ? void 0 : _b[j]) !== "undefined") {
              maxY = Math.max(maxY, seriesMax[i][j]);
              lowestY = Math.min(lowestY, seriesMax[i][j]);
            }
            if (typeof ((_c = seriesMin[i]) == null ? void 0 : _c[j]) !== "undefined") {
              lowestY = Math.min(lowestY, seriesMin[i][j]);
              highestY = Math.max(highestY, seriesMin[i][j]);
            }
            switch (seriesType) {
              case "candlestick":
                {
                  if (typeof this.w.candleData.seriesCandleC[i][j] !== "undefined") {
                    maxY = Math.max(maxY, this.w.candleData.seriesCandleH[i][j]);
                    lowestY = Math.min(
                      lowestY,
                      this.w.candleData.seriesCandleL[i][j]
                    );
                  }
                }
                break;
              case "boxPlot":
                {
                  if (typeof this.w.candleData.seriesCandleC[i][j] !== "undefined") {
                    maxY = Math.max(maxY, this.w.candleData.seriesCandleC[i][j]);
                    lowestY = Math.min(
                      lowestY,
                      this.w.candleData.seriesCandleO[i][j]
                    );
                  }
                }
                break;
            }
            if (seriesType && seriesType !== "candlestick" && seriesType !== "boxPlot" && seriesType !== "rangeArea" && seriesType !== "rangeBar") {
              maxY = Math.max(maxY, this.w.seriesData.series[i][j]);
              lowestY = Math.min(lowestY, this.w.seriesData.series[i][j]);
            }
            if (this.w.seriesData.seriesGoals[i] && this.w.seriesData.seriesGoals[i][j] && Array.isArray(this.w.seriesData.seriesGoals[i][j])) {
              this.w.seriesData.seriesGoals[i][j].forEach(
                (g) => {
                  maxY = Math.max(maxY, g.value);
                  lowestY = Math.min(lowestY, g.value);
                }
              );
            }
            highestY = maxY;
            val = Utils$1.noExponents(val);
            if (Utils$1.isFloat(val)) {
              gl.yValueDecimal = Math.max(
                gl.yValueDecimal,
                val.toString().split(".")[1].length
              );
            }
            if (minY > ((_d = seriesMin[i]) == null ? void 0 : _d[j]) && ((_e = seriesMin[i]) == null ? void 0 : _e[j]) < 0) {
              minY = seriesMin[i][j];
            }
          } else {
            gl.hasNullValues = true;
          }
        }
        if (seriesType === "bar" || seriesType === "column") {
          if (minY < 0 && maxY < 0) {
            maxY = 0;
            highestY = Math.max(highestY, 0);
          }
          if (minY === Number.MIN_VALUE) {
            minY = 0;
            lowestY = Math.min(lowestY, 0);
          }
        }
      }
      if (cnf.chart.type === "rangeBar" && this.w.rangeData.seriesRangeStart.length && gl.isBarHorizontal) {
        minY = lowestY;
      }
      if (cnf.chart.type === "bar") {
        if (minY < 0 && maxY < 0) {
          maxY = 0;
        }
        if (minY === Number.MIN_VALUE) {
          minY = 0;
        }
      }
      return {
        minY,
        maxY,
        lowestY,
        highestY
      };
    }
    setYRange() {
      const gl = this.w.globals;
      const cnf = this.w.config;
      gl.maxY = -Number.MAX_VALUE;
      gl.minY = Number.MIN_VALUE;
      let lowestYInAllSeries = Number.MAX_VALUE;
      let minYMaxY;
      if (gl.isMultipleYAxis) {
        lowestYInAllSeries = Number.MAX_VALUE;
        for (let i = 0; i < this.w.seriesData.series.length; i++) {
          minYMaxY = this.getMinYMaxY(i);
          gl.minYArr[i] = minYMaxY.lowestY;
          gl.maxYArr[i] = minYMaxY.highestY;
          lowestYInAllSeries = Math.min(lowestYInAllSeries, minYMaxY.lowestY);
        }
      }
      minYMaxY = this.getMinYMaxY(
        0,
        lowestYInAllSeries,
        void 0,
        this.w.seriesData.series.length
      );
      if (cnf.chart.type === "bar") {
        gl.minY = minYMaxY.minY;
        gl.maxY = minYMaxY.maxY;
      } else {
        gl.minY = minYMaxY.lowestY;
        gl.maxY = minYMaxY.highestY;
      }
      lowestYInAllSeries = minYMaxY.lowestY;
      if (cnf.chart.stacked) {
        this._setStackedMinMax();
      }
      if (cnf.chart.type === "line" || cnf.chart.type === "area" || cnf.chart.type === "scatter" || cnf.chart.type === "candlestick" || cnf.chart.type === "boxPlot" || cnf.chart.type === "rangeBar" && !gl.isBarHorizontal) {
        if (gl.minY === Number.MIN_VALUE && lowestYInAllSeries !== -Number.MAX_VALUE && lowestYInAllSeries !== gl.maxY) {
          gl.minY = lowestYInAllSeries;
        }
      } else {
        gl.minY = gl.minY !== Number.MIN_VALUE ? Math.min(minYMaxY.minY, gl.minY) : minYMaxY.minY;
      }
      cnf.yaxis.forEach((yaxe, index) => {
        if (yaxe.max !== void 0) {
          if (typeof yaxe.max === "number") {
            gl.maxYArr[index] = yaxe.max;
          } else if (typeof yaxe.max === "function") {
            gl.maxYArr[index] = yaxe.max(
              gl.isMultipleYAxis ? gl.maxYArr[index] : gl.maxY
            );
          }
          gl.maxY = gl.maxYArr[index];
        }
        if (yaxe.min !== void 0) {
          if (typeof yaxe.min === "number") {
            gl.minYArr[index] = yaxe.min;
          } else if (typeof yaxe.min === "function") {
            gl.minYArr[index] = yaxe.min(
              gl.isMultipleYAxis ? gl.minYArr[index] === Number.MIN_VALUE ? 0 : gl.minYArr[index] : gl.minY
            );
          }
          gl.minY = gl.minYArr[index];
        }
      });
      if (gl.isBarHorizontal) {
        const minmax = ["min", "max"];
        minmax.forEach((m) => {
          if (cnf.xaxis[m] !== void 0 && typeof cnf.xaxis[m] === "number") {
            m === "min" ? gl.minY = cnf.xaxis[m] : gl.maxY = cnf.xaxis[m];
          }
        });
      }
      if (gl.isMultipleYAxis) {
        this.scales.scaleMultipleYAxes();
        gl.minY = lowestYInAllSeries;
      } else {
        this.scales.setYScaleForIndex(0, gl.minY, gl.maxY);
        gl.minY = gl.yAxisScale[0].niceMin;
        gl.maxY = gl.yAxisScale[0].niceMax;
        gl.minYArr[0] = gl.minY;
        gl.maxYArr[0] = gl.maxY;
      }
      gl.barGroups = [];
      gl.lineGroups = [];
      gl.areaGroups = [];
      cnf.series.forEach((s) => {
        const _s = (
          /** @type {any} */
          s
        );
        const type = _s.type || cnf.chart.type;
        switch (type) {
          case "bar":
          case "column":
            gl.barGroups.push(_s.group);
            break;
          case "line":
            gl.lineGroups.push(_s.group);
            break;
          case "area":
            gl.areaGroups.push(_s.group);
            break;
        }
      });
      gl.barGroups = gl.barGroups.filter((v, i, a) => a.indexOf(v) === i);
      gl.lineGroups = gl.lineGroups.filter((v, i, a) => a.indexOf(v) === i);
      gl.areaGroups = gl.areaGroups.filter((v, i, a) => a.indexOf(v) === i);
      return {
        minY: gl.minY,
        maxY: gl.maxY,
        minYArr: gl.minYArr,
        maxYArr: gl.maxYArr,
        yAxisScale: gl.yAxisScale
      };
    }
    setXRange() {
      const gl = this.w.globals;
      const cnf = this.w.config;
      const isXNumeric = cnf.xaxis.type === "numeric" || cnf.xaxis.type === "datetime" || cnf.xaxis.type === "category" && !this.w.axisFlags.noLabelsProvided || this.w.axisFlags.noLabelsProvided || this.w.axisFlags.isXNumeric;
      const getInitialMinXMaxX = () => {
        for (let i = 0; i < this.w.seriesData.series.length; i++) {
          if (this.w.labelData.labels[i]) {
            for (let j = 0; j < this.w.labelData.labels[i].length; j++) {
              if (this.w.labelData.labels[i][j] !== null && Utils$1.isNumber(this.w.labelData.labels[i][j])) {
                gl.maxX = Math.max(
                  gl.maxX,
                  /** @type {number} */
                  /** @type {any} */
                  this.w.labelData.labels[i][j]
                );
                gl.initialMaxX = Math.max(
                  gl.maxX,
                  /** @type {number} */
                  /** @type {any} */
                  this.w.labelData.labels[i][j]
                );
                gl.minX = Math.min(
                  gl.minX,
                  /** @type {number} */
                  /** @type {any} */
                  this.w.labelData.labels[i][j]
                );
                gl.initialMinX = Math.min(
                  gl.minX,
                  /** @type {number} */
                  /** @type {any} */
                  this.w.labelData.labels[i][j]
                );
              }
            }
          }
        }
      };
      if (this.w.axisFlags.isXNumeric) {
        getInitialMinXMaxX();
      }
      if (this.w.axisFlags.noLabelsProvided) {
        if (cnf.xaxis.categories.length === 0) {
          gl.maxX = /** @type {any} */
          this.w.labelData.labels[this.w.labelData.labels.length - 1];
          gl.initialMaxX = /** @type {any} */
          this.w.labelData.labels[this.w.labelData.labels.length - 1];
          gl.minX = 1;
          gl.initialMinX = 1;
        }
      }
      if (this.w.axisFlags.isXNumeric || this.w.axisFlags.noLabelsProvided || this.w.axisFlags.dataFormatXNumeric) {
        let ticks = 10;
        if (cnf.xaxis.tickAmount === void 0) {
          ticks = Math.round(gl.svgWidth / 150);
          if (cnf.xaxis.type === "numeric" && gl.dataPoints < 30) {
            ticks = gl.dataPoints - 1;
          }
          if (ticks > gl.dataPoints && gl.dataPoints !== 0) {
            ticks = gl.dataPoints - 1;
          }
        } else if (cnf.xaxis.tickAmount === "dataPoints") {
          if (this.w.seriesData.series.length > 1) {
            ticks = this.w.seriesData.series[gl.maxValsInArrayIndex].length - 1;
          }
          if (this.w.axisFlags.isXNumeric) {
            const diff = Math.round(gl.maxX - gl.minX);
            if (diff < 30) {
              ticks = diff;
            }
          }
        } else {
          ticks = cnf.xaxis.tickAmount;
        }
        gl.xTickAmount = ticks;
        if (cnf.xaxis.max !== void 0 && typeof cnf.xaxis.max === "number") {
          gl.maxX = cnf.xaxis.max;
        }
        if (cnf.xaxis.min !== void 0 && typeof cnf.xaxis.min === "number") {
          gl.minX = cnf.xaxis.min;
        }
        if (cnf.xaxis.range !== void 0) {
          gl.minX = gl.maxX - cnf.xaxis.range;
        }
        if (gl.minX !== Number.MAX_VALUE && gl.maxX !== -Number.MAX_VALUE) {
          if (cnf.xaxis.convertedCatToNumeric && !this.w.axisFlags.dataFormatXNumeric) {
            const catScale = [];
            for (let i = gl.minX - 1; i < gl.maxX; i++) {
              catScale.push(i + 1);
            }
            gl.xAxisScale = {
              result: catScale,
              niceMin: catScale[0],
              niceMax: catScale[catScale.length - 1]
            };
          } else {
            gl.xAxisScale = this.scales.setXScale(gl.minX, gl.maxX);
          }
        } else {
          gl.xAxisScale = this.scales.linearScale(
            0,
            ticks,
            ticks,
            0,
            cnf.xaxis.stepSize
          );
          if (this.w.axisFlags.noLabelsProvided && this.w.labelData.labels.length > 0) {
            gl.xAxisScale = this.scales.linearScale(
              1,
              this.w.labelData.labels.length,
              ticks - 1,
              0,
              cnf.xaxis.stepSize
            );
            this.w.seriesData.seriesX = /** @type {any} */
            this.w.labelData.labels.slice();
          }
        }
        if (isXNumeric) {
          this.w.labelData.labels = /** @type {any} */
          gl.xAxisScale.result.slice();
        }
      }
      if (gl.isBarHorizontal && this.w.labelData.labels.length) {
        gl.xTickAmount = this.w.labelData.labels.length;
      }
      this._handleSingleDataPoint();
      this._getMinXDiff();
      return {
        minX: gl.minX,
        maxX: gl.maxX
      };
    }
    setZRange() {
      const gl = this.w.globals;
      if (!this.w.axisFlags.isDataXYZ) return;
      for (let i = 0; i < this.w.seriesData.series.length; i++) {
        if (typeof this.w.seriesData.seriesZ[i] !== "undefined") {
          for (let j = 0; j < this.w.seriesData.seriesZ[i].length; j++) {
            if (this.w.seriesData.seriesZ[i][j] !== null && Utils$1.isNumber(this.w.seriesData.seriesZ[i][j])) {
              gl.maxZ = Math.max(gl.maxZ, this.w.seriesData.seriesZ[i][j]);
              gl.minZ = Math.min(gl.minZ, this.w.seriesData.seriesZ[i][j]);
            }
          }
        }
      }
    }
    _handleSingleDataPoint() {
      const gl = this.w.globals;
      const cnf = this.w.config;
      if (gl.minX === gl.maxX) {
        const datetimeObj = new DateTime(this.w);
        if (cnf.xaxis.type === "datetime") {
          const newMinX = datetimeObj.getDate(gl.minX);
          if (cnf.xaxis.labels.datetimeUTC) {
            newMinX.setUTCDate(newMinX.getUTCDate() - 2);
          } else {
            newMinX.setDate(newMinX.getDate() - 2);
          }
          gl.minX = new Date(newMinX).getTime();
          const newMaxX = datetimeObj.getDate(gl.maxX);
          if (cnf.xaxis.labels.datetimeUTC) {
            newMaxX.setUTCDate(newMaxX.getUTCDate() + 2);
          } else {
            newMaxX.setDate(newMaxX.getDate() + 2);
          }
          gl.maxX = new Date(newMaxX).getTime();
        } else if (cnf.xaxis.type === "numeric" || cnf.xaxis.type === "category" && !this.w.axisFlags.noLabelsProvided) {
          gl.minX = gl.minX - 2;
          gl.initialMinX = gl.minX;
          gl.maxX = gl.maxX + 2;
          gl.initialMaxX = gl.maxX;
        }
      }
    }
    _getMinXDiff() {
      const gl = this.w.globals;
      if (this.w.axisFlags.isXNumeric) {
        this.w.seriesData.seriesX.forEach((sX) => {
          if (sX.length) {
            if (sX.length === 1) {
              sX.push(
                this.w.seriesData.seriesX[gl.maxValsInArrayIndex][this.w.seriesData.seriesX[gl.maxValsInArrayIndex].length - 1]
              );
            }
            const seriesX = sX.slice();
            seriesX.sort((a, b) => a - b);
            seriesX.forEach((s, j) => {
              if (j > 0) {
                const xDiff = s - seriesX[j - 1];
                if (xDiff > 0) {
                  gl.minXDiff = Math.min(xDiff, gl.minXDiff);
                }
              }
            });
            if (gl.dataPoints === 1 || gl.minXDiff === Number.MAX_VALUE) {
              gl.minXDiff = 0.5;
            }
          }
        });
      }
    }
    _setStackedMinMax() {
      const gl = this.w.globals;
      if (!this.w.seriesData.series.length) return;
      let seriesGroups = this.w.labelData.seriesGroups;
      if (!seriesGroups.length) {
        seriesGroups = [this.w.seriesData.seriesNames.map((name2) => name2)];
      }
      const stackedPoss = {};
      const stackedNegs = {};
      seriesGroups.forEach((group) => {
        stackedPoss[group] = [];
        stackedNegs[group] = [];
        const indicesOfSeriesInGroup = this.w.config.series.map(
          (serie, si) => group.indexOf(this.w.seriesData.seriesNames[si]) > -1 ? si : null
        ).filter((f) => f !== null);
        indicesOfSeriesInGroup.forEach((i) => {
          var _a, _b, _c, _d;
          for (let j = 0; j < this.w.seriesData.series[gl.maxValsInArrayIndex].length; j++) {
            if (typeof stackedPoss[group][j] === "undefined") {
              stackedPoss[group][j] = 0;
              stackedNegs[group][j] = 0;
            }
            const stackSeries = this.w.config.chart.stacked && !gl.comboCharts || this.w.config.chart.stacked && gl.comboCharts && (!this.w.config.chart.stackOnlyBar || /** @type {Record<string,any>} */
            ((_b = (_a = this.w.config.series) == null ? void 0 : _a[i]) == null ? void 0 : _b.type) === "bar" || /** @type {Record<string,any>} */
            ((_d = (_c = this.w.config.series) == null ? void 0 : _c[i]) == null ? void 0 : _d.type) === "column");
            if (stackSeries) {
              if (this.w.seriesData.series[i][j] !== null && Utils$1.isNumber(this.w.seriesData.series[i][j])) {
                this.w.seriesData.series[i][j] > 0 ? stackedPoss[group][j] += parseFloat(String(this.w.seriesData.series[i][j])) + 1e-4 : stackedNegs[group][j] += parseFloat(
                  String(this.w.seriesData.series[i][j])
                );
              }
            }
          }
        });
      });
      Object.entries(stackedPoss).forEach(([key]) => {
        stackedPoss[key].forEach(
          (_, stgi) => {
            gl.maxY = Math.max(gl.maxY, stackedPoss[key][stgi]);
            gl.minY = Math.min(gl.minY, stackedNegs[key][stgi]);
          }
        );
      });
    }
  }
  function getThemePalettes() {
    return {
      palette1: ["#008FFB", "#00E396", "#FEB019", "#FF4560", "#775DD0"],
      palette2: ["#3F51B5", "#03A9F4", "#4CAF50", "#F9CE1D", "#FF9800"],
      palette3: ["#33B2DF", "#546E7A", "#D4526E", "#13D8AA", "#A5978B"],
      palette4: ["#4ECDC4", "#C7F464", "#81D4FA", "#FD6A6A", "#546E7A"],
      palette5: ["#2B908F", "#F9A3A4", "#90EE7E", "#FA4443", "#69D2E7"],
      palette6: ["#449DD1", "#F86624", "#EA3546", "#662E9B", "#C5D86D"],
      palette7: ["#D7263D", "#1B998B", "#2E294E", "#F46036", "#E2C044"],
      palette8: ["#662E9B", "#F86624", "#F9C80E", "#EA3546", "#43BCCD"],
      palette9: ["#5C4742", "#A5978B", "#8D5B4C", "#5A2A27", "#C4BBAF"],
      palette10: ["#A300D6", "#7D02EB", "#5653FE", "#2983FF", "#00B1F2"],
      // CVD-safe palettes (Wong 2011 / IBM design)
      cvdDeuteranopia: ["#0072B2", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#D55E00", "#CC79A7"],
      cvdProtanopia: ["#0077BB", "#EE7733", "#009988", "#EE3377", "#BBBBBB", "#33BBEE", "#CC3311"],
      cvdTritanopia: ["#CC3311", "#009988", "#EE7733", "#0077BB", "#EE3377", "#BBBBBB", "#33BBEE"],
      highContrast: ["#005A9C", "#C00000", "#007A33", "#6C3483", "#7B3F00", "#0097A7", "#4A235A"]
    };
  }
  class YAxis {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {any} [elgrid]
     */
    constructor(w, { theme = null, timeScale = null } = {}, elgrid) {
      this.w = w;
      this.elgrid = elgrid;
      this.xaxisFontSize = w.config.xaxis.labels.style.fontSize;
      this.axisFontFamily = w.config.xaxis.labels.style.fontFamily;
      this.xaxisForeColors = w.config.xaxis.labels.style.colors;
      this.isCategoryBarHorizontal = w.config.chart.type === "bar" && w.config.plotOptions.bar.horizontal;
      this.xAxisoffX = w.config.xaxis.position === "bottom" ? w.layout.gridHeight : 0;
      this.drawnLabels = [];
      this.axesUtils = new AxesUtils(w, { theme, timeScale });
    }
    /**
     * @param {number} realIndex
     */
    drawYaxis(realIndex) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const yaxisStyle = w.config.yaxis[realIndex].labels.style;
      const {
        fontSize: yaxisFontSize,
        fontFamily: yaxisFontFamily,
        fontWeight: yaxisFontWeight
      } = yaxisStyle;
      const elYaxis = graphics.group({
        class: "apexcharts-yaxis",
        rel: realIndex,
        transform: `translate(${w.globals.translateYAxisX[realIndex]}, 0)`
      });
      if (this.axesUtils.isYAxisHidden(realIndex)) return elYaxis;
      const elYaxisTexts = graphics.group({ class: "apexcharts-yaxis-texts-g" });
      elYaxis.add(elYaxisTexts);
      const tickAmount = w.globals.yAxisScale[realIndex].result.length - 1;
      const labelsDivider = w.layout.gridHeight / tickAmount;
      const lbFormatter = w.formatters.yLabelFormatters[realIndex];
      const labels = this.axesUtils.checkForReversedLabels(
        realIndex,
        w.globals.yAxisScale[realIndex].result.slice()
      );
      if (w.config.yaxis[realIndex].labels.show) {
        let lY = w.layout.translateY + w.config.yaxis[realIndex].labels.offsetY;
        if (w.globals.isBarHorizontal) lY = 0;
        else if (w.config.chart.type === "heatmap") lY -= labelsDivider / 2;
        lY += parseInt(yaxisFontSize, 10) / 3;
        let firstLabel = null;
        for (let i = tickAmount; i >= 0; i--) {
          const val = lbFormatter(labels[i], i, w);
          let xPad = w.config.yaxis[realIndex].labels.padding;
          if (w.config.yaxis[realIndex].opposite && w.config.yaxis.length !== 0)
            xPad *= -1;
          const textAnchor = this.getTextAnchor(
            w.config.yaxis[realIndex].labels.align,
            w.config.yaxis[realIndex].opposite
          );
          const yColors = this.axesUtils.getYAxisForeColor(
            yaxisStyle.colors,
            realIndex
          );
          const foreColor = Array.isArray(yColors) ? yColors[i] : yColors;
          const existingYLabels = Array.from(
            w.dom.baseEl.querySelectorAll(
              `.apexcharts-yaxis[rel='${realIndex}'] .apexcharts-yaxis-label tspan`
            )
          ).map((label2) => label2.textContent);
          const label = graphics.drawText({
            x: xPad,
            y: lY,
            text: existingYLabels.includes(val) && !w.config.yaxis[realIndex].labels.showDuplicates ? "" : val,
            textAnchor,
            fontSize: yaxisFontSize,
            fontFamily: yaxisFontFamily,
            fontWeight: yaxisFontWeight,
            maxWidth: w.config.yaxis[realIndex].labels.maxWidth,
            foreColor,
            isPlainText: false,
            cssClass: `apexcharts-yaxis-label ${yaxisStyle.cssClass}`
          });
          elYaxisTexts.add(label);
          this.addTooltip(label, val);
          if (firstLabel === null) {
            firstLabel = label;
          }
          if (w.config.yaxis[realIndex].labels.rotate !== 0) {
            this.rotateLabel(
              graphics,
              label,
              firstLabel,
              w.config.yaxis[realIndex].labels.rotate
            );
          }
          lY += labelsDivider;
        }
      }
      this.addYAxisTitle(graphics, elYaxis, realIndex);
      this.addAxisBorder(graphics, elYaxis, realIndex, tickAmount, labelsDivider);
      return elYaxis;
    }
    /**
     * @param {string} align
     * @param {boolean} opposite
     */
    getTextAnchor(align, opposite) {
      if (align === "left") return "start";
      if (align === "center") return "middle";
      if (align === "right") return "end";
      return opposite ? "start" : "end";
    }
    /**
     * @param {any} label
     * @param {any} val
     */
    addTooltip(label, val) {
      const elTooltipTitle = BrowserAPIs.createElementNS(SVGNS, "title");
      elTooltipTitle.textContent = Array.isArray(val) ? val.join(" ") : val;
      label.node.appendChild(elTooltipTitle);
    }
    /**
     * @param {import('../Graphics').default} graphics
     * @param {any} label
     * @param {any} firstLabel
     * @param {number} rotate
     */
    rotateLabel(graphics, label, firstLabel, rotate) {
      const firstLabelCenter = graphics.rotateAroundCenter(firstLabel.node);
      const labelCenter = graphics.rotateAroundCenter(label.node);
      label.node.setAttribute(
        "transform",
        `rotate(${rotate} ${firstLabelCenter.x} ${labelCenter.y})`
      );
    }
    /**
     * @param {import('../Graphics').default} graphics
     * @param {any} elYaxis
     * @param {number} realIndex
     */
    addYAxisTitle(graphics, elYaxis, realIndex) {
      const w = this.w;
      if (w.config.yaxis[realIndex].title.text !== void 0) {
        const elYaxisTitle = graphics.group({ class: "apexcharts-yaxis-title" });
        const x = w.config.yaxis[realIndex].opposite ? w.globals.translateYAxisX[realIndex] : 0;
        const elYAxisTitleText = graphics.drawText({
          x,
          y: w.layout.gridHeight / 2 + w.layout.translateY + w.config.yaxis[realIndex].title.offsetY,
          text: w.config.yaxis[realIndex].title.text,
          textAnchor: "end",
          foreColor: w.config.yaxis[realIndex].title.style.color,
          fontSize: w.config.yaxis[realIndex].title.style.fontSize,
          fontWeight: w.config.yaxis[realIndex].title.style.fontWeight,
          fontFamily: w.config.yaxis[realIndex].title.style.fontFamily,
          cssClass: `apexcharts-yaxis-title-text ${w.config.yaxis[realIndex].title.style.cssClass}`
        });
        elYaxisTitle.add(elYAxisTitleText);
        elYaxis.add(elYaxisTitle);
      }
    }
    /**
     * @param {import('../Graphics').default} graphics
     * @param {any} elYaxis
     * @param {number} realIndex
     * @param {number} tickAmount
     * @param {number} labelsDivider
     */
    addAxisBorder(graphics, elYaxis, realIndex, tickAmount, labelsDivider) {
      const w = this.w;
      const axisBorder = w.config.yaxis[realIndex].axisBorder;
      let x = 31 + axisBorder.offsetX;
      if (w.config.yaxis[realIndex].opposite) x = -31 - axisBorder.offsetX;
      if (axisBorder.show) {
        const elVerticalLine = graphics.drawLine(
          x,
          w.layout.translateY + axisBorder.offsetY - 2,
          x,
          w.layout.gridHeight + w.layout.translateY + axisBorder.offsetY + 2,
          axisBorder.color,
          0,
          axisBorder.width
        );
        elYaxis.add(elVerticalLine);
      }
      if (w.config.yaxis[realIndex].axisTicks.show) {
        this.axesUtils.drawYAxisTicks(
          x,
          tickAmount,
          axisBorder,
          w.config.yaxis[realIndex].axisTicks,
          realIndex,
          labelsDivider,
          elYaxis
        );
      }
    }
    /**
     * @param {number} realIndex
     */
    drawYaxisInversed(realIndex) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const elXaxis = graphics.group({
        class: "apexcharts-xaxis apexcharts-yaxis-inversed"
      });
      const elXaxisTexts = graphics.group({
        class: "apexcharts-xaxis-texts-g",
        transform: `translate(${w.layout.translateXAxisX}, ${w.layout.translateXAxisY})`
      });
      elXaxis.add(elXaxisTexts);
      let tickAmount = w.globals.yAxisScale[realIndex].result.length - 1;
      const labelsDivider = w.layout.gridWidth / tickAmount + 0.1;
      let l = labelsDivider + w.config.xaxis.labels.offsetX;
      const lbFormatter = w.formatters.xLabelFormatter;
      let labels = this.axesUtils.checkForReversedLabels(
        realIndex,
        w.globals.yAxisScale[realIndex].result.slice()
      );
      const timescaleLabels = w.labelData.timescaleLabels;
      if (timescaleLabels.length > 0) {
        this.xaxisLabels = timescaleLabels.slice();
        labels = timescaleLabels.slice();
        tickAmount = labels.length;
      }
      if (w.config.xaxis.labels.show) {
        for (let i = timescaleLabels.length ? 0 : tickAmount; timescaleLabels.length ? i < timescaleLabels.length : i >= 0; timescaleLabels.length ? i++ : i--) {
          let val = lbFormatter == null ? void 0 : lbFormatter(labels[i], i, w);
          let x = w.layout.gridWidth + w.globals.padHorizontal - (l - labelsDivider + w.config.xaxis.labels.offsetX);
          if (timescaleLabels.length) {
            const label = this.axesUtils.getLabel(
              labels,
              timescaleLabels,
              x,
              i,
              this.drawnLabels,
              this.xaxisFontSize
            );
            x = label.x;
            val = label.text;
            this.drawnLabels.push(label.text);
            if (i === 0 && w.globals.skipFirstTimelinelabel) val = "";
            if (i === labels.length - 1 && w.globals.skipLastTimelinelabel)
              val = "";
          }
          const elTick = graphics.drawText({
            x,
            y: this.xAxisoffX + w.config.xaxis.labels.offsetY + 30 - (w.config.xaxis.position === "top" ? w.layout.xAxisHeight + w.config.xaxis.axisTicks.height - 2 : 0),
            text: val,
            textAnchor: "middle",
            foreColor: Array.isArray(this.xaxisForeColors) ? this.xaxisForeColors[realIndex] : this.xaxisForeColors,
            fontSize: this.xaxisFontSize,
            fontFamily: this.axisFontFamily,
            fontWeight: w.config.xaxis.labels.style.fontWeight,
            isPlainText: false,
            cssClass: `apexcharts-xaxis-label ${w.config.xaxis.labels.style.cssClass}`
          });
          elXaxisTexts.add(elTick);
          this.addTooltip(elTick, val);
          l += labelsDivider;
        }
      }
      this.inversedYAxisTitleText(elXaxis);
      this.inversedYAxisBorder(elXaxis);
      return elXaxis;
    }
    /**
     * @param {any} parent
     */
    inversedYAxisBorder(parent) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const axisBorder = w.config.xaxis.axisBorder;
      if (axisBorder.show) {
        let lineCorrection = 0;
        if (w.config.chart.type === "bar" && w.axisFlags.isXNumeric)
          lineCorrection -= 15;
        const elHorzLine = graphics.drawLine(
          w.globals.padHorizontal + lineCorrection + axisBorder.offsetX,
          this.xAxisoffX,
          w.layout.gridWidth,
          this.xAxisoffX,
          axisBorder.color,
          0,
          axisBorder.height
        );
        if (this.elgrid && this.elgrid.elGridBorders && w.config.grid.show) {
          this.elgrid.elGridBorders.add(elHorzLine);
        } else {
          parent.add(elHorzLine);
        }
      }
    }
    /**
     * @param {any} parent
     */
    inversedYAxisTitleText(parent) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      if (w.config.xaxis.title.text !== void 0) {
        const elYaxisTitle = graphics.group({
          class: "apexcharts-xaxis-title apexcharts-yaxis-title-inversed"
        });
        const elYAxisTitleText = graphics.drawText({
          x: w.layout.gridWidth / 2 + w.config.xaxis.title.offsetX,
          y: this.xAxisoffX + parseFloat(this.xaxisFontSize) + parseFloat(w.config.xaxis.title.style.fontSize) + w.config.xaxis.title.offsetY + 20,
          text: w.config.xaxis.title.text,
          textAnchor: "middle",
          fontSize: w.config.xaxis.title.style.fontSize,
          fontFamily: w.config.xaxis.title.style.fontFamily,
          fontWeight: w.config.xaxis.title.style.fontWeight,
          foreColor: w.config.xaxis.title.style.color,
          cssClass: `apexcharts-xaxis-title-text ${w.config.xaxis.title.style.cssClass}`
        });
        elYaxisTitle.add(elYAxisTitleText);
        parent.add(elYaxisTitle);
      }
    }
    /**
     * @param {number} realIndex
     * @param {boolean} yAxisOpposite
     */
    yAxisTitleRotate(realIndex, yAxisOpposite) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const elYAxisLabelsWrap = w.dom.baseEl.querySelector(
        `.apexcharts-yaxis[rel='${realIndex}'] .apexcharts-yaxis-texts-g`
      );
      const yAxisLabelsCoord = elYAxisLabelsWrap ? elYAxisLabelsWrap.getBoundingClientRect() : { width: 0, height: 0 };
      const yAxisTitle = w.dom.baseEl.querySelector(
        `.apexcharts-yaxis[rel='${realIndex}'] .apexcharts-yaxis-title text`
      );
      const yAxisTitleCoord = yAxisTitle ? yAxisTitle.getBoundingClientRect() : { width: 0, height: 0 };
      if (yAxisTitle) {
        const x = this.xPaddingForYAxisTitle(
          realIndex,
          yAxisLabelsCoord,
          yAxisTitleCoord,
          yAxisOpposite
        );
        yAxisTitle.setAttribute("x", String(x.xPos - (yAxisOpposite ? 10 : 0)));
        const titleRotatingCenter = graphics.rotateAroundCenter(yAxisTitle);
        yAxisTitle.setAttribute(
          "transform",
          `rotate(${yAxisOpposite ? w.config.yaxis[realIndex].title.rotate * -1 : w.config.yaxis[realIndex].title.rotate} ${titleRotatingCenter.x} ${titleRotatingCenter.y})`
        );
      }
    }
    /**
     * @param {number} realIndex
     * @param {{width: number, height: number}} yAxisLabelsCoord
     * @param {{width: number, height: number}} yAxisTitleCoord
     * @param {boolean} yAxisOpposite
     */
    xPaddingForYAxisTitle(realIndex, yAxisLabelsCoord, yAxisTitleCoord, yAxisOpposite) {
      const w = this.w;
      let x = 0;
      let padd = 10;
      if (w.config.yaxis[realIndex].title.text === void 0 || realIndex < 0) {
        return { xPos: x, padd: 0 };
      }
      if (yAxisOpposite) {
        x = yAxisLabelsCoord.width + w.config.yaxis[realIndex].title.offsetX + yAxisTitleCoord.width / 2 + padd / 2;
      } else {
        x = yAxisLabelsCoord.width * -1 + w.config.yaxis[realIndex].title.offsetX + padd / 2 + yAxisTitleCoord.width / 2;
        if (w.globals.isBarHorizontal) {
          padd = 25;
          x = yAxisLabelsCoord.width * -1 - w.config.yaxis[realIndex].title.offsetX - padd;
        }
      }
      return { xPos: x, padd };
    }
    /**
     * @param {Array<{width: number, height: number}>} yaxisLabelCoords
     * @param {Array<{width: number, height: number}>} yTitleCoords
     */
    setYAxisXPosition(yaxisLabelCoords, yTitleCoords) {
      const w = this.w;
      let xLeft = 0;
      let xRight = 0;
      let leftOffsetX = 18;
      let rightOffsetX = 1;
      if (w.config.yaxis.length > 1) this.multipleYs = true;
      w.config.yaxis.forEach((yaxe, index) => {
        const shouldNotDrawAxis = w.globals.ignoreYAxisIndexes.includes(index) || !yaxe.show || yaxe.floating || yaxisLabelCoords[index].width === 0;
        const axisWidth = yaxisLabelCoords[index].width + yTitleCoords[index].width;
        if (!yaxe.opposite) {
          xLeft = w.layout.translateX - leftOffsetX;
          if (!shouldNotDrawAxis) leftOffsetX += axisWidth + 20;
          w.globals.translateYAxisX[index] = xLeft + yaxe.labels.offsetX;
        } else {
          if (w.globals.isBarHorizontal) {
            xRight = w.layout.gridWidth + w.layout.translateX - 1;
            w.globals.translateYAxisX[index] = xRight - yaxe.labels.offsetX;
          } else {
            xRight = w.layout.gridWidth + w.layout.translateX + rightOffsetX;
            if (!shouldNotDrawAxis) rightOffsetX += axisWidth + 20;
            w.globals.translateYAxisX[index] = xRight - yaxe.labels.offsetX + 20;
          }
        }
      });
    }
    setYAxisTextAlignments() {
      const w = this.w;
      const yaxis = Array.from(
        w.dom.baseEl.getElementsByClassName("apexcharts-yaxis")
      );
      yaxis.forEach((y, index) => {
        const yaxe = w.config.yaxis[index];
        if (yaxe && !yaxe.floating && yaxe.labels.align !== void 0) {
          const yAxisInner = w.dom.baseEl.querySelector(
            `.apexcharts-yaxis[rel='${index}'] .apexcharts-yaxis-texts-g`
          );
          const yAxisTexts = Array.from(
            w.dom.baseEl.querySelectorAll(
              `.apexcharts-yaxis[rel='${index}'] .apexcharts-yaxis-label`
            )
          );
          const rect = (
            /** @type {Element} */
            yAxisInner.getBoundingClientRect()
          );
          yAxisTexts.forEach((label) => {
            label.setAttribute("text-anchor", yaxe.labels.align);
          });
          if (yaxe.labels.align === "left" && !yaxe.opposite) {
            yAxisInner.setAttribute(
              "transform",
              `translate(-${rect.width}, 0)`
            );
          } else if (yaxe.labels.align === "center") {
            yAxisInner.setAttribute(
              "transform",
              `translate(${rect.width / 2 * (!yaxe.opposite ? -1 : 1)}, 0)`
            );
          } else if (yaxe.labels.align === "right" && yaxe.opposite) {
            yAxisInner.setAttribute(
              "transform",
              `translate(${rect.width}, 0)`
            );
          }
        }
      });
    }
  }
  class Events {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.documentEvent = this.documentEvent.bind(this);
    }
    /**
     * @param {string} name
     * @param {Function} handler
     */
    addEventListener(name2, handler) {
      const w = this.w;
      if (Object.prototype.hasOwnProperty.call(w.globals.events, name2)) {
        w.globals.events[name2].push(handler);
      } else {
        w.globals.events[name2] = [handler];
      }
    }
    /**
     * @param {string} name
     * @param {Function} handler
     */
    removeEventListener(name2, handler) {
      const w = this.w;
      if (!Object.prototype.hasOwnProperty.call(w.globals.events, name2)) {
        return;
      }
      const index = (
        /** @type {Record<string,any>} */
        w.globals.events[name2].indexOf(handler)
      );
      if (index !== -1) {
        w.globals.events[name2].splice(
          index,
          1
        );
      }
    }
    /**
     * @param {string} name
     * @param {any[]} args
     */
    fireEvent(name2, args) {
      const w = this.w;
      if (!Object.prototype.hasOwnProperty.call(w.globals.events, name2)) {
        return;
      }
      if (!args || !args.length) {
        args = [];
      }
      const evs = (
        /** @type {Record<string,any>} */
        w.globals.events[name2]
      );
      const l = evs.length;
      for (let i = 0; i < l; i++) {
        evs[i].apply(null, args);
      }
    }
    setupEventHandlers() {
      const w = this.w;
      const me = this.ctx;
      const clickableArea = w.dom.baseEl.querySelector(w.globals.chartClass);
      this.ctx.eventList.forEach((event) => {
        clickableArea == null ? void 0 : clickableArea.addEventListener(
          event,
          (e) => {
            const capturedSeriesIndex = e.target.getAttribute("i") === null && w.interact.capturedSeriesIndex !== -1 ? w.interact.capturedSeriesIndex : e.target.getAttribute("i");
            const capturedDataPointIndex = e.target.getAttribute("j") === null && w.interact.capturedDataPointIndex !== -1 ? w.interact.capturedDataPointIndex : e.target.getAttribute("j");
            const opts = Object.assign({}, w, {
              seriesIndex: w.globals.axisCharts ? capturedSeriesIndex : 0,
              dataPointIndex: capturedDataPointIndex
            });
            if (e.type === "keydown") {
              if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
                if (me.ctx.keyboardNavigation) {
                  me.ctx.keyboardNavigation.handleKey(e);
                }
                if (typeof w.config.chart.events.keyDown === "function") {
                  w.config.chart.events.keyDown(e, me, opts);
                }
                me.ctx.events.fireEvent("keydown", [e, me, opts]);
              }
            } else if (e.type === "keyup") {
              if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
                if (typeof w.config.chart.events.keyUp === "function") {
                  w.config.chart.events.keyUp(e, me, opts);
                }
                me.ctx.events.fireEvent("keyup", [e, me, opts]);
              }
            } else if (e.type === "mousemove" || e.type === "touchmove") {
              if (typeof w.config.chart.events.mouseMove === "function") {
                w.config.chart.events.mouseMove(e, me, opts);
              }
            } else if (e.type === "mouseleave" || e.type === "touchleave") {
              if (typeof w.config.chart.events.mouseLeave === "function") {
                w.config.chart.events.mouseLeave(e, me, opts);
              }
            } else if (e.type === "mouseup" && e.which === 1 || e.type === "touchend") {
              if (typeof w.config.chart.events.click === "function") {
                w.config.chart.events.click(e, me, opts);
              }
              me.ctx.events.fireEvent("click", [e, me, opts]);
            }
          },
          { capture: false, passive: true }
        );
      });
      this.ctx.eventList.forEach((event) => {
        w.dom.baseEl.addEventListener(event, this.documentEvent, {
          passive: true
        });
      });
      this.ctx.core.setupBrushHandler();
    }
    /**
     * @param {any} e
     */
    documentEvent(e) {
      const w = this.w;
      const target = e.target.className;
      if (e.type === "click") {
        const elMenu = w.dom.baseEl.querySelector(".apexcharts-menu");
        if (elMenu && elMenu.classList.contains("apexcharts-menu-open") && target !== "apexcharts-menu-icon") {
          elMenu.classList.remove("apexcharts-menu-open");
        }
      }
      w.interact.clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
      w.interact.clientY = e.type === "touchmove" ? e.touches[0].clientY : e.clientY;
    }
  }
  class Localization {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
    }
    /**
     * @param {string} localeName
     */
    setCurrentLocaleValues(localeName) {
      let locales = this.w.config.chart.locales;
      const globalApex = Environment.getApex();
      if (globalApex.chart && globalApex.chart.locales && globalApex.chart.locales.length > 0) {
        locales = this.w.config.chart.locales.concat(globalApex.chart.locales);
      }
      const selectedLocale = locales.filter(
        (c) => c.name === localeName
      )[0];
      if (selectedLocale) {
        const ret = Utils$1.extend(en, selectedLocale);
        this.w.globals.locale = ret.options;
      } else {
        throw new Error(
          "Wrong locale name provided. Please make sure you set the correct locale name in options"
        );
      }
    }
  }
  class Axes {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
    }
    /**
     * @param {string} type
     * @param {any} elgrid
     */
    drawAxis(type, elgrid) {
      const gl = this.w.globals;
      const cnf = this.w.config;
      const xAxis = new XAxis(this.w, this.ctx, elgrid);
      const yAxis = new YAxis(this.w, { theme: this.ctx.theme, timeScale: this.ctx.timeScale }, elgrid);
      if (gl.axisCharts && type !== "radar") {
        let elXaxis, elYaxis;
        if (gl.isBarHorizontal) {
          elYaxis = yAxis.drawYaxisInversed(0);
          elXaxis = xAxis.drawXaxisInversed(0);
          this.w.dom.elGraphical.add(elXaxis);
          this.w.dom.elGraphical.add(elYaxis);
        } else {
          elXaxis = xAxis.drawXaxis();
          this.w.dom.elGraphical.add(elXaxis);
          cnf.yaxis.map((yaxe, index) => {
            if (gl.ignoreYAxisIndexes.indexOf(index) === -1) {
              elYaxis = yAxis.drawYaxis(index);
              this.w.dom.Paper.add(elYaxis);
              if (this.w.config.grid.position === "back") {
                const inner = this.w.dom.Paper.children()[1];
                if (inner) {
                  inner.remove();
                  this.w.dom.Paper.add(inner);
                }
              }
            }
          });
        }
      }
    }
  }
  class Crosshairs {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
    }
    drawXCrosshairs() {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const filters = new Filters(this.w);
      const crosshairGradient = w.config.xaxis.crosshairs.fill.gradient;
      const crosshairShadow = w.config.xaxis.crosshairs.dropShadow;
      const fillType = w.config.xaxis.crosshairs.fill.type;
      const gradientFrom = crosshairGradient.colorFrom;
      const gradientTo = crosshairGradient.colorTo;
      const opacityFrom = crosshairGradient.opacityFrom;
      const opacityTo = crosshairGradient.opacityTo;
      const stops = crosshairGradient.stops;
      const shadow = "none";
      const dropShadow = crosshairShadow.enabled;
      const shadowLeft = crosshairShadow.left;
      const shadowTop = crosshairShadow.top;
      const shadowBlur = crosshairShadow.blur;
      const shadowColor = crosshairShadow.color;
      const shadowOpacity = crosshairShadow.opacity;
      let xcrosshairsFill = w.config.xaxis.crosshairs.fill.color;
      if (w.config.xaxis.crosshairs.show) {
        if (fillType === "gradient") {
          xcrosshairsFill = graphics.drawGradient(
            "vertical",
            gradientFrom,
            gradientTo,
            opacityFrom,
            opacityTo,
            null,
            stops,
            []
          );
        }
        let xcrosshairs = graphics.drawRect();
        if (w.config.xaxis.crosshairs.width === 1) {
          xcrosshairs = graphics.drawLine(0, 0, 0, 0);
        }
        let gridHeight = w.layout.gridHeight;
        if (!Utils$1.isNumber(gridHeight) || gridHeight < 0) {
          gridHeight = 0;
        }
        let crosshairsWidth = w.config.xaxis.crosshairs.width;
        if (!Utils$1.isNumber(crosshairsWidth) || Number(crosshairsWidth) < 0) {
          crosshairsWidth = 0;
        }
        xcrosshairs.attr({
          class: "apexcharts-xcrosshairs",
          x: 0,
          y: 0,
          y2: gridHeight,
          width: crosshairsWidth,
          height: gridHeight,
          fill: xcrosshairsFill,
          filter: shadow,
          "fill-opacity": w.config.xaxis.crosshairs.opacity,
          stroke: w.config.xaxis.crosshairs.stroke.color,
          "stroke-width": w.config.xaxis.crosshairs.stroke.width,
          "stroke-dasharray": w.config.xaxis.crosshairs.stroke.dashArray
        });
        if (dropShadow) {
          xcrosshairs = filters.dropShadow(xcrosshairs, {
            left: shadowLeft,
            top: shadowTop,
            blur: shadowBlur,
            color: shadowColor,
            opacity: shadowOpacity
          });
        }
        w.dom.elGraphical.add(xcrosshairs);
      }
    }
    drawYCrosshairs() {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const crosshair = (
        /** @type {any[]} */
        w.config.yaxis[0].crosshairs
      );
      const offX = w.globals.barPadForNumericAxis;
      if (
        /** @type {any[]} */
        w.config.yaxis[0].crosshairs.show
      ) {
        const ycrosshairs = graphics.drawLine(
          -offX,
          0,
          w.layout.gridWidth + offX,
          0,
          crosshair.stroke.color,
          crosshair.stroke.dashArray,
          crosshair.stroke.width
        );
        ycrosshairs.attr({
          class: "apexcharts-ycrosshairs"
        });
        w.dom.elGraphical.add(ycrosshairs);
      }
      const ycrosshairsHidden = graphics.drawLine(
        -offX,
        0,
        w.layout.gridWidth + offX,
        0,
        crosshair.stroke.color,
        0,
        0
      );
      ycrosshairsHidden.attr({
        class: "apexcharts-ycrosshairs-hidden"
      });
      w.dom.elGraphical.add(ycrosshairsHidden);
    }
  }
  class Responsive {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this._activeBreakpoint = null;
    }
    // the opts parameter if not null has to be set overriding everything
    // as the opts is set by user externally
    /**
     * @param {object} opts
     */
    checkResponsiveConfig(opts) {
      const w = this.w;
      const cnf = w.config;
      if (cnf.responsive.length === 0) return;
      const res = cnf.responsive.slice();
      res.sort(
        (a, b) => a.breakpoint > b.breakpoint ? 1 : b.breakpoint > a.breakpoint ? -1 : 0
      ).reverse();
      const config = new Config({});
      const iterateResponsiveOptions = (newOptions = {}) => {
        const largestBreakpoint = res[0].breakpoint;
        const width = Environment.isBrowser() ? window.innerWidth > 0 ? window.innerWidth : screen.width : 0;
        if (width > largestBreakpoint) {
          if (this._activeBreakpoint !== null) {
            if (!w.globals.initialConfig) return;
            const initialConfig = Utils$1.clone(w.globals.initialConfig);
            initialConfig.series = Utils$1.clone(w.config.series);
            const options2 = CoreUtils.extendArrayProps(config, initialConfig, w);
            newOptions = Utils$1.extend(options2, newOptions);
            this.overrideResponsiveOptions(newOptions);
            this._activeBreakpoint = null;
          }
        } else {
          for (let i = 0; i < res.length; i++) {
            if (width < res[i].breakpoint) {
              newOptions = CoreUtils.extendArrayProps(config, res[i].options, w);
              newOptions = Utils$1.extend(w.config, newOptions);
              this.overrideResponsiveOptions(newOptions);
              this._activeBreakpoint = res[i].breakpoint;
            }
          }
        }
      };
      if (opts) {
        let options2 = CoreUtils.extendArrayProps(config, opts, w);
        options2 = Utils$1.extend(w.config, options2);
        options2 = Utils$1.extend(options2, opts);
        iterateResponsiveOptions(options2);
      } else {
        iterateResponsiveOptions({});
      }
    }
    /**
     * @param {Record<string, any>} newOptions
     */
    overrideResponsiveOptions(newOptions) {
      const newConfig = new Config(newOptions).init({ responsiveOverride: true });
      this.w.config = /** @type {any} */
      newConfig;
    }
  }
  class Series {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {{ toggleDataSeries?: Function, revertDefaultAxisMinMax?: Function, updateSeries?: Function }} [callbacks]
     */
    constructor(w, {
      toggleDataSeries = void 0,
      revertDefaultAxisMinMax = void 0,
      updateSeries = void 0
    } = {}) {
      this.w = w;
      this._toggleDataSeries = toggleDataSeries || null;
      this._revertDefaultAxisMinMax = revertDefaultAxisMinMax || null;
      this._updateSeries = updateSeries || null;
      this.legendInactiveClass = "legend-mouseover-inactive";
    }
    clearSeriesCache() {
      const w = this.w;
      if (w.globals.cachedSelectors) {
        delete w.globals.cachedSelectors.allSeriesEls;
        delete w.globals.cachedSelectors.highlightSeriesEls;
      }
    }
    getAllSeriesEls() {
      const w = this.w;
      const cacheKey = "allSeriesEls";
      if (!w.globals.cachedSelectors[cacheKey]) {
        w.globals.cachedSelectors[cacheKey] = /** @type {any} */
        w.dom.baseEl.getElementsByClassName(`apexcharts-series`);
      }
      return w.globals.cachedSelectors[cacheKey];
    }
    /**
     * @param {string} seriesName
     */
    getSeriesByName(seriesName) {
      return this.w.dom.baseEl.querySelector(
        `.apexcharts-inner .apexcharts-series[seriesName='${Utils$1.escapeString(
          seriesName
        )}']`
      );
    }
    /**
     * @param {string} seriesName
     */
    isSeriesHidden(seriesName) {
      var _a;
      const targetElement = this.getSeriesByName(seriesName);
      const el = (
        /** @type {Element} */
        targetElement
      );
      const realIndex = parseInt((_a = el.getAttribute("data:realIndex")) != null ? _a : "0", 10);
      const isHidden = el.classList.contains("apexcharts-series-collapsed");
      return { isHidden, realIndex };
    }
    /**
     * @param {any} elSeries
     * @param {number} index
     */
    addCollapsedClassToSeries(elSeries, index) {
      Series.addCollapsedClassToSeries(this.w, elSeries, index);
    }
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {any} elSeries
     * @param {number} index
     */
    static addCollapsedClassToSeries(w, elSeries, index) {
      function iterateOnAllCollapsedSeries(series) {
        for (let cs = 0; cs < series.length; cs++) {
          if (series[cs].index === index) {
            elSeries.node.classList.add("apexcharts-series-collapsed");
          }
        }
      }
      iterateOnAllCollapsedSeries(w.globals.collapsedSeries);
      iterateOnAllCollapsedSeries(w.globals.ancillaryCollapsedSeries);
    }
    /**
     * @param {string} seriesName
     */
    toggleSeries(seriesName) {
      var _a;
      const isSeriesHidden = this.isSeriesHidden(seriesName);
      (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, isSeriesHidden.isHidden);
      return isSeriesHidden.isHidden;
    }
    /**
     * @param {string} seriesName
     */
    showSeries(seriesName) {
      var _a;
      const isSeriesHidden = this.isSeriesHidden(seriesName);
      if (isSeriesHidden.isHidden) {
        (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, true);
      }
    }
    /**
     * @param {string} seriesName
     */
    hideSeries(seriesName) {
      var _a;
      const isSeriesHidden = this.isSeriesHidden(seriesName);
      if (!isSeriesHidden.isHidden) {
        (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, false);
      }
    }
    resetSeries(shouldUpdateChart = true, shouldResetZoom = true, shouldResetCollapsed = true) {
      var _a, _b;
      const w = this.w;
      this.clearSeriesCache();
      let series = Utils$1.clone(w.globals.initialSeries);
      w.globals.previousPaths = [];
      if (shouldResetCollapsed) {
        w.globals.collapsedSeries = [];
        w.globals.ancillaryCollapsedSeries = [];
        w.globals.collapsedSeriesIndices = [];
        w.globals.ancillaryCollapsedSeriesIndices = [];
      } else {
        series = this.emptyCollapsedSeries(series);
      }
      w.config.series = series;
      if (shouldUpdateChart) {
        if (shouldResetZoom) {
          w.interact.zoomed = false;
          (_a = this._revertDefaultAxisMinMax) == null ? void 0 : _a.call(this);
        }
        (_b = this._updateSeries) == null ? void 0 : _b.call(
          this,
          series,
          w.config.chart.animations.dynamicAnimation.enabled
        );
      }
    }
    /**
     * @param {any[]} series
     */
    emptyCollapsedSeries(series) {
      const w = this.w;
      for (let i = 0; i < series.length; i++) {
        if (w.globals.collapsedSeriesIndices.indexOf(i) > -1) {
          series[i].data = [];
        }
      }
      return series;
    }
    /**
     * @param {string} seriesName
     */
    highlightSeries(seriesName) {
      var _a;
      const w = this.w;
      const targetElement = this.getSeriesByName(seriesName);
      const realIndex = parseInt(
        (_a = targetElement == null ? void 0 : targetElement.getAttribute("data:realIndex")) != null ? _a : "",
        10
      );
      const cacheKey = "highlightSeriesEls";
      let allSeriesEls = w.globals.cachedSelectors[cacheKey];
      if (!allSeriesEls) {
        allSeriesEls = w.dom.baseEl.querySelectorAll(
          `.apexcharts-series, .apexcharts-datalabels, .apexcharts-yaxis`
        );
        w.globals.cachedSelectors[cacheKey] = allSeriesEls;
      }
      let seriesEl = null;
      let dataLabelEl = null;
      let yaxisEl = null;
      if (w.globals.axisCharts || w.config.chart.type === "radialBar") {
        if (w.globals.axisCharts) {
          seriesEl = w.dom.baseEl.querySelector(
            `.apexcharts-series[data\\:realIndex='${realIndex}']`
          );
          dataLabelEl = w.dom.baseEl.querySelector(
            `.apexcharts-datalabels[data\\:realIndex='${realIndex}']`
          );
          const yaxisIndex = w.globals.seriesYAxisReverseMap[realIndex];
          yaxisEl = w.dom.baseEl.querySelector(
            `.apexcharts-yaxis[rel='${yaxisIndex}']`
          );
        } else {
          seriesEl = w.dom.baseEl.querySelector(
            `.apexcharts-series[rel='${realIndex + 1}']`
          );
        }
      } else {
        seriesEl = w.dom.baseEl.querySelector(
          `.apexcharts-series[rel='${realIndex + 1}'] path`
        );
      }
      for (let se = 0; se < allSeriesEls.length; se++) {
        const serEl = (
          /** @type {Element} */
          allSeriesEls[se]
        );
        serEl.classList.add(this.legendInactiveClass);
      }
      if (seriesEl) {
        if (!w.globals.axisCharts) {
          const parentEl = (
            /** @type {Element} */
            seriesEl.parentNode
          );
          parentEl == null ? void 0 : parentEl.classList.remove(this.legendInactiveClass);
        }
        seriesEl.classList.remove(this.legendInactiveClass);
        if (dataLabelEl !== null) {
          dataLabelEl.classList.remove(this.legendInactiveClass);
        }
        if (yaxisEl !== null) {
          yaxisEl.classList.remove(this.legendInactiveClass);
        }
      } else {
        for (let se = 0; se < allSeriesEls.length; se++) {
          const serEl = (
            /** @type {Element} */
            allSeriesEls[se]
          );
          serEl.classList.remove(this.legendInactiveClass);
        }
      }
    }
    /**
     * @param {Event} e
     * @param {any} targetElement
     */
    toggleSeriesOnHover(e, targetElement) {
      const w = this.w;
      if (!targetElement) targetElement = e.target;
      const allSeriesEls = w.dom.baseEl.querySelectorAll(
        `.apexcharts-series, .apexcharts-datalabels, .apexcharts-yaxis`
      );
      if (e.type === "mousemove") {
        const realIndex = parseInt(targetElement.getAttribute("rel"), 10) - 1;
        this.highlightSeries(w.seriesData.seriesNames[realIndex]);
      } else if (e.type === "mouseout") {
        for (let se = 0; se < allSeriesEls.length; se++) {
          allSeriesEls[se].classList.remove(this.legendInactiveClass);
        }
      }
    }
    /**
     * @param {Event} e
     * @param {any} targetElement
     */
    highlightRangeInSeries(e, targetElement) {
      const w = this.w;
      const allHeatMapElements = w.dom.baseEl.getElementsByClassName(
        "apexcharts-heatmap-rect"
      );
      const activeInactive = (action) => {
        for (let i = 0; i < allHeatMapElements.length; i++) {
          const actionFn = (
            /** @type {any} */
            allHeatMapElements[i].classList[action]
          );
          if (typeof actionFn === "function") {
            actionFn.call(
              /** @type {any} */
              allHeatMapElements[i].classList,
              this.legendInactiveClass
            );
          }
        }
      };
      const removeInactiveClassFromHoveredRange = (range, rangeMax) => {
        for (let i = 0; i < allHeatMapElements.length; i++) {
          const val = Number(allHeatMapElements[i].getAttribute("val"));
          if (val >= range.from && (val < range.to || range.to === rangeMax && val === rangeMax)) {
            allHeatMapElements[i].classList.remove(this.legendInactiveClass);
          }
        }
      };
      if (e.type === "mousemove") {
        const seriesCnt = parseInt(targetElement.getAttribute("rel"), 10) - 1;
        activeInactive("add");
        const ranges = w.config.plotOptions.heatmap.colorScale.ranges;
        const range = ranges[seriesCnt];
        const rangeMax = ranges.reduce(
          (acc, cur) => Math.max(acc, cur.to),
          0
        );
        removeInactiveClassFromHoveredRange(range, rangeMax);
      } else if (e.type === "mouseout") {
        activeInactive("remove");
      }
    }
    /**
     * @param {string[]} chartTypes
     */
    getActiveConfigSeriesIndex(order = "asc", chartTypes = []) {
      const w = this.w;
      let activeIndex = 0;
      if (w.config.series.length > 1) {
        const activeSeriesIndex = w.config.series.map((s, index) => {
          const checkChartType = () => {
            if (w.globals.comboCharts) {
              return chartTypes.length === 0 || chartTypes.length && chartTypes.indexOf(
                /** @type {Record<string,any>} */
                w.config.series[index].type
              ) > -1;
            }
            return true;
          };
          const hasData = (
            /** @type {any} */
            s.data && /** @type {any} */
            s.data.length > 0 && w.globals.collapsedSeriesIndices.indexOf(index) === -1
          );
          return hasData && checkChartType() ? index : -1;
        });
        for (let a = order === "asc" ? 0 : activeSeriesIndex.length - 1; order === "asc" ? a < activeSeriesIndex.length : a >= 0; order === "asc" ? a++ : a--) {
          if (activeSeriesIndex[a] !== -1) {
            activeIndex = activeSeriesIndex[a];
            break;
          }
        }
      }
      return activeIndex;
    }
    getBarSeriesIndices() {
      const w = this.w;
      if (w.globals.comboCharts) {
        return this.w.config.series.map((s, i) => {
          return s.type === "bar" || s.type === "column" ? i : -1;
        }).filter((i) => {
          return i !== -1;
        });
      }
      return this.w.config.series.map((s, i) => {
        return i;
      });
    }
    getPreviousPaths() {
      var _a, _b, _c, _d;
      const w = this.w;
      w.globals.previousPaths = [];
      function pushPaths(seriesEls, i, type) {
        const paths = seriesEls[i].childNodes;
        const dArr = {
          type,
          paths: (
            /** @type {any[]} */
            []
          ),
          realIndex: seriesEls[i].getAttribute("data:realIndex")
        };
        for (let j = 0; j < paths.length; j++) {
          if (paths[j].hasAttribute("pathTo")) {
            const d = paths[j].getAttribute("pathTo");
            dArr.paths.push({ d });
          }
        }
        w.globals.previousPaths.push(dArr);
      }
      const getPaths = (chartType) => {
        return w.dom.baseEl.querySelectorAll(
          `.apexcharts-${chartType}-series .apexcharts-series`
        );
      };
      const chartTypes = [
        "line",
        "area",
        "bar",
        "rangebar",
        "rangeArea",
        "candlestick",
        "radar"
      ];
      chartTypes.forEach((type) => {
        const paths = getPaths(type);
        for (let p = 0; p < paths.length; p++) {
          pushPaths(paths, p, type);
        }
      });
      const heatTreeSeries = w.dom.baseEl.querySelectorAll(
        `.apexcharts-${w.config.chart.type} .apexcharts-series`
      );
      if (heatTreeSeries.length > 0) {
        for (let h = 0; h < heatTreeSeries.length; h++) {
          const seriesEls = w.dom.baseEl.querySelectorAll(
            `.apexcharts-${w.config.chart.type} .apexcharts-series[data\\:realIndex='${h}'] rect`
          );
          const dArr = [];
          for (let i = 0; i < seriesEls.length; i++) {
            const getAttr = (x) => {
              return (
                /** @type {Element} */
                seriesEls[i].getAttribute(x)
              );
            };
            const rect = {
              x: parseFloat((_a = getAttr("x")) != null ? _a : "0"),
              y: parseFloat((_b = getAttr("y")) != null ? _b : "0"),
              width: parseFloat((_c = getAttr("width")) != null ? _c : "0"),
              height: parseFloat((_d = getAttr("height")) != null ? _d : "0")
            };
            dArr.push({
              rect,
              color: seriesEls[i].getAttribute("color")
            });
          }
          w.globals.previousPaths.push(dArr);
        }
      }
      if (!w.globals.axisCharts) {
        w.globals.previousPaths = w.seriesData.series;
      }
    }
    clearPreviousPaths() {
      const w = this.w;
      w.globals.previousPaths = [];
      w.globals.allSeriesCollapsed = false;
    }
    handleNoData() {
      const w = this.w;
      const me = this;
      const noDataOpts = w.config.noData;
      const graphics = new Graphics(me.w);
      let x = w.globals.svgWidth / 2;
      let y = w.globals.svgHeight / 2;
      let textAnchor = "middle";
      w.globals.noData = true;
      w.globals.animationEnded = true;
      if (noDataOpts.align === "left") {
        x = 10;
        textAnchor = "start";
      } else if (noDataOpts.align === "right") {
        x = w.globals.svgWidth - 10;
        textAnchor = "end";
      }
      if (noDataOpts.verticalAlign === "top") {
        y = 50;
      } else if (noDataOpts.verticalAlign === "bottom") {
        y = w.globals.svgHeight - 50;
      }
      x = x + noDataOpts.offsetX;
      y = y + parseInt(noDataOpts.style.fontSize, 10) + 2 + noDataOpts.offsetY;
      if (noDataOpts.text !== void 0 && noDataOpts.text !== "") {
        const titleText = graphics.drawText({
          x,
          y,
          text: noDataOpts.text,
          textAnchor,
          fontSize: noDataOpts.style.fontSize,
          fontFamily: noDataOpts.style.fontFamily,
          foreColor: noDataOpts.style.color,
          opacity: 1,
          cssClass: "apexcharts-text-nodata"
        });
        w.dom.Paper.add(titleText);
      }
    }
    // When user clicks on legends, the collapsed series is filled with [0,0,0,...,0]
    // This is because we don't want to alter the series' length as it is used at many places
    /**
     * @param {any[]} series
     */
    setNullSeriesToZeroValues(series) {
      const w = this.w;
      for (let sl = 0; sl < series.length; sl++) {
        if (series[sl].length === 0) {
          for (let j = 0; j < series[w.globals.maxValsInArrayIndex].length; j++) {
            series[sl].push(0);
          }
        }
      }
      return series;
    }
    hasAllSeriesEqualX() {
      let equalLen = true;
      const w = this.w;
      const filteredSerX = this.filteredSeriesX();
      for (let i = 0; i < filteredSerX.length - 1; i++) {
        if (filteredSerX[i][0] !== filteredSerX[i + 1][0]) {
          equalLen = false;
          break;
        }
      }
      w.globals.allSeriesHasEqualX = equalLen;
      return equalLen;
    }
    filteredSeriesX() {
      const w = this.w;
      const filteredSeriesX = w.seriesData.seriesX.map(
        (ser) => ser.length > 0 ? ser : []
      );
      return filteredSeriesX;
    }
  }
  class Theme {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
      this.colors = [];
      this.isColorFn = false;
      this.isHeatmapDistributed = this.checkHeatmapDistributed();
      this.isBarDistributed = this.checkBarDistributed();
    }
    checkHeatmapDistributed() {
      const { chart, plotOptions } = this.w.config;
      return chart.type === "treemap" && plotOptions.treemap && plotOptions.treemap.distributed || chart.type === "heatmap" && plotOptions.heatmap && plotOptions.heatmap.distributed;
    }
    checkBarDistributed() {
      const { chart, plotOptions } = this.w.config;
      return plotOptions.bar && plotOptions.bar.distributed && (chart.type === "bar" || chart.type === "rangeBar");
    }
    init() {
      this.setDefaultColors();
    }
    setDefaultColors() {
      var _a;
      const w = this.w;
      const utils = new Utils$1();
      w.dom.elWrap.classList.add(
        `apexcharts-theme-${w.config.theme.mode || "light"}`
      );
      const colorBlindMode = (_a = w.config.theme.accessibility) == null ? void 0 : _a.colorBlindMode;
      if (colorBlindMode) {
        w.globals.colors = this.getColorBlindColors(colorBlindMode);
        this.applySeriesColors(w.seriesData.seriesColors, w.globals.colors);
        const defaultColors2 = w.globals.colors.slice();
        this.pushExtraColors(w.globals.colors);
        this.applyColorTypes(["fill", "stroke"], defaultColors2);
        this.applyDataLabelsColors(defaultColors2);
        this.applyRadarPolygonsColors();
        this.applyMarkersColors(defaultColors2);
        if (colorBlindMode === "highContrast") {
          w.dom.elWrap.classList.add("apexcharts-high-contrast");
        }
        return;
      }
      const configColors = [...w.config.colors || w.config.fill.colors || []];
      w.globals.colors = this.getColors(configColors);
      this.applySeriesColors(w.seriesData.seriesColors, w.globals.colors);
      if (w.config.theme.monochrome.enabled) {
        w.globals.colors = this.getMonochromeColors(
          w.config.theme.monochrome,
          w.seriesData.series,
          utils
        );
      }
      const defaultColors = w.globals.colors.slice();
      this.pushExtraColors(w.globals.colors);
      this.applyColorTypes(["fill", "stroke"], defaultColors);
      this.applyDataLabelsColors(defaultColors);
      this.applyRadarPolygonsColors();
      this.applyMarkersColors(defaultColors);
    }
    /**
     * @param {any[]} configColors
     */
    getColors(configColors) {
      const w = this.w;
      if (!configColors || configColors.length === 0) {
        return this.predefined();
      }
      if (Array.isArray(configColors) && configColors.length > 0 && typeof configColors[0] === "function") {
        this.isColorFn = true;
        return w.config.series.map((s, i) => {
          const c = configColors[i] || configColors[0];
          return typeof c === "function" ? c({
            value: w.globals.axisCharts ? w.seriesData.series[i][0] || 0 : w.seriesData.series[i],
            seriesIndex: i,
            dataPointIndex: i,
            w: this.w
          }) : c;
        });
      }
      return configColors;
    }
    /**
     * @param {any[]} seriesColors
     * @param {any[]} globalsColors
     */
    applySeriesColors(seriesColors, globalsColors) {
      seriesColors.forEach((c, i) => {
        if (c) {
          globalsColors[i] = c;
        }
      });
    }
    /**
     * @param {Record<string, any>} monochrome
     * @param {any[]} series
     * @param {any} utils
     */
    getMonochromeColors(monochrome, series, utils) {
      const { color, shadeIntensity, shadeTo } = monochrome;
      const glsCnt = this.isBarDistributed || this.isHeatmapDistributed ? series[0].length * series.length : series.length;
      const part = 1 / (glsCnt / shadeIntensity);
      let percent = 0;
      return Array.from({ length: glsCnt }, () => {
        const newColor = shadeTo === "dark" ? utils.shadeColor(percent * -1, color) : utils.shadeColor(percent, color);
        percent += part;
        return newColor;
      });
    }
    /**
     * @param {string[]} colorTypes
     * @param {string[]} defaultColors
     */
    applyColorTypes(colorTypes, defaultColors) {
      const w = this.w;
      colorTypes.forEach((c) => {
        w.globals[c].colors = w.config[c].colors === void 0 ? this.isColorFn ? w.config.colors : defaultColors : w.config[c].colors.slice();
        this.pushExtraColors(
          /** @type {Record<string,any>} */
          w.globals[c].colors
        );
      });
    }
    /**
     * @param {string[]} defaultColors
     */
    applyDataLabelsColors(defaultColors) {
      const w = this.w;
      w.globals.dataLabels.style.colors = w.config.dataLabels.style.colors === void 0 ? defaultColors : w.config.dataLabels.style.colors.slice();
      this.pushExtraColors(w.globals.dataLabels.style.colors, 50);
    }
    applyRadarPolygonsColors() {
      const w = this.w;
      w.globals.radarPolygons.fill.colors = w.config.plotOptions.radar.polygons.fill.colors === void 0 ? [w.config.theme.mode === "dark" ? "#343A3F" : "none"] : w.config.plotOptions.radar.polygons.fill.colors.slice();
      this.pushExtraColors(w.globals.radarPolygons.fill.colors, 20);
    }
    /**
     * @param {string[]} defaultColors
     */
    applyMarkersColors(defaultColors) {
      const w = this.w;
      w.globals.markers.colors = w.config.markers.colors === void 0 ? defaultColors : w.config.markers.colors.slice();
      this.pushExtraColors(w.globals.markers.colors);
    }
    /**
     * @param {any} colorSeries
     * @param {number} [length]
     * @param {boolean | null} [distributed]
     */
    pushExtraColors(colorSeries, length, distributed = null) {
      const w = this.w;
      let len = length || w.seriesData.series.length;
      if (distributed === null) {
        distributed = this.isBarDistributed || this.isHeatmapDistributed || w.config.chart.type === "heatmap" && w.config.plotOptions.heatmap && w.config.plotOptions.heatmap.colorScale.inverse;
      }
      if (distributed && w.seriesData.series.length) {
        len = w.seriesData.series[w.globals.maxValsInArrayIndex].length * w.seriesData.series.length;
      }
      if (colorSeries.length < len) {
        const diff = len - colorSeries.length;
        for (let i = 0; i < diff; i++) {
          colorSeries.push(colorSeries[i]);
        }
      }
    }
    /**
     * @param {'light' | 'dark'} mode
     */
    getColorBlindColors(mode) {
      const palettes = getThemePalettes();
      const map = {
        deuteranopia: palettes.cvdDeuteranopia,
        protanopia: palettes.cvdProtanopia,
        tritanopia: palettes.cvdTritanopia,
        highContrast: palettes.highContrast
      };
      return (
        /** @type {Record<string,any>} */
        /** @type {any} */
        (map[mode] || palettes.palette1).slice()
      );
    }
    /**
     * @param {Record<string, any>} options
     */
    updateThemeOptions(options2) {
      options2.chart = options2.chart || {};
      options2.tooltip = options2.tooltip || {};
      const mode = options2.theme.mode;
      const palette = mode === "dark" ? "palette4" : mode === "light" ? "palette1" : options2.theme.palette || "palette1";
      const foreColor = mode === "dark" ? "#f6f7f8" : mode === "light" ? "#373d3f" : options2.chart.foreColor || "#373d3f";
      options2.tooltip.theme = mode || "light";
      options2.chart.foreColor = foreColor;
      options2.theme.palette = palette;
      return options2;
    }
    predefined() {
      const palette = this.w.config.theme.palette;
      const palettes = getThemePalettes();
      return (
        /** @type {Record<string,any>} */
        palettes[palette] || palettes.palette1
      );
    }
  }
  class TitleSubtitle {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
    }
    draw() {
      this.drawTitleSubtitle("title");
      this.drawTitleSubtitle("subtitle");
    }
    /**
     * @param {'title' | 'subtitle'} type
     */
    drawTitleSubtitle(type) {
      const w = this.w;
      const tsConfig = type === "title" ? w.config.title : w.config.subtitle;
      let x = w.globals.svgWidth / 2;
      let y = tsConfig.offsetY;
      let textAnchor = "middle";
      if (tsConfig.align === "left") {
        x = 10;
        textAnchor = "start";
      } else if (tsConfig.align === "right") {
        x = w.globals.svgWidth - 10;
        textAnchor = "end";
      }
      x = x + tsConfig.offsetX;
      y = y + parseInt(tsConfig.style.fontSize, 10) + tsConfig.margin / 2;
      if (tsConfig.text !== void 0) {
        const graphics = new Graphics(this.w);
        const titleText = graphics.drawText({
          x,
          y,
          text: tsConfig.text,
          textAnchor,
          fontSize: tsConfig.style.fontSize,
          fontFamily: tsConfig.style.fontFamily,
          fontWeight: tsConfig.style.fontWeight,
          foreColor: tsConfig.style.color,
          opacity: 1
        });
        titleText.node.setAttribute("class", `apexcharts-${type}-text`);
        w.dom.Paper.add(titleText);
      }
    }
  }
  let Helpers$4 = class Helpers {
    /**
     * @param {import('./Dimensions').default} dCtx
     */
    constructor(dCtx) {
      this.w = dCtx.w;
      this.dCtx = dCtx;
    }
    /**
     * Get Chart Title/Subtitle Dimensions
     * @memberof Dimensions
     * @return {{width: number, height: number}}
     * @param {string} type
     **/
    getTitleSubtitleCoords(type) {
      const w = this.w;
      let width = 0;
      let height = 0;
      const floating = type === "title" ? w.config.title.floating : w.config.subtitle.floating;
      const el = w.dom.baseEl.querySelector(`.apexcharts-${type}-text`);
      if (el !== null && !floating) {
        const coord = el.getBoundingClientRect();
        width = coord.width;
        height = w.globals.axisCharts ? coord.height + 5 : coord.height;
      }
      return {
        width,
        height
      };
    }
    getLegendsRect() {
      const w = this.w;
      const elLegendWrap = w.dom.elLegendWrap;
      if (!w.config.legend.height && (w.config.legend.position === "top" || w.config.legend.position === "bottom")) {
        if (elLegendWrap)
          elLegendWrap.style.maxHeight = w.globals.svgHeight / 2 + "px";
      }
      const lgRect = (
        /** @type {any} */
        Object.assign({}, Utils$1.getBoundingClientRect(elLegendWrap))
      );
      if (elLegendWrap !== null && !w.config.legend.floating && w.config.legend.show) {
        this.dCtx.lgRect = {
          x: lgRect.x,
          y: lgRect.y,
          height: lgRect.height,
          width: lgRect.height === 0 ? 0 : lgRect.width
        };
      } else {
        this.dCtx.lgRect = {
          x: 0,
          y: 0,
          height: 0,
          width: 0
        };
      }
      if (w.config.legend.position === "left" || w.config.legend.position === "right") {
        if (this.dCtx.lgRect.width * 1.5 > w.globals.svgWidth) {
          this.dCtx.lgRect.width = w.globals.svgWidth / 1.5;
        }
      }
      return this.dCtx.lgRect;
    }
    /**
     * Get Y Axis Dimensions
     * @memberof Dimensions
     * @return {{width: number, height: number}}
     **/
    getDatalabelsRect() {
      const w = this.w;
      const allLabels = [];
      w.config.series.forEach(
        (serie, seriesIndex) => {
          serie.data.forEach(
            (datum, dataPointIndex) => {
              const getText = (v) => {
                return w.config.dataLabels.formatter(v, {
                  seriesIndex,
                  dataPointIndex,
                  w
                });
              };
              const labelText = getText(
                w.seriesData.series[seriesIndex][dataPointIndex]
              );
              allLabels.push(labelText);
            }
          );
        }
      );
      const val = Utils$1.getLargestStringFromArr(allLabels);
      const graphics = new Graphics(this.w);
      const dataLabelsStyle = w.config.dataLabels.style;
      const labelrect = graphics.getTextRects(
        val,
        parseInt(dataLabelsStyle.fontSize).toString(),
        dataLabelsStyle.fontFamily
      );
      return {
        width: labelrect.width * 1.05,
        height: labelrect.height
      };
    }
    /**
     * @param {any} val
     * @param {any[]} arr
     */
    getLargestStringFromMultiArr(val, arr) {
      const w = this.w;
      let valArr = val;
      if (w.axisFlags.isMultiLineX) {
        const maxArrs = arr.map((xl) => {
          return Array.isArray(xl) ? xl.length : 1;
        });
        const maxArrLen = Math.max(...maxArrs);
        const maxArrIndex = maxArrs.indexOf(maxArrLen);
        valArr = arr[maxArrIndex];
      }
      return valArr;
    }
  };
  class DimXAxis {
    /**
     * @param {import('./Dimensions').default} dCtx
     */
    constructor(dCtx) {
      this.w = dCtx.w;
      this.dCtx = dCtx;
    }
    /**
     * Get X Axis Dimensions
     * @memberof Dimensions
     * @return {{width: number, height: number}}
     **/
    getxAxisLabelsCoords() {
      const w = this.w;
      let xaxisLabels = w.labelData.labels.slice();
      if (w.config.xaxis.convertedCatToNumeric && xaxisLabels.length === 0) {
        xaxisLabels = w.labelData.categoryLabels;
      }
      let rect;
      if (w.labelData.timescaleLabels.length > 0) {
        const coords = this.getxAxisTimeScaleLabelsCoords();
        rect = {
          width: coords.width,
          height: coords.height
        };
        w.layout.rotateXLabels = false;
      } else {
        this.dCtx.lgWidthForSideLegends = (w.config.legend.position === "left" || w.config.legend.position === "right") && !w.config.legend.floating ? this.dCtx.lgRect.width : 0;
        const xlbFormatter = w.formatters.xLabelFormatter;
        let val = Utils$1.getLargestStringFromArr(xaxisLabels);
        let valArr = this.dCtx.dimHelpers.getLargestStringFromMultiArr(
          val,
          xaxisLabels
        );
        if (w.globals.isBarHorizontal) {
          val = w.globals.yAxisScale[0].result.reduce(
            (a, b) => a.length > b.length ? a : b,
            0
          );
          valArr = val;
        }
        const xFormat = new Formatters(this.w);
        const timestamp = val;
        val = xFormat.xLabelFormat(
          /** @type {Function} */
          xlbFormatter,
          val,
          timestamp,
          {
            i: void 0,
            dateFormatter: new DateTime(this.w).formatDate,
            w
          }
        );
        valArr = xFormat.xLabelFormat(
          /** @type {Function} */
          xlbFormatter,
          valArr,
          timestamp,
          {
            i: void 0,
            dateFormatter: new DateTime(this.w).formatDate,
            w
          }
        );
        if (w.config.xaxis.convertedCatToNumeric && typeof val === "undefined" || String(val).trim() === "") {
          val = "1";
          valArr = val;
        }
        const graphics = new Graphics(this.w);
        let xLabelrect = graphics.getTextRects(
          val,
          w.config.xaxis.labels.style.fontSize
        );
        let xArrLabelrect = xLabelrect;
        if (val !== valArr) {
          xArrLabelrect = graphics.getTextRects(
            valArr,
            w.config.xaxis.labels.style.fontSize
          );
        }
        rect = {
          width: xLabelrect.width >= xArrLabelrect.width ? xLabelrect.width : xArrLabelrect.width,
          height: xLabelrect.height >= xArrLabelrect.height ? xLabelrect.height : xArrLabelrect.height
        };
        if (rect.width * xaxisLabels.length > w.globals.svgWidth - this.dCtx.lgWidthForSideLegends - this.dCtx.yAxisWidth - this.dCtx.gridPad.left - this.dCtx.gridPad.right && w.config.xaxis.labels.rotate !== 0 || w.config.xaxis.labels.rotateAlways) {
          if (!w.globals.isBarHorizontal) {
            w.layout.rotateXLabels = true;
            const getRotatedTextRects = (text) => {
              return graphics.getTextRects(
                text,
                w.config.xaxis.labels.style.fontSize,
                w.config.xaxis.labels.style.fontFamily,
                `rotate(${w.config.xaxis.labels.rotate} 0 0)`,
                false
              );
            };
            xLabelrect = getRotatedTextRects(val);
            if (val !== valArr) {
              xArrLabelrect = getRotatedTextRects(valArr);
            }
            rect.height = (xLabelrect.height > xArrLabelrect.height ? xLabelrect.height : xArrLabelrect.height) / 1.5;
            rect.width = xLabelrect.width > xArrLabelrect.width ? xLabelrect.width : xArrLabelrect.width;
          }
        } else {
          w.layout.rotateXLabels = false;
        }
      }
      if (!w.config.xaxis.labels.show) {
        rect = {
          width: 0,
          height: 0
        };
      }
      return {
        width: rect.width,
        height: rect.height
      };
    }
    /**
     * Get X Axis Label Group height
     * @memberof Dimensions
     * @return {{width: number, height: number}}
     */
    getxAxisGroupLabelsCoords() {
      var _a;
      const w = this.w;
      if (!w.labelData.hasXaxisGroups) {
        return { width: 0, height: 0 };
      }
      const fontSize = ((_a = w.config.xaxis.group.style) == null ? void 0 : _a.fontSize) || w.config.xaxis.labels.style.fontSize;
      const xaxisLabels = w.labelData.groups.map(
        (g) => g.title
      );
      let rect;
      const val = Utils$1.getLargestStringFromArr(xaxisLabels);
      const valArr = this.dCtx.dimHelpers.getLargestStringFromMultiArr(
        val,
        xaxisLabels
      );
      const graphics = new Graphics(this.w);
      const xLabelrect = graphics.getTextRects(val, fontSize);
      let xArrLabelrect = xLabelrect;
      if (val !== valArr) {
        xArrLabelrect = graphics.getTextRects(valArr, fontSize);
      }
      rect = {
        width: xLabelrect.width >= xArrLabelrect.width ? xLabelrect.width : xArrLabelrect.width,
        height: xLabelrect.height >= xArrLabelrect.height ? xLabelrect.height : xArrLabelrect.height
      };
      if (!w.config.xaxis.labels.show) {
        rect = {
          width: 0,
          height: 0
        };
      }
      return {
        width: rect.width,
        height: rect.height
      };
    }
    /**
     * Get X Axis Title Dimensions
     * @memberof Dimensions
     * @return {{width: number, height: number}}
     **/
    getxAxisTitleCoords() {
      const w = this.w;
      let width = 0;
      let height = 0;
      if (w.config.xaxis.title.text !== void 0) {
        const graphics = new Graphics(this.w);
        const rect = graphics.getTextRects(
          w.config.xaxis.title.text,
          w.config.xaxis.title.style.fontSize
        );
        width = rect.width;
        height = rect.height;
      }
      return {
        width,
        height
      };
    }
    getxAxisTimeScaleLabelsCoords() {
      const w = this.w;
      this.dCtx.timescaleLabels = w.labelData.timescaleLabels.slice();
      const labels = this.dCtx.timescaleLabels.map(
        (label) => label.value
      );
      const val = labels.reduce((a, b) => {
        if (typeof a === "undefined") {
          console.error(
            "You have possibly supplied invalid Date format. Please supply a valid JavaScript Date"
          );
          return 0;
        } else {
          return a.length > b.length ? a : b;
        }
      }, 0);
      const graphics = new Graphics(this.w);
      const rect = graphics.getTextRects(
        val,
        w.config.xaxis.labels.style.fontSize
      );
      const totalWidthRotated = rect.width * 1.05 * labels.length;
      if (totalWidthRotated > w.layout.gridWidth && w.config.xaxis.labels.rotate !== 0) {
        w.globals.overlappingXLabels = true;
      }
      return rect;
    }
    // In certain cases, the last labels gets cropped in xaxis.
    // Hence, we add some additional padding based on the label length to avoid the last label being cropped or we don't draw it at all
    /**
     * @param {Record<string, any>} xaxisLabelCoords
     */
    additionalPaddingXLabels(xaxisLabelCoords) {
      const w = this.w;
      const gl = w.globals;
      const cnf = w.config;
      const xtype = cnf.xaxis.type;
      const lbWidth = xaxisLabelCoords.width;
      gl.skipLastTimelinelabel = false;
      gl.skipFirstTimelinelabel = false;
      const isBarOpposite = w.config.yaxis[0].opposite && w.globals.isBarHorizontal;
      const isCollapsed = (i) => gl.collapsedSeriesIndices.indexOf(i) !== -1;
      const rightPad = (yaxe) => {
        if (this.dCtx.timescaleLabels && this.dCtx.timescaleLabels.length) {
          const firstimescaleLabel = this.dCtx.timescaleLabels[0];
          const lastTimescaleLabel = this.dCtx.timescaleLabels[this.dCtx.timescaleLabels.length - 1];
          const lastLabelPosition = lastTimescaleLabel.position + lbWidth / 1.75 - this.dCtx.yAxisWidthRight;
          const firstLabelPosition = firstimescaleLabel.position - lbWidth / 1.75 + this.dCtx.yAxisWidthLeft;
          const lgRightRectWidth = w.config.legend.position === "right" && this.dCtx.lgRect.width > 0 ? this.dCtx.lgRect.width : 0;
          if (lastLabelPosition > gl.svgWidth - w.layout.translateX - lgRightRectWidth) {
            gl.skipLastTimelinelabel = true;
          }
          if (firstLabelPosition < -((!yaxe.show || yaxe.floating) && (cnf.chart.type === "bar" || cnf.chart.type === "candlestick" || cnf.chart.type === "rangeBar" || cnf.chart.type === "boxPlot") ? lbWidth / 1.75 : 10)) {
            gl.skipFirstTimelinelabel = true;
          }
        } else if (xtype === "datetime") {
          if (this.dCtx.gridPad.right < lbWidth && !w.layout.rotateXLabels) {
            gl.skipLastTimelinelabel = true;
          }
        } else if (xtype !== "datetime") {
          if (this.dCtx.gridPad.right < lbWidth / 2 - this.dCtx.yAxisWidthRight && !w.layout.rotateXLabels && !w.config.xaxis.labels.trim) {
            this.dCtx.xPadRight = lbWidth / 2 + 1;
          }
        }
      };
      const padYAxe = (yaxe, i) => {
        if (cnf.yaxis.length > 1 && isCollapsed(i)) return;
        rightPad(yaxe);
      };
      cnf.yaxis.forEach((yaxe, i) => {
        if (isBarOpposite) {
          if (this.dCtx.gridPad.left < lbWidth) {
            this.dCtx.xPadLeft = lbWidth / 2 + 1;
          }
          this.dCtx.xPadRight = lbWidth / 2 + 1;
        } else {
          padYAxe(yaxe, i);
        }
      });
    }
  }
  class DimYAxis {
    /**
     * @param {import('./Dimensions').default} dCtx
     */
    constructor(dCtx) {
      this.w = dCtx.w;
      this.dCtx = dCtx;
    }
    /**
     * Get Y Axis Dimensions
     * @memberof Dimensions
     * @returns {Array<{width: number, height: number}>}
     **/
    getyAxisLabelsCoords() {
      const w = this.w;
      const width = 0;
      const height = 0;
      const ret = [];
      let labelPad = 10;
      const axesUtils = new AxesUtils(this.w, { theme: this.dCtx.theme, timeScale: this.dCtx.timeScale });
      w.config.yaxis.map((yaxe, index) => {
        const formatterArgs = {
          seriesIndex: index,
          dataPointIndex: -1,
          w
        };
        const yS = w.globals.yAxisScale[index];
        let yAxisMinWidth = 0;
        if (!axesUtils.isYAxisHidden(index) && yaxe.labels.show && yaxe.labels.minWidth !== void 0)
          yAxisMinWidth = yaxe.labels.minWidth;
        if (!axesUtils.isYAxisHidden(index) && yaxe.labels.show && yS.result.length) {
          const lbFormatter = w.formatters.yLabelFormatters[index];
          const minV = yS.niceMin === Number.MIN_VALUE ? 0 : yS.niceMin;
          let val = yS.result.reduce((acc, curr) => {
            var _a, _b;
            return ((_a = String(lbFormatter(acc, formatterArgs))) == null ? void 0 : _a.length) > ((_b = String(lbFormatter(curr, formatterArgs))) == null ? void 0 : _b.length) ? acc : curr;
          }, minV);
          val = lbFormatter(val, formatterArgs);
          let valArr = val;
          if (typeof val === "undefined" || val.length === 0) {
            val = yS.niceMax;
          }
          if (String(val).length === 1) {
            val = val + ".0";
            valArr = val;
          }
          if (w.globals.isBarHorizontal) {
            labelPad = 0;
            const barYaxisLabels = w.labelData.labels.slice();
            val = Utils$1.getLargestStringFromArr(barYaxisLabels);
            val = lbFormatter(val, { seriesIndex: index, dataPointIndex: -1, w });
            valArr = this.dCtx.dimHelpers.getLargestStringFromMultiArr(
              val,
              barYaxisLabels
            );
          }
          const graphics = new Graphics(this.w);
          const rotateStr = "rotate(".concat(yaxe.labels.rotate, " 0 0)");
          const rect = graphics.getTextRects(
            val,
            yaxe.labels.style.fontSize,
            yaxe.labels.style.fontFamily,
            rotateStr,
            false
          );
          let arrLabelrect = rect;
          if (val !== valArr) {
            arrLabelrect = graphics.getTextRects(
              valArr,
              yaxe.labels.style.fontSize,
              yaxe.labels.style.fontFamily,
              rotateStr,
              false
            );
          }
          ret.push({
            width: (yAxisMinWidth > arrLabelrect.width || yAxisMinWidth > rect.width ? yAxisMinWidth : arrLabelrect.width > rect.width ? arrLabelrect.width : rect.width) + labelPad,
            height: arrLabelrect.height > rect.height ? arrLabelrect.height : rect.height
          });
        } else {
          ret.push({
            width,
            height
          });
        }
      });
      return ret;
    }
    /**
     * Get Y Axis Dimensions
     * @memberof Dimensions
     * @returns {Array<{width: number, height: number}>}
     **/
    getyAxisTitleCoords() {
      const w = this.w;
      const ret = [];
      w.config.yaxis.map((yaxe) => {
        if (yaxe.show && yaxe.title.text !== void 0) {
          const graphics = new Graphics(this.w);
          const rotateStr = "rotate(".concat(yaxe.title.rotate, " 0 0)");
          const rect = graphics.getTextRects(
            yaxe.title.text,
            yaxe.title.style.fontSize,
            yaxe.title.style.fontFamily,
            rotateStr,
            false
          );
          ret.push({
            width: rect.width,
            height: rect.height
          });
        } else {
          ret.push({
            width: 0,
            height: 0
          });
        }
      });
      return ret;
    }
    getTotalYAxisWidth() {
      const w = this.w;
      let yAxisWidth = 0;
      let yAxisWidthLeft = 0;
      let yAxisWidthRight = 0;
      const padding = w.globals.yAxisScale.length > 1 ? 10 : 0;
      const axesUtils = new AxesUtils(this.w, { theme: this.dCtx.theme, timeScale: this.dCtx.timeScale });
      const isHiddenYAxis = function(index) {
        return w.globals.ignoreYAxisIndexes.indexOf(index) > -1;
      };
      const padForLabelTitle = (coord, index) => {
        const floating = w.config.yaxis[index].floating;
        let width = 0;
        if (coord.width > 0 && !floating) {
          width = coord.width + padding;
          if (isHiddenYAxis(index)) {
            width = width - coord.width - padding;
          }
        } else {
          width = floating || axesUtils.isYAxisHidden(index) ? 0 : 5;
        }
        w.config.yaxis[index].opposite ? yAxisWidthRight = yAxisWidthRight + width : yAxisWidthLeft = yAxisWidthLeft + width;
        yAxisWidth = yAxisWidth + width;
      };
      w.layout.yLabelsCoords.map((yLabelCoord, index) => {
        padForLabelTitle(yLabelCoord, index);
      });
      w.layout.yTitleCoords.map((yTitleCoord, index) => {
        padForLabelTitle(yTitleCoord, index);
      });
      if (w.globals.isBarHorizontal && !w.config.yaxis[0].floating) {
        yAxisWidth = w.layout.yLabelsCoords[0].width + w.layout.yTitleCoords[0].width + 15;
      }
      this.dCtx.yAxisWidthLeft = yAxisWidthLeft;
      this.dCtx.yAxisWidthRight = yAxisWidthRight;
      return yAxisWidth;
    }
  }
  class DimGrid {
    /**
     * @param {import('./Dimensions').default} dCtx
     */
    constructor(dCtx) {
      this.w = dCtx.w;
      this.dCtx = dCtx;
    }
    /**
     * @param {number} gridWidth
     */
    gridPadForColumnsInNumericAxis(gridWidth) {
      const { w } = this;
      const { config: cnf, globals: gl } = w;
      if (gl.noData || gl.collapsedSeries.length + gl.ancillaryCollapsedSeries.length === cnf.series.length) {
        return 0;
      }
      const hasBar = (type2) => ["bar", "rangeBar", "candlestick", "boxPlot"].includes(type2);
      const type = cnf.chart.type;
      let barWidth = 0;
      let seriesLen = hasBar(type) ? cnf.series.length : 1;
      if (gl.comboBarCount > 0) {
        seriesLen = gl.comboBarCount;
      }
      gl.collapsedSeries.forEach((c) => {
        if (hasBar(c.type)) {
          seriesLen -= 1;
        }
      });
      if (cnf.chart.stacked) {
        seriesLen = 1;
      }
      const barsPresent = hasBar(type) || gl.comboBarCount > 0;
      let xRange = Math.abs(gl.initialMaxX - gl.initialMinX);
      if (barsPresent && w.axisFlags.isXNumeric && !gl.isBarHorizontal && seriesLen > 0 && xRange !== 0) {
        if (xRange <= 3) {
          xRange = gl.dataPoints;
        }
        const xRatio = xRange / gridWidth;
        let xDivision = gl.minXDiff && gl.minXDiff / xRatio > 0 ? gl.minXDiff / xRatio : 0;
        if (xDivision > gridWidth / 2) {
          xDivision /= 2;
        }
        barWidth = xDivision * parseInt(cnf.plotOptions.bar.columnWidth, 10) / 100;
        if (barWidth < 1) {
          barWidth = 1;
        }
        gl.barPadForNumericAxis = barWidth;
      }
      return barWidth;
    }
    gridPadFortitleSubtitle() {
      const { w } = this;
      const { globals: gl } = w;
      let gridShrinkOffset = this.dCtx.isSparkline || !gl.axisCharts ? 0 : 10;
      const titleSubtitle = ["title", "subtitle"];
      titleSubtitle.forEach((t) => {
        if (w.config[t].text !== void 0) {
          gridShrinkOffset += w.config[t].margin;
        } else {
          gridShrinkOffset += this.dCtx.isSparkline || !gl.axisCharts ? 0 : 5;
        }
      });
      if (w.config.legend.show && w.config.legend.position === "bottom" && !w.config.legend.floating && !gl.axisCharts) {
        gridShrinkOffset += 10;
      }
      const titleCoords = this.dCtx.dimHelpers.getTitleSubtitleCoords("title");
      const subtitleCoords = this.dCtx.dimHelpers.getTitleSubtitleCoords("subtitle");
      w.layout.gridHeight -= titleCoords.height + subtitleCoords.height + gridShrinkOffset;
      w.layout.translateY += titleCoords.height + subtitleCoords.height + gridShrinkOffset;
    }
    /**
     * @param {{width: number, height: number}[]} yTitleCoords
     * @param {{width: number, height: number}[]} yaxisLabelCoords
     */
    setGridXPosForDualYAxis(yTitleCoords, yaxisLabelCoords) {
      const { w } = this;
      const axesUtils = new AxesUtils(this.w, { theme: this.dCtx.theme, timeScale: this.dCtx.timeScale });
      w.config.yaxis.forEach((yaxe, index) => {
        if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1 && !yaxe.floating && !axesUtils.isYAxisHidden(index)) {
          if (yaxe.opposite) {
            w.layout.translateX -= yaxisLabelCoords[index].width + yTitleCoords[index].width + parseInt(yaxe.labels.style.fontSize, 10) / 1.2 + 12;
          }
          if (w.layout.translateX < 2) {
            w.layout.translateX = 2;
          }
        }
      });
    }
  }
  class Dimensions {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.theme = ctx.theme;
      this.timeScale = ctx.timeScale;
      this.lgRect = /** @type {any} */
      {};
      this.yAxisWidth = 0;
      this.yAxisWidthLeft = 0;
      this.yAxisWidthRight = 0;
      this.xAxisHeight = 0;
      this.isSparkline = this.w.config.chart.sparkline.enabled;
      this.dimHelpers = new Helpers$4(this);
      this.dimYAxis = new DimYAxis(this);
      this.dimXAxis = new DimXAxis(this);
      this.dimGrid = new DimGrid(this);
      this.lgWidthForSideLegends = 0;
      this.gridPad = this.w.config.grid.padding;
      this.xPadRight = 0;
      this.xPadLeft = 0;
      this.datalabelsCoords = { width: 0, height: 0 };
      this.xAxisWidth = 0;
      this.timescaleLabels = [];
    }
    /**
     * @memberof Dimensions
     **/
    plotCoords() {
      const w = this.w;
      const gl = w.globals;
      this.lgRect = this.dimHelpers.getLegendsRect();
      this.datalabelsCoords = { width: 0, height: 0 };
      const maxStrokeWidth = Array.isArray(w.config.stroke.width) ? Math.max(...w.config.stroke.width) : w.config.stroke.width;
      if (this.isSparkline) {
        if (w.config.markers.discrete.length > 0 || w.config.markers.size > 0) {
          Object.entries(this.gridPad).forEach(([k, v]) => {
            this.gridPad[k] = Math.max(
              v,
              this.w.globals.markers.largestSize / 1.5
            );
          });
        }
        this.gridPad.top = Math.max(maxStrokeWidth / 2, this.gridPad.top);
        this.gridPad.bottom = Math.max(maxStrokeWidth / 2, this.gridPad.bottom);
      }
      if (gl.axisCharts) {
        this.setDimensionsForAxisCharts();
      } else {
        this.setDimensionsForNonAxisCharts();
      }
      this.dimGrid.gridPadFortitleSubtitle();
      w.layout.gridHeight = w.layout.gridHeight - this.gridPad.top - this.gridPad.bottom;
      w.layout.gridWidth = w.layout.gridWidth - this.gridPad.left - this.gridPad.right - this.xPadRight - this.xPadLeft;
      const barWidth = this.dimGrid.gridPadForColumnsInNumericAxis(
        w.layout.gridWidth
      );
      w.layout.gridWidth = w.layout.gridWidth - barWidth * 2;
      w.layout.translateX = w.layout.translateX + this.gridPad.left + this.xPadLeft + (barWidth > 0 ? barWidth : 0);
      w.layout.translateY = w.layout.translateY + this.gridPad.top;
      return {
        // w.layout (future slice)
        layout: {
          gridHeight: w.layout.gridHeight,
          gridWidth: w.layout.gridWidth,
          translateX: w.layout.translateX,
          translateY: w.layout.translateY,
          translateXAxisX: w.layout.translateXAxisX,
          translateXAxisY: w.layout.translateXAxisY,
          rotateXLabels: w.layout.rotateXLabels,
          xAxisHeight: w.layout.xAxisHeight,
          xAxisLabelsHeight: w.layout.xAxisLabelsHeight,
          xAxisGroupLabelsHeight: w.layout.xAxisGroupLabelsHeight,
          xAxisLabelsWidth: w.layout.xAxisLabelsWidth,
          yLabelsCoords: w.layout.yLabelsCoords,
          yTitleCoords: w.layout.yTitleCoords
        }
      };
    }
    setDimensionsForAxisCharts() {
      const w = this.w;
      const gl = w.globals;
      const yaxisLabelCoords = this.dimYAxis.getyAxisLabelsCoords();
      const yTitleCoords = this.dimYAxis.getyAxisTitleCoords();
      if (gl.isSlopeChart) {
        this.datalabelsCoords = this.dimHelpers.getDatalabelsRect();
      }
      w.layout.yLabelsCoords = [];
      w.layout.yTitleCoords = [];
      w.config.yaxis.map((yaxe, index) => {
        w.layout.yLabelsCoords.push({
          width: yaxisLabelCoords[index].width,
          index
        });
        w.layout.yTitleCoords.push(
          /** @type {any} */
          {
            width: yTitleCoords[index].width,
            index
          }
        );
      });
      this.yAxisWidth = this.dimYAxis.getTotalYAxisWidth();
      const xaxisLabelCoords = this.dimXAxis.getxAxisLabelsCoords();
      const xaxisGroupLabelCoords = this.dimXAxis.getxAxisGroupLabelsCoords();
      const xtitleCoords = this.dimXAxis.getxAxisTitleCoords();
      this.conditionalChecksForAxisCoords(
        xaxisLabelCoords,
        xtitleCoords,
        xaxisGroupLabelCoords
      );
      w.layout.translateXAxisY = w.layout.rotateXLabels ? this.xAxisHeight / 8 : -4;
      w.layout.translateXAxisX = w.layout.rotateXLabels && w.axisFlags.isXNumeric && w.config.xaxis.labels.rotate <= -45 ? -this.xAxisWidth / 4 : 0;
      if (w.globals.isBarHorizontal) {
        w.layout.rotateXLabels = false;
        w.layout.translateXAxisY = -1 * (parseInt(w.config.xaxis.labels.style.fontSize, 10) / 1.5);
      }
      w.layout.translateXAxisY = w.layout.translateXAxisY + w.config.xaxis.labels.offsetY;
      w.layout.translateXAxisX = w.layout.translateXAxisX + w.config.xaxis.labels.offsetX;
      let yAxisWidth = this.yAxisWidth;
      let xAxisHeight = this.xAxisHeight;
      w.layout.xAxisLabelsHeight = this.xAxisHeight - xtitleCoords.height;
      w.layout.xAxisGroupLabelsHeight = w.layout.xAxisLabelsHeight - xaxisLabelCoords.height;
      w.layout.xAxisLabelsWidth = this.xAxisWidth;
      w.layout.xAxisHeight = this.xAxisHeight;
      let translateY = 10;
      if (w.config.chart.type === "radar" || this.isSparkline) {
        yAxisWidth = 0;
        xAxisHeight = 0;
      }
      if (this.isSparkline) {
        this.lgRect = {
          height: 0,
          width: 0
        };
      }
      if (this.isSparkline || w.config.chart.type === "treemap") {
        yAxisWidth = 0;
        xAxisHeight = 0;
        translateY = 0;
      }
      if (!this.isSparkline && w.config.chart.type !== "treemap") {
        this.dimXAxis.additionalPaddingXLabels(xaxisLabelCoords);
      }
      const legendTopBottom = () => {
        w.layout.translateX = yAxisWidth + this.datalabelsCoords.width;
        w.layout.gridHeight = gl.svgHeight - this.lgRect.height - xAxisHeight - (!this.isSparkline && w.config.chart.type !== "treemap" ? w.layout.rotateXLabels ? 10 : 15 : 0);
        w.layout.gridWidth = gl.svgWidth - yAxisWidth - this.datalabelsCoords.width * 2;
      };
      if (w.config.xaxis.position === "top")
        translateY = w.layout.xAxisHeight - w.config.xaxis.axisTicks.height - 5;
      switch (w.config.legend.position) {
        case "bottom":
          w.layout.translateY = translateY;
          legendTopBottom();
          break;
        case "top":
          w.layout.translateY = this.lgRect.height + translateY;
          legendTopBottom();
          break;
        case "left":
          w.layout.translateY = translateY;
          w.layout.translateX = this.lgRect.width + yAxisWidth + this.datalabelsCoords.width;
          w.layout.gridHeight = gl.svgHeight - xAxisHeight - 12;
          w.layout.gridWidth = gl.svgWidth - this.lgRect.width - yAxisWidth - this.datalabelsCoords.width * 2;
          break;
        case "right":
          w.layout.translateY = translateY;
          w.layout.translateX = yAxisWidth + this.datalabelsCoords.width;
          w.layout.gridHeight = gl.svgHeight - xAxisHeight - 12;
          w.layout.gridWidth = gl.svgWidth - this.lgRect.width - yAxisWidth - this.datalabelsCoords.width * 2 - 5;
          break;
        default:
          throw new Error("Legend position not supported");
      }
      this.dimGrid.setGridXPosForDualYAxis(yTitleCoords, yaxisLabelCoords);
      const objyAxis = new YAxis(this.w, {
        theme: this.theme,
        timeScale: this.timeScale
      });
      objyAxis.setYAxisXPosition(yaxisLabelCoords, yTitleCoords);
    }
    setDimensionsForNonAxisCharts() {
      const w = this.w;
      const gl = w.globals;
      const cnf = w.config;
      let xPad = 0;
      if (w.config.legend.show && !w.config.legend.floating) {
        xPad = 20;
      }
      const type = cnf.chart.type === "pie" || cnf.chart.type === "polarArea" || cnf.chart.type === "donut" ? "pie" : "radialBar";
      const offY = cnf.plotOptions[type].offsetY;
      const offX = cnf.plotOptions[type].offsetX;
      if (!cnf.legend.show || cnf.legend.floating) {
        w.layout.gridHeight = gl.svgHeight;
        const maxWidth = w.dom.elWrap.getBoundingClientRect().width;
        w.layout.gridWidth = Math.min(maxWidth, w.layout.gridHeight);
        w.layout.translateY = offY;
        w.layout.translateX = offX + (gl.svgWidth - w.layout.gridWidth) / 2;
        return;
      }
      switch (cnf.legend.position) {
        case "bottom":
          w.layout.gridHeight = gl.svgHeight - this.lgRect.height;
          w.layout.gridWidth = gl.svgWidth;
          w.layout.translateY = offY - 10;
          w.layout.translateX = offX + (gl.svgWidth - w.layout.gridWidth) / 2;
          break;
        case "top":
          w.layout.gridHeight = gl.svgHeight - this.lgRect.height;
          w.layout.gridWidth = gl.svgWidth;
          w.layout.translateY = this.lgRect.height + offY + 10;
          w.layout.translateX = offX + (gl.svgWidth - w.layout.gridWidth) / 2;
          break;
        case "left":
          w.layout.gridWidth = gl.svgWidth - this.lgRect.width - xPad;
          w.layout.gridHeight = cnf.chart.height !== "auto" ? gl.svgHeight : w.layout.gridWidth;
          w.layout.translateY = offY;
          w.layout.translateX = offX + this.lgRect.width + xPad;
          break;
        case "right":
          w.layout.gridWidth = gl.svgWidth - this.lgRect.width - xPad - 5;
          w.layout.gridHeight = cnf.chart.height !== "auto" ? gl.svgHeight : w.layout.gridWidth;
          w.layout.translateY = offY;
          w.layout.translateX = offX + 10;
          break;
        default:
          throw new Error("Legend position not supported");
      }
    }
    /**
     * @param {any} xaxisLabelCoords
     * @param {any} xtitleCoords
     * @param {any} xaxisGroupLabelCoords
     */
    conditionalChecksForAxisCoords(xaxisLabelCoords, xtitleCoords, xaxisGroupLabelCoords) {
      const w = this.w;
      const xAxisNum = w.labelData.hasXaxisGroups ? 2 : 1;
      const baseXAxisHeight = xaxisGroupLabelCoords.height + xaxisLabelCoords.height + xtitleCoords.height;
      const xAxisHeightMultiplicate = w.axisFlags.isMultiLineX ? 1.2 : LINE_HEIGHT_RATIO;
      const rotatedXAxisOffset = w.layout.rotateXLabels ? 22 : 10;
      const rotatedXAxisLegendOffset = w.layout.rotateXLabels && w.config.legend.position === "bottom";
      const additionalOffset = rotatedXAxisLegendOffset ? 10 : 0;
      this.xAxisHeight = baseXAxisHeight * xAxisHeightMultiplicate + xAxisNum * rotatedXAxisOffset + additionalOffset;
      this.xAxisWidth = xaxisLabelCoords.width;
      if (this.xAxisHeight - xtitleCoords.height > w.config.xaxis.labels.maxHeight) {
        this.xAxisHeight = w.config.xaxis.labels.maxHeight;
      }
      if (w.config.xaxis.labels.minHeight && this.xAxisHeight < w.config.xaxis.labels.minHeight) {
        this.xAxisHeight = w.config.xaxis.labels.minHeight;
      }
      if (w.config.xaxis.floating) {
        this.xAxisHeight = 0;
      }
      let minYAxisWidth = 0;
      let maxYAxisWidth = 0;
      w.config.yaxis.forEach((y) => {
        minYAxisWidth += y.labels.minWidth;
        maxYAxisWidth += y.labels.maxWidth;
      });
      if (this.yAxisWidth < minYAxisWidth) {
        this.yAxisWidth = minYAxisWidth;
      }
      if (this.yAxisWidth > maxYAxisWidth) {
        this.yAxisWidth = maxYAxisWidth;
      }
    }
  }
  const MINUTES_IN_DAY = 24 * 60;
  const SECONDS_IN_DAY = MINUTES_IN_DAY * 60;
  const MIN_ZOOM_DAYS = 10 / SECONDS_IN_DAY;
  class TimeScale {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.timeScaleArray = [];
      this.utc = this.w.config.xaxis.labels.datetimeUTC;
    }
    /**
     * @param {number} minX
     * @param {number} maxX
     */
    calculateTimeScaleTicks(minX, maxX) {
      const w = this.w;
      if (w.globals.allSeriesCollapsed) {
        w.labelData.labels = [];
        w.labelData.timescaleLabels = [];
        return [];
      }
      const dt = new DateTime(this.w);
      const daysDiff = (maxX - minX) / (1e3 * SECONDS_IN_DAY);
      this.determineInterval(daysDiff);
      w.interact.disableZoomIn = false;
      w.interact.disableZoomOut = false;
      if (daysDiff < MIN_ZOOM_DAYS) {
        w.interact.disableZoomIn = true;
      } else if (daysDiff > 5e4) {
        w.interact.disableZoomOut = true;
      }
      const timeIntervals = dt.getTimeUnitsfromTimestamp(minX, maxX);
      const daysWidthOnXAxis = w.layout.gridWidth / daysDiff;
      const hoursWidthOnXAxis = daysWidthOnXAxis / 24;
      const minutesWidthOnXAxis = hoursWidthOnXAxis / 60;
      const secondsWidthOnXAxis = minutesWidthOnXAxis / 60;
      const numberOfHours = Math.floor(daysDiff * 24);
      const numberOfMinutes = Math.floor(daysDiff * MINUTES_IN_DAY);
      const numberOfSeconds = Math.floor(daysDiff * SECONDS_IN_DAY);
      const numberOfDays = Math.floor(daysDiff);
      const numberOfMonths = Math.floor(daysDiff / 30);
      const numberOfYears = Math.floor(daysDiff / 365);
      const firstVal = {
        minMillisecond: timeIntervals.minMillisecond,
        minSecond: timeIntervals.minSecond,
        minMinute: timeIntervals.minMinute,
        minHour: timeIntervals.minHour,
        minDate: timeIntervals.minDate,
        minMonth: timeIntervals.minMonth,
        minYear: timeIntervals.minYear
      };
      const currentMillisecond = firstVal.minMillisecond;
      const currentSecond = firstVal.minSecond;
      const currentMinute = firstVal.minMinute;
      const currentHour = firstVal.minHour;
      const currentMonthDate = firstVal.minDate;
      const currentDate = firstVal.minDate;
      const currentMonth = firstVal.minMonth;
      const currentYear = firstVal.minYear;
      const params = {
        firstVal,
        currentMillisecond,
        currentSecond,
        currentMinute,
        currentHour,
        currentMonthDate,
        currentDate,
        currentMonth,
        currentYear,
        daysWidthOnXAxis,
        hoursWidthOnXAxis,
        minutesWidthOnXAxis,
        secondsWidthOnXAxis,
        numberOfSeconds,
        numberOfMinutes,
        numberOfHours,
        numberOfDays,
        numberOfMonths,
        numberOfYears
      };
      switch (this.tickInterval) {
        case "years": {
          this.generateYearScale(params);
          break;
        }
        case "months":
        case "half_year": {
          this.generateMonthScale(params);
          break;
        }
        case "months_days":
        case "months_fortnight":
        case "days":
        case "week_days": {
          this.generateDayScale(params);
          break;
        }
        case "hours": {
          this.generateHourScale(params);
          break;
        }
        case "minutes_fives":
        case "minutes":
          this.generateMinuteScale(params);
          break;
        case "seconds_tens":
        case "seconds_fives":
        case "seconds":
          this.generateSecondScale(params);
          break;
      }
      const adjustedMonthInTimeScaleArray = this.timeScaleArray.map(
        (ts) => {
          const defaultReturn = {
            position: ts.position,
            unit: ts.unit,
            year: ts.year,
            day: ts.day ? ts.day : 1,
            hour: ts.hour ? ts.hour : 0,
            month: ts.month + 1
          };
          if (ts.unit === "month") {
            return __spreadProps(__spreadValues({}, defaultReturn), {
              day: 1,
              value: ts.value + 1
            });
          } else if (ts.unit === "day" || ts.unit === "hour") {
            return __spreadProps(__spreadValues({}, defaultReturn), {
              value: ts.value
            });
          } else if (ts.unit === "minute") {
            return __spreadProps(__spreadValues({}, defaultReturn), {
              value: ts.value,
              minute: ts.value
            });
          } else if (ts.unit === "second") {
            return __spreadProps(__spreadValues({}, defaultReturn), {
              value: ts.value,
              minute: ts.minute,
              second: ts.second
            });
          }
          return ts;
        }
      );
      const filteredTimeScale = adjustedMonthInTimeScaleArray.filter(
        (ts) => {
          let modulo = 1;
          let ticks = Math.ceil(w.layout.gridWidth / 120);
          const value = ts.value;
          if (w.config.xaxis.tickAmount !== void 0) {
            ticks = w.config.xaxis.tickAmount;
          }
          if (adjustedMonthInTimeScaleArray.length > ticks) {
            modulo = Math.floor(adjustedMonthInTimeScaleArray.length / ticks);
          }
          let shouldNotSkipUnit = false;
          let shouldNotPrint = false;
          switch (this.tickInterval) {
            case "years":
              if (ts.unit === "year") {
                shouldNotSkipUnit = true;
              }
              break;
            case "half_year":
              modulo = 7;
              if (ts.unit === "year") {
                shouldNotSkipUnit = true;
              }
              break;
            case "months":
              modulo = 1;
              if (ts.unit === "year") {
                shouldNotSkipUnit = true;
              }
              break;
            case "months_fortnight":
              modulo = 15;
              if (ts.unit === "year" || ts.unit === "month") {
                shouldNotSkipUnit = true;
              }
              if (value === 30) {
                shouldNotPrint = true;
              }
              break;
            case "months_days":
              modulo = 10;
              if (ts.unit === "month") {
                shouldNotSkipUnit = true;
              }
              if (value === 30) {
                shouldNotPrint = true;
              }
              break;
            case "week_days":
              modulo = 8;
              if (ts.unit === "month") {
                shouldNotSkipUnit = true;
              }
              break;
            case "days":
              modulo = 1;
              if (ts.unit === "month") {
                shouldNotSkipUnit = true;
              }
              break;
            case "hours":
              if (ts.unit === "day") {
                shouldNotSkipUnit = true;
              }
              break;
            case "minutes_fives":
              if (value % 5 !== 0) {
                shouldNotPrint = true;
              }
              break;
            case "seconds_tens":
              if (value % 10 !== 0) {
                shouldNotPrint = true;
              }
              break;
            case "seconds_fives":
              if (value % 5 !== 0) {
                shouldNotPrint = true;
              }
              break;
          }
          if (this.tickInterval === "hours" || this.tickInterval === "minutes_fives" || this.tickInterval === "seconds_tens" || this.tickInterval === "seconds_fives") {
            if (!shouldNotPrint) {
              return true;
            }
          } else {
            if ((value % modulo === 0 || shouldNotSkipUnit) && !shouldNotPrint) {
              return true;
            }
          }
        }
      );
      return filteredTimeScale;
    }
    /**
     * @param {Array<Record<string, any>>} filteredTimeScale
     */
    recalcDimensionsBasedOnFormat(filteredTimeScale) {
      const w = this.w;
      const reformattedTimescaleArray = this.formatDates(filteredTimeScale);
      const removedOverlappingTS = this.removeOverlappingTS(
        reformattedTimescaleArray
      );
      w.labelData.timescaleLabels = removedOverlappingTS.slice();
      const dimensions = new Dimensions(this.w, this.ctx);
      const layoutState = dimensions.plotCoords();
      this.ctx._writeLayoutCoords(layoutState.layout);
    }
    /**
     * @param {number} daysDiff
     */
    determineInterval(daysDiff) {
      const yearsDiff = daysDiff / 365;
      const hoursDiff = daysDiff * 24;
      const minutesDiff = hoursDiff * 60;
      const secondsDiff = minutesDiff * 60;
      switch (true) {
        case yearsDiff > 5:
          this.tickInterval = "years";
          break;
        case daysDiff > 800:
          this.tickInterval = "half_year";
          break;
        case daysDiff > 180:
          this.tickInterval = "months";
          break;
        case daysDiff > 90:
          this.tickInterval = "months_fortnight";
          break;
        case daysDiff > 60:
          this.tickInterval = "months_days";
          break;
        case daysDiff > 30:
          this.tickInterval = "week_days";
          break;
        case daysDiff > 2:
          this.tickInterval = "days";
          break;
        case hoursDiff > 2.4:
          this.tickInterval = "hours";
          break;
        case minutesDiff > 15:
          this.tickInterval = "minutes_fives";
          break;
        case minutesDiff > 5:
          this.tickInterval = "minutes";
          break;
        case minutesDiff > 1:
          this.tickInterval = "seconds_tens";
          break;
        case secondsDiff > 20:
          this.tickInterval = "seconds_fives";
          break;
        default:
          this.tickInterval = "seconds";
          break;
      }
    }
    /** @param {{firstVal: any, currentMonth: any, currentYear: any, daysWidthOnXAxis: any, numberOfYears: any}} opts */
    generateYearScale({
      firstVal,
      currentMonth,
      currentYear,
      daysWidthOnXAxis,
      numberOfYears
    }) {
      let firstTickValue = firstVal.minYear;
      let firstTickPosition = 0;
      const dt = new DateTime(this.w);
      const unit = "year";
      if (firstVal.minDate > 1 || firstVal.minMonth > 0) {
        const remainingDays = dt.determineRemainingDaysOfYear(
          firstVal.minYear,
          firstVal.minMonth,
          firstVal.minDate
        );
        const remainingDaysOfFirstYear = dt.determineDaysOfYear(firstVal.minYear) - remainingDays + 1;
        firstTickPosition = remainingDaysOfFirstYear * daysWidthOnXAxis;
        firstTickValue = firstVal.minYear + 1;
        this.timeScaleArray.push({
          position: firstTickPosition,
          value: firstTickValue,
          unit,
          year: firstTickValue,
          month: 1
        });
      } else if (firstVal.minDate === 1 && firstVal.minMonth === 0) {
        this.timeScaleArray.push({
          position: firstTickPosition,
          value: firstTickValue,
          unit,
          year: currentYear,
          month: Utils$1.monthMod(currentMonth + 1)
        });
      }
      let year = firstTickValue;
      let pos = firstTickPosition;
      for (let i = 0; i < numberOfYears; i++) {
        year++;
        pos = dt.determineDaysOfYear(year - 1) * daysWidthOnXAxis + pos;
        this.timeScaleArray.push({
          position: pos,
          value: year,
          unit,
          year,
          month: 1
        });
      }
    }
    /** @param {{firstVal: any, currentMonthDate: any, currentMonth: any, currentYear: any, daysWidthOnXAxis: any, numberOfMonths: any}} opts */
    generateMonthScale({
      firstVal,
      currentMonthDate,
      currentMonth,
      currentYear,
      daysWidthOnXAxis,
      numberOfMonths
    }) {
      let firstTickValue = currentMonth;
      let firstTickPosition = 0;
      const dt = new DateTime(this.w);
      let unit = "month";
      let yrCounter = 0;
      if (firstVal.minDate > 1) {
        const remainingDaysOfFirstMonth = dt.determineDaysOfMonths(currentMonth + 1, firstVal.minYear) - currentMonthDate + 1;
        firstTickPosition = remainingDaysOfFirstMonth * daysWidthOnXAxis;
        firstTickValue = Utils$1.monthMod(currentMonth + 1);
        let year = currentYear + yrCounter;
        let month2 = Utils$1.monthMod(firstTickValue);
        let value = firstTickValue;
        if (firstTickValue === 0) {
          unit = "year";
          value = year;
          month2 = 1;
          yrCounter += 1;
          year = year + yrCounter;
        }
        this.timeScaleArray.push({
          position: firstTickPosition,
          value,
          unit,
          year,
          month: month2
        });
      } else {
        this.timeScaleArray.push({
          position: firstTickPosition,
          value: firstTickValue,
          unit,
          year: currentYear,
          month: Utils$1.monthMod(currentMonth)
        });
      }
      let month = firstTickValue + 1;
      let pos = firstTickPosition;
      for (let i = 0, j = 1; i < numberOfMonths; i++, j++) {
        month = Utils$1.monthMod(month);
        if (month === 0) {
          unit = "year";
          yrCounter += 1;
        } else {
          unit = "month";
        }
        const year = this._getYear(currentYear, month, yrCounter);
        pos = dt.determineDaysOfMonths(month, year) * daysWidthOnXAxis + pos;
        const monthVal = month === 0 ? year : month;
        this.timeScaleArray.push({
          position: pos,
          value: monthVal,
          unit,
          year,
          month: month === 0 ? 1 : month
        });
        month++;
      }
    }
    /** @param {{firstVal: any, currentMonth: any, currentYear: any, hoursWidthOnXAxis: any, numberOfDays: any}} opts */
    generateDayScale({
      firstVal,
      currentMonth,
      currentYear,
      hoursWidthOnXAxis,
      numberOfDays
    }) {
      const dt = new DateTime(this.w);
      let unit = "day";
      let firstTickValue = firstVal.minDate + 1;
      let date = firstTickValue;
      const changeMonth = (dateVal, month2, year) => {
        const monthdays = dt.determineDaysOfMonths(month2 + 1, year);
        if (dateVal > monthdays) {
          month2 = month2 + 1;
          date = 1;
          unit = "month";
          val = month2;
          return month2;
        }
        return month2;
      };
      const remainingHours = 24 - firstVal.minHour;
      const yrCounter = 0;
      let firstTickPosition = remainingHours * hoursWidthOnXAxis;
      let val = firstTickValue;
      let month = changeMonth(date, currentMonth, currentYear);
      if (firstVal.minHour === 0 && firstVal.minDate === 1) {
        firstTickPosition = 0;
        val = Utils$1.monthMod(firstVal.minMonth);
        unit = "month";
        date = firstVal.minDate;
      } else if (firstVal.minDate !== 1 && firstVal.minHour === 0 && firstVal.minMinute === 0) {
        firstTickPosition = 0;
        firstTickValue = firstVal.minDate;
        date = firstTickValue;
        val = firstTickValue;
        month = changeMonth(date, currentMonth, currentYear);
        if (val !== 1) {
          unit = "day";
        }
      }
      this.timeScaleArray.push({
        position: firstTickPosition,
        value: val,
        unit,
        year: this._getYear(currentYear, month, yrCounter),
        month: Utils$1.monthMod(month),
        day: date
      });
      let pos = firstTickPosition;
      for (let i = 0; i < numberOfDays; i++) {
        date += 1;
        unit = "day";
        month = changeMonth(
          date,
          month,
          this._getYear(currentYear, month, yrCounter)
        );
        const year = this._getYear(currentYear, month, yrCounter);
        pos = 24 * hoursWidthOnXAxis + pos;
        const value = date === 1 ? Utils$1.monthMod(month) : date;
        this.timeScaleArray.push({
          position: pos,
          value,
          unit,
          year,
          month: Utils$1.monthMod(month),
          day: value
        });
      }
    }
    /** @param {{firstVal: any, currentDate: any, currentMonth: any, currentYear: any, minutesWidthOnXAxis: any, numberOfHours: any}} opts */
    generateHourScale({
      firstVal,
      currentDate,
      currentMonth,
      currentYear,
      minutesWidthOnXAxis,
      numberOfHours
    }) {
      const dt = new DateTime(this.w);
      const yrCounter = 0;
      let unit = "hour";
      const changeDate = (dateVal, month2) => {
        const monthdays = dt.determineDaysOfMonths(month2 + 1, currentYear);
        if (dateVal > monthdays) {
          date = 1;
          month2 = month2 + 1;
        }
        return { month: month2, date };
      };
      const changeMonth = (dateVal, month2) => {
        const monthdays = dt.determineDaysOfMonths(month2 + 1, currentYear);
        if (dateVal > monthdays) {
          month2 = month2 + 1;
          return month2;
        }
        return month2;
      };
      const remainingMins = 60 - (firstVal.minMinute + firstVal.minSecond / 60);
      let firstTickPosition = remainingMins * minutesWidthOnXAxis;
      let firstTickValue = firstVal.minHour + 1;
      let hour = firstTickValue;
      if (remainingMins === 60) {
        firstTickPosition = 0;
        firstTickValue = firstVal.minHour;
        hour = firstTickValue;
      }
      let date = currentDate;
      if (hour >= 24) {
        hour = 0;
        date += 1;
        unit = "day";
        firstTickValue = date;
      }
      const checkNextMonth = changeDate(date, currentMonth);
      let month = checkNextMonth.month;
      month = changeMonth(date, month);
      if (unit === "day") {
        firstTickValue = date;
      }
      this.timeScaleArray.push({
        position: firstTickPosition,
        value: firstTickValue,
        unit,
        day: date,
        hour,
        year: currentYear,
        month: Utils$1.monthMod(month)
      });
      hour++;
      let pos = firstTickPosition;
      for (let i = 0; i < numberOfHours; i++) {
        unit = "hour";
        if (hour >= 24) {
          hour = 0;
          date += 1;
          unit = "day";
          const checkNextMonth2 = changeDate(date, month);
          month = checkNextMonth2.month;
          month = changeMonth(date, month);
        }
        const year = this._getYear(currentYear, month, yrCounter);
        pos = 60 * minutesWidthOnXAxis + pos;
        const val = hour === 0 ? date : hour;
        this.timeScaleArray.push({
          position: pos,
          value: val,
          unit,
          hour,
          day: date,
          year,
          month: Utils$1.monthMod(month)
        });
        hour++;
      }
    }
    /** @param {{currentMillisecond: any, currentSecond: any, currentMinute: any, currentHour: any, currentDate: any, currentMonth: any, currentYear: any, minutesWidthOnXAxis: any, secondsWidthOnXAxis: any, numberOfMinutes: any}} opts */
    generateMinuteScale({
      currentMillisecond,
      currentSecond,
      currentMinute,
      currentHour,
      currentDate,
      currentMonth,
      currentYear,
      minutesWidthOnXAxis,
      secondsWidthOnXAxis,
      numberOfMinutes
    }) {
      const dt = new DateTime(this.w);
      const yrCounter = 0;
      const unit = "minute";
      const remainingSecs = 60 - currentSecond;
      let firstTickPosition = (remainingSecs - currentMillisecond / 1e3) * secondsWidthOnXAxis;
      let minute = currentMinute + 1;
      if (currentSecond === 0 && currentMillisecond === 0) {
        firstTickPosition = 0;
        minute = currentMinute;
      }
      let date = currentDate;
      let month = currentMonth;
      const year = currentYear;
      let hour = currentHour;
      let pos = firstTickPosition;
      for (let i = 0; i < numberOfMinutes; i++) {
        if (minute >= 60) {
          minute = 0;
          hour += 1;
          if (hour === 24) {
            hour = 0;
            date += 1;
            const monthDays = dt.determineDaysOfMonths(
              month + 1,
              this._getYear(year, month, yrCounter)
            );
            if (date > monthDays) {
              date = 1;
              month += 1;
            }
          }
        }
        this.timeScaleArray.push({
          position: pos,
          value: minute,
          unit,
          hour,
          minute,
          day: date,
          year: this._getYear(year, month, yrCounter),
          month: Utils$1.monthMod(month)
        });
        pos += minutesWidthOnXAxis;
        minute++;
      }
    }
    /** @param {{currentMillisecond: any, currentSecond: any, currentMinute: any, currentHour: any, currentDate: any, currentMonth: any, currentYear: any, secondsWidthOnXAxis: any, numberOfSeconds: any}} opts */
    generateSecondScale({
      currentMillisecond,
      currentSecond,
      currentMinute,
      currentHour,
      currentDate,
      currentMonth,
      currentYear,
      secondsWidthOnXAxis,
      numberOfSeconds
    }) {
      const yrCounter = 0;
      const unit = "second";
      const remainingMillisecs = 1e3 - currentMillisecond;
      let firstTickPosition = remainingMillisecs / 1e3 * secondsWidthOnXAxis;
      let second = currentSecond + 1;
      if (currentMillisecond === 0) {
        firstTickPosition = 0;
        second = currentSecond;
      }
      let minute = currentMinute;
      const date = currentDate;
      const month = currentMonth;
      const year = currentYear;
      let hour = currentHour;
      let pos = firstTickPosition;
      for (let i = 0; i < numberOfSeconds; i++) {
        if (second >= 60) {
          minute++;
          second = 0;
          if (minute >= 60) {
            hour++;
            minute = 0;
            if (hour === 24) {
              hour = 0;
            }
          }
        }
        this.timeScaleArray.push({
          position: pos,
          value: second,
          unit,
          hour,
          minute,
          second,
          day: date,
          year: this._getYear(year, month, yrCounter),
          month: Utils$1.monthMod(month)
        });
        pos += secondsWidthOnXAxis;
        second++;
      }
    }
    /**
     * @param {Record<string, any>} ts
     * @param {string | number} value
     */
    createRawDateString(ts, value) {
      let raw = ts.year;
      if (ts.month === 0) {
        ts.month = 1;
      }
      raw += "-" + ("0" + ts.month.toString()).slice(-2);
      if (ts.unit === "day") {
        raw += "-" + ("0" + value).slice(-2);
      } else {
        raw += "-" + ("0" + (ts.day ? ts.day : "1")).slice(-2);
      }
      if (ts.unit === "hour") {
        raw += "T" + ("0" + value).slice(-2);
      } else {
        raw += "T" + ("0" + (ts.hour ? ts.hour : "0")).slice(-2);
      }
      if (ts.unit === "minute") {
        raw += ":" + ("0" + value).slice(-2);
      } else {
        raw += ":" + (ts.minute ? ("0" + ts.minute).slice(-2) : "00");
      }
      if (ts.unit === "second") {
        raw += ":" + ("0" + value).slice(-2);
      } else {
        raw += ":00";
      }
      if (this.utc) {
        raw += ".000Z";
      }
      return raw;
    }
    /**
     * @param {Array<Record<string, any>>} filteredTimeScale
     */
    formatDates(filteredTimeScale) {
      const w = this.w;
      const reformattedTimescaleArray = filteredTimeScale.map(
        (ts) => {
          let value = ts.value.toString();
          const dt = new DateTime(this.w);
          const raw = this.createRawDateString(ts, value);
          let dateToFormat = dt.getDate(dt.parseDate(raw));
          if (!this.utc) {
            dateToFormat = dt.getDate(dt.parseDateWithTimezone(raw));
          }
          if (w.config.xaxis.labels.format === void 0) {
            let customFormat = "dd MMM";
            const dtFormatter = w.config.xaxis.labels.datetimeFormatter;
            if (ts.unit === "year") customFormat = dtFormatter.year;
            if (ts.unit === "month") customFormat = dtFormatter.month;
            if (ts.unit === "day") customFormat = dtFormatter.day;
            if (ts.unit === "hour") customFormat = dtFormatter.hour;
            if (ts.unit === "minute") customFormat = dtFormatter.minute;
            if (ts.unit === "second") customFormat = dtFormatter.second;
            value = dt.formatDate(dateToFormat, customFormat);
          } else {
            value = dt.formatDate(dateToFormat, w.config.xaxis.labels.format);
          }
          return {
            dateString: raw,
            position: ts.position,
            value,
            unit: ts.unit,
            year: ts.year,
            month: ts.month
          };
        }
      );
      return reformattedTimescaleArray;
    }
    /**
     * @param {any[]} arr
     */
    removeOverlappingTS(arr) {
      const graphics = new Graphics(this.w);
      let equalLabelLengthFlag = false;
      let constantLabelWidth;
      if (arr.length > 0 && // check arr length
      arr[0].value && // check arr[0] contains value
      /**
       * @param {Record<string, any>} lb
       */
      arr.every((lb) => lb.value.length === arr[0].value.length)) {
        equalLabelLengthFlag = true;
        constantLabelWidth = graphics.getTextRects(
          arr[0].value,
          this.w.config.xaxis.labels.style.fontSize
        ).width;
      }
      let lastDrawnIndex = 0;
      let filteredArray = arr.map((item, index) => {
        if (index > 0 && this.w.config.xaxis.labels.hideOverlappingLabels) {
          const prevLabelWidth = !equalLabelLengthFlag ? graphics.getTextRects(
            /** @type {any} */
            arr[lastDrawnIndex].value,
            this.w.config.xaxis.labels.style.fontSize
          ).width : constantLabelWidth;
          const prevPos = arr[lastDrawnIndex].position;
          const pos = item.position;
          if (pos > prevPos + prevLabelWidth + 10) {
            lastDrawnIndex = index;
            return item;
          } else {
            return null;
          }
        } else {
          return item;
        }
      });
      filteredArray = filteredArray.filter((f) => f !== null);
      return filteredArray;
    }
    /**
     * @param {number} currentYear
     * @param {number} month
     * @param {number} yrCounter
     */
    _getYear(currentYear, month, yrCounter) {
      return currentYear + Math.floor(month / 12) + yrCounter;
    }
  }
  const REGISTRY_KEY = "__apexcharts_registry__";
  if (!/** @type {any} */
  globalThis[REGISTRY_KEY]) {
    globalThis[REGISTRY_KEY] = {};
  }
  function getRegistry() {
    return (
      /** @type {any} */
      globalThis[REGISTRY_KEY]
    );
  }
  function register(typeMap) {
    Object.assign(getRegistry(), typeMap);
  }
  function getChartClass(type) {
    const Cls = getRegistry()[type];
    if (!Cls) {
      throw new Error(
        `ApexCharts: chart type "${type}" is not registered. Import it via ApexCharts.use() or use the full apexcharts bundle.`
      );
    }
    return Cls;
  }
  class Core {
    /**
     * @param {Element} el
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(el, w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.el = el;
    }
    setupElements() {
      const { globals: gl, config: cnf } = this.w;
      const ct = cnf.chart.type;
      const xyChartsArrTypes = [
        "line",
        "area",
        "bar",
        "rangeBar",
        "rangeArea",
        "candlestick",
        "boxPlot",
        "scatter",
        "bubble"
      ];
      const axisChartsArrTypes = [
        ...xyChartsArrTypes,
        "radar",
        "heatmap",
        "treemap"
      ];
      gl.axisCharts = axisChartsArrTypes.includes(ct);
      gl.xyCharts = xyChartsArrTypes.includes(ct);
      gl.isBarHorizontal = ["bar", "rangeBar", "boxPlot"].includes(ct) && cnf.plotOptions.bar.horizontal;
      gl.chartClass = `.apexcharts${gl.chartID}`;
      this.w.dom.baseEl = this.el;
      this.w.dom.elWrap = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "div"
      );
      Graphics.setAttrs(this.w.dom.elWrap, {
        id: gl.chartClass.substring(1),
        class: `apexcharts-canvas ${gl.chartClass.substring(1)}`
      });
      this.el.appendChild(this.w.dom.elWrap);
      const SVG2 = Environment.isBrowser() ? (
        /** @type {any} */
        window.SVG
      ) : (
        /** @type {any} */
        global.SVG
      );
      this.w.dom.Paper = SVG2().addTo(this.w.dom.elWrap);
      this.w.dom.Paper.attr({
        class: "apexcharts-svg",
        "xmlns:data": "ApexChartsNS",
        transform: `translate(${cnf.chart.offsetX}, ${cnf.chart.offsetY})`
      });
      this.w.dom.Paper.node.style.background = cnf.theme.mode === "dark" && !cnf.chart.background ? "#343A3F" : cnf.theme.mode === "light" && !cnf.chart.background ? "#fff" : cnf.chart.background;
      this.setSVGDimensions();
      this.w.dom.elLegendForeign = BrowserAPIs.createElementNS(
        SVGNS,
        "foreignObject"
      );
      Graphics.setAttrs(this.w.dom.elLegendForeign, {
        x: 0,
        y: 0,
        width: gl.svgWidth,
        height: gl.svgHeight
      });
      this.w.dom.elLegendWrap = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "div"
      );
      this.w.dom.elLegendWrap.classList.add("apexcharts-legend");
      this.w.dom.elWrap.appendChild(this.w.dom.elLegendWrap);
      this.w.dom.Paper.node.appendChild(this.w.dom.elLegendForeign);
      if (cnf.chart.accessibility.enabled) {
        const ariaLabel = this.getAccessibleChartLabel();
        const svgRole = cnf.chart.accessibility.keyboard.enabled && cnf.chart.accessibility.keyboard.navigation.enabled ? "application" : "img";
        this.w.dom.Paper.attr({
          role: svgRole,
          "aria-label": ariaLabel
        });
        if (cnf.chart.accessibility.description) {
          const descEl = BrowserAPIs.createElementNS(SVGNS, "desc");
          descEl.textContent = cnf.chart.accessibility.description;
          this.w.dom.Paper.node.insertBefore(
            descEl,
            this.w.dom.elLegendForeign.nextSibling
          );
        }
      }
      this.w.dom.elGraphical = this.w.dom.Paper.group().attr({
        class: "apexcharts-inner apexcharts-graphical"
      });
      this.w.dom.elDefs = this.w.dom.Paper.defs();
      this.w.dom.Paper.add(this.w.dom.elGraphical);
      this.w.dom.elGraphical.add(this.w.dom.elDefs);
    }
    /**
     * @param {any[]} ser
     * @param {import('../types/internal').XYRatios} xyRatios
     */
    plotChartType(ser, xyRatios) {
      const { w, ctx } = this;
      const { config: cnf, globals: gl } = w;
      const seriesTypes = {
        line: { series: [], i: [] },
        area: { series: [], i: [] },
        scatter: { series: [], i: [] },
        bubble: { series: [], i: [] },
        bar: { series: [], i: [] },
        candlestick: { series: [], i: [] },
        boxPlot: { series: [], i: [] },
        rangeBar: { series: [], i: [] },
        rangeArea: { series: [], seriesRangeEnd: [], i: [] }
      };
      const chartType = cnf.chart.type || "line";
      let nonComboType = null;
      let comboCount = 0;
      this.w.seriesData.series.forEach((serie, st) => {
        var _a, _b;
        const seriesType = ((_a = ser[st]) == null ? void 0 : _a.type) === "column" ? "bar" : ((_b = ser[st]) == null ? void 0 : _b.type) || (chartType === "column" ? "bar" : chartType);
        if (
          /** @type {Record<string,any>} */
          seriesTypes[seriesType]
        ) {
          if (seriesType === "rangeArea") {
            seriesTypes[seriesType].series.push(this.w.rangeData.seriesRangeStart[st]);
            seriesTypes[seriesType].seriesRangeEnd.push(this.w.rangeData.seriesRangeEnd[st]);
          } else {
            seriesTypes[seriesType].series.push(serie);
          }
          seriesTypes[seriesType].i.push(st);
          if (seriesType === "bar") w.globals.columnSeries = seriesTypes.bar;
        } else if ([
          "heatmap",
          "treemap",
          "pie",
          "donut",
          "polarArea",
          "radialBar",
          "radar"
        ].includes(seriesType)) {
          nonComboType = seriesType;
        } else {
          console.warn(
            `You have specified an unrecognized series type (${seriesType}).`
          );
        }
        if (chartType !== seriesType && seriesType !== "scatter") comboCount++;
      });
      if (comboCount > 0) {
        if (nonComboType) {
          console.warn(
            `Chart or series type ${nonComboType} cannot appear with other chart or series types.`
          );
        }
        if (seriesTypes.bar.series.length > 0 && cnf.plotOptions.bar.horizontal) {
          comboCount -= seriesTypes.bar.series.length;
          seriesTypes.bar = { series: [], i: [] };
          w.globals.columnSeries = { series: [], i: [] };
          console.warn(
            "Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`"
          );
        }
      }
      gl.comboCharts || (gl.comboCharts = comboCount > 0);
      const needsLine = seriesTypes.line.series.length > 0 || seriesTypes.area.series.length > 0 || seriesTypes.scatter.series.length > 0 || seriesTypes.bubble.series.length > 0 || seriesTypes.rangeArea.series.length > 0 || !gl.comboCharts && ["line", "area", "scatter", "bubble", "rangeArea"].includes(
        cnf.chart.type
      );
      const line = needsLine ? new (getChartClass("line"))(ctx.w, ctx, xyRatios) : null;
      const needsCandlestick = seriesTypes.candlestick.series.length > 0 || seriesTypes.boxPlot.series.length > 0 || !gl.comboCharts && ["candlestick", "boxPlot"].includes(cnf.chart.type);
      const boxCandlestick = needsCandlestick ? new (getChartClass("candlestick"))(ctx.w, ctx, xyRatios) : null;
      const needsPie = !gl.comboCharts && ["pie", "donut", "polarArea"].includes(cnf.chart.type);
      ctx.pie = needsPie ? new (getChartClass("pie"))(ctx.w, ctx) : null;
      const needsRangeBar = seriesTypes.rangeBar.series.length > 0 || !gl.comboCharts && cnf.chart.type === "rangeBar";
      ctx.rangeBar = needsRangeBar ? new (getChartClass("rangeBar"))(ctx.w, ctx, xyRatios) : null;
      let elGraph = [];
      if (gl.comboCharts) {
        const coreUtils = new CoreUtils(this.w);
        if (seriesTypes.area.series.length > 0) {
          elGraph.push(
            ...coreUtils.drawSeriesByGroup(
              seriesTypes.area,
              gl.areaGroups,
              "area",
              line
            )
          );
        }
        if (seriesTypes.bar.series.length > 0) {
          if (cnf.chart.stacked) {
            const barStacked = new (getChartClass("barStacked"))(
              ctx.w,
              ctx,
              xyRatios
            );
            elGraph.push(
              barStacked.draw(seriesTypes.bar.series, seriesTypes.bar.i)
            );
          } else {
            ctx.bar = new (getChartClass("bar"))(ctx.w, ctx, xyRatios);
            elGraph.push(ctx.bar.draw(seriesTypes.bar.series, seriesTypes.bar.i));
          }
        }
        if (seriesTypes.rangeArea.series.length > 0) {
          elGraph.push(
            line.draw(
              seriesTypes.rangeArea.series,
              "rangeArea",
              seriesTypes.rangeArea.i,
              seriesTypes.rangeArea.seriesRangeEnd
            )
          );
        }
        if (seriesTypes.line.series.length > 0) {
          elGraph.push(
            ...coreUtils.drawSeriesByGroup(
              seriesTypes.line,
              gl.lineGroups,
              "line",
              line
            )
          );
        }
        if (seriesTypes.candlestick.series.length > 0) {
          elGraph.push(
            boxCandlestick.draw(
              seriesTypes.candlestick.series,
              "candlestick",
              seriesTypes.candlestick.i
            )
          );
        }
        if (seriesTypes.boxPlot.series.length > 0) {
          elGraph.push(
            boxCandlestick.draw(
              seriesTypes.boxPlot.series,
              "boxPlot",
              seriesTypes.boxPlot.i
            )
          );
        }
        if (seriesTypes.rangeBar.series.length > 0) {
          elGraph.push(
            ctx.rangeBar.draw(
              seriesTypes.rangeBar.series,
              seriesTypes.rangeBar.i
            )
          );
        }
        if (seriesTypes.scatter.series.length > 0) {
          const scatterLine = new (getChartClass("line"))(
            ctx.w,
            ctx,
            xyRatios,
            true
          );
          elGraph.push(
            scatterLine.draw(
              seriesTypes.scatter.series,
              "scatter",
              seriesTypes.scatter.i
            )
          );
        }
        if (seriesTypes.bubble.series.length > 0) {
          const bubbleLine = new (getChartClass("line"))(
            ctx.w,
            ctx,
            xyRatios,
            true
          );
          elGraph.push(
            bubbleLine.draw(
              seriesTypes.bubble.series,
              "bubble",
              seriesTypes.bubble.i
            )
          );
        }
      } else {
        const type = cnf.chart.type;
        switch (type) {
          case "line":
            elGraph = line.draw(this.w.seriesData.series, "line");
            break;
          case "area":
            elGraph = line.draw(this.w.seriesData.series, "area");
            break;
          case "bar":
            if (cnf.chart.stacked) {
              const barStacked = new (getChartClass("barStacked"))(
                ctx.w,
                ctx,
                xyRatios
              );
              elGraph = barStacked.draw(this.w.seriesData.series);
            } else {
              ctx.bar = new (getChartClass("bar"))(ctx.w, ctx, xyRatios);
              elGraph = ctx.bar.draw(this.w.seriesData.series);
            }
            break;
          case "candlestick":
            elGraph = boxCandlestick.draw(this.w.seriesData.series, "candlestick");
            break;
          case "boxPlot":
            elGraph = boxCandlestick.draw(this.w.seriesData.series, type);
            break;
          case "rangeBar":
            elGraph = ctx.rangeBar.draw(this.w.seriesData.series);
            break;
          case "rangeArea":
            elGraph = line.draw(
              this.w.rangeData.seriesRangeStart,
              "rangeArea",
              void 0,
              this.w.rangeData.seriesRangeEnd
            );
            break;
          case "heatmap": {
            const heatmap = new (getChartClass("heatmap"))(ctx.w, ctx, xyRatios);
            elGraph = heatmap.draw(this.w.seriesData.series);
            break;
          }
          case "treemap": {
            const treemap = new (getChartClass("treemap"))(ctx.w, ctx);
            elGraph = treemap.draw(this.w.seriesData.series);
            break;
          }
          case "pie":
          case "donut":
          case "polarArea":
            elGraph = ctx.pie.draw(this.w.seriesData.series);
            break;
          case "radialBar": {
            const radialBar = new (getChartClass("radialBar"))(ctx.w, ctx);
            elGraph = radialBar.draw(this.w.seriesData.series);
            break;
          }
          case "radar": {
            const radar = new (getChartClass("radar"))(ctx.w, ctx);
            elGraph = radar.draw(this.w.seriesData.series);
            break;
          }
          default:
            elGraph = line.draw(this.w.seriesData.series);
        }
      }
      return elGraph;
    }
    setSVGDimensions() {
      var _a;
      const { globals: gl, config: cnf } = this.w;
      cnf.chart.width = cnf.chart.width || "100%";
      cnf.chart.height = cnf.chart.height || "auto";
      const rawWidth = cnf.chart.width;
      const rawHeight = cnf.chart.height;
      gl.svgWidth = NaN;
      gl.svgHeight = NaN;
      let elDim = Utils$1.getDimensions(this.el);
      const widthUnit = rawWidth.toString().split(/[0-9]+/g).pop();
      if (widthUnit === "%") {
        if (Utils$1.isNumber(elDim[0])) {
          if (elDim[0].width === 0) {
            elDim = Utils$1.getDimensions(this.el.parentNode);
          }
          gl.svgWidth = elDim[0] * parseInt(rawWidth, 10) / 100;
        }
      } else if (widthUnit === "px" || widthUnit === "") {
        gl.svgWidth = parseInt(rawWidth, 10);
      }
      const heightUnit = String(rawHeight).toString().split(/[0-9]+/g).pop();
      if (rawHeight !== "auto" && rawHeight !== "") {
        if (heightUnit === "%") {
          const elParentDim = Utils$1.getDimensions(this.el.parentNode);
          gl.svgHeight = elParentDim[1] * parseInt(rawHeight, 10) / 100;
        } else {
          gl.svgHeight = parseInt(rawHeight, 10);
        }
      } else {
        gl.svgHeight = gl.axisCharts ? gl.svgWidth / 1.61 : gl.svgWidth / 1.2;
      }
      gl.svgWidth = Math.max(gl.svgWidth, 0);
      gl.svgHeight = Math.max(gl.svgHeight, 0);
      Graphics.setAttrs(this.w.dom.Paper.node, {
        width: gl.svgWidth,
        height: gl.svgHeight
      });
      if (heightUnit !== "%" && Environment.isBrowser()) {
        const offsetY = cnf.chart.sparkline.enabled ? 0 : gl.axisCharts ? cnf.chart.parentHeightOffset : 0;
        const paperNode = this.w.dom.Paper.node;
        if ((_a = paperNode.parentNode) == null ? void 0 : _a.parentNode) {
          paperNode.parentNode.parentNode.style.minHeight = `${gl.svgHeight + offsetY}px`;
        }
      }
      this.w.dom.elWrap.style.width = `${gl.svgWidth}px`;
      this.w.dom.elWrap.style.height = `${gl.svgHeight}px`;
    }
    shiftGraphPosition() {
      const { globals: gl } = this.w;
      const { translateY: tY, translateX: tX } = gl;
      Graphics.setAttrs(this.w.dom.elGraphical.node, {
        transform: `translate(${tX}, ${tY})`
      });
    }
    resizeNonAxisCharts() {
      var _a, _b;
      const { w } = this;
      let legendHeight = 0;
      let offY = w.config.chart.sparkline.enabled ? 1 : 15;
      offY += w.config.grid.padding.bottom;
      if (["top", "bottom"].includes(w.config.legend.position) && w.config.legend.show && !w.config.legend.floating) {
        legendHeight = ((_b = (_a = this.ctx.legend) == null ? void 0 : _a.legendHelpers.getLegendDimensions().clwh) != null ? _b : 0) + 7;
      }
      const el = w.dom.baseEl.querySelector(
        ".apexcharts-radialbar, .apexcharts-pie"
      );
      let chartInnerDimensions = w.globals.radialSize * 2.05;
      if (el && !w.config.chart.sparkline.enabled && w.config.plotOptions.radialBar.startAngle !== 0) {
        const elRadialRect = Utils$1.getBoundingClientRect(el);
        chartInnerDimensions = elRadialRect.bottom;
        const maxHeight = elRadialRect.bottom - elRadialRect.top;
        chartInnerDimensions = Math.max(w.globals.radialSize * 2.05, maxHeight);
      }
      const newHeight = Math.ceil(
        chartInnerDimensions + this.w.layout.translateY + legendHeight + offY
      );
      if (this.w.dom.elLegendForeign) {
        this.w.dom.elLegendForeign.setAttribute("height", String(newHeight));
      }
      if (w.config.chart.height && String(w.config.chart.height).includes("%"))
        return;
      this.w.dom.elWrap.style.height = `${newHeight}px`;
      Graphics.setAttrs(this.w.dom.Paper.node, { height: newHeight });
      if (Environment.isBrowser()) {
        this.w.dom.Paper.node.parentNode.parentNode.style.minHeight = `${newHeight}px`;
      }
    }
    coreCalculations() {
      new Range(this.w).init();
    }
    resetGlobals() {
      const resetxyValues = () => this.w.config.series.map(() => []);
      const globalObj = new Globals();
      const { globals: gl } = this.w;
      const parsingFlags = {
        dataWasParsed: this.w.axisFlags.dataWasParsed,
        originalSeries: gl.originalSeries
      };
      globalObj.initGlobalVars(gl);
      gl.seriesXvalues = resetxyValues();
      gl.seriesYvalues = resetxyValues();
      if (parsingFlags.dataWasParsed) {
        this.w.axisFlags.dataWasParsed = parsingFlags.dataWasParsed;
        gl.originalSeries = parsingFlags.originalSeries;
      }
    }
    isMultipleY() {
      if (Array.isArray(this.w.config.yaxis) && this.w.config.yaxis.length > 1) {
        this.w.globals.isMultipleYAxis = true;
        return true;
      }
      return false;
    }
    xySettings() {
      const { w } = this;
      let xyRatios = null;
      if (w.globals.axisCharts) {
        if (w.config.xaxis.crosshairs.position === "back") {
          new Crosshairs(this.w).drawXCrosshairs();
        }
        if (w.config.yaxis[0].crosshairs.position === "back") {
          new Crosshairs(this.w).drawYCrosshairs();
        }
        if (w.config.xaxis.type === "datetime" && w.config.xaxis.labels.formatter === void 0) {
          this.ctx.timeScale = new TimeScale(this.w, this.ctx);
          let formattedTimeScale = [];
          if (isFinite(w.globals.minX) && isFinite(w.globals.maxX) && !w.globals.isBarHorizontal) {
            formattedTimeScale = this.ctx.timeScale.calculateTimeScaleTicks(
              w.globals.minX,
              w.globals.maxX
            );
          } else if (w.globals.isBarHorizontal) {
            formattedTimeScale = this.ctx.timeScale.calculateTimeScaleTicks(
              w.globals.minY,
              w.globals.maxY
            );
          }
          this.ctx.timeScale.recalcDimensionsBasedOnFormat(formattedTimeScale);
        }
        const coreUtils = new CoreUtils(this.w);
        xyRatios = coreUtils.getCalculatedRatios();
      }
      return xyRatios;
    }
    /**
     * @param {any} targetChart
     */
    updateSourceChart(targetChart) {
      this.ctx.w.interact.selection = void 0;
      this.ctx.updateHelpers._updateOptions(
        {
          chart: {
            selection: {
              xaxis: {
                min: targetChart.w.globals.minX,
                max: targetChart.w.globals.maxX
              }
            }
          }
        },
        false,
        false
      );
    }
    setupBrushHandler() {
      const { ctx, w } = this;
      if (!w.config.chart.brush.enabled) return;
      if (typeof w.config.chart.events.selection !== "function") {
        const targets = Array.isArray(w.config.chart.brush.targets) ? w.config.chart.brush.targets : [w.config.chart.brush.target];
        targets.forEach((target) => {
          const targetChart = (
            /** @type {any} */
            ctx.constructor.getChartByID(
              target
            )
          );
          targetChart.w.globals.brushSource = this.ctx;
          if (typeof targetChart.w.config.chart.events.zoomed !== "function") {
            targetChart.w.config.chart.events.zoomed = () => this.updateSourceChart(targetChart);
          }
          if (typeof targetChart.w.config.chart.events.scrolled !== "function") {
            targetChart.w.config.chart.events.scrolled = () => (
              /**
               * @param {any} chart
               * @param {Event} e
               */
              this.updateSourceChart(targetChart)
            );
          }
        });
        w.config.chart.events.selection = (chart, e) => {
          targets.forEach((target) => {
            const targetChart = (
              /** @type {any} */
              ctx.constructor.getChartByID(
                target
              )
            );
            targetChart.ctx.updateHelpers._updateOptions(
              {
                xaxis: {
                  min: e.xaxis.min,
                  max: e.xaxis.max
                }
              },
              false,
              false,
              false,
              false
            );
          });
        };
      }
    }
    getAccessibleChartLabel() {
      const w = this.w;
      const cnf = w.config;
      let label = "";
      if (cnf.chart.accessibility && cnf.chart.accessibility.description) {
        label = cnf.chart.accessibility.description;
      } else if (cnf.title.text) {
        const chartType = cnf.chart.type;
        label = `${cnf.title.text}. ${chartType} chart`;
        if (cnf.subtitle.text) {
          label += `. ${cnf.subtitle.text}`;
        }
      } else {
        const chartType = cnf.chart.type;
        const seriesCount = w.seriesData.series.length || (cnf.series ? cnf.series.length : 0);
        label = `${chartType} chart with ${seriesCount} data series`;
      }
      return label;
    }
  }
  class Data {
    /**
     * @param {import('../types/internal').ChartStateW} w
     */
    constructor(w, { resetGlobals = () => {
    }, isMultipleY = () => {
    } } = {}) {
      this.w = w;
      this.resetGlobals = resetGlobals;
      this.isMultipleY = isMultipleY;
      this.twoDSeries = [];
      this.threeDSeries = [];
      this.twoDSeriesX = [];
      this.seriesGoals = [];
      this.coreUtils = new CoreUtils(this.w);
      this.activeSeriesIndex = 0;
    }
    // Helper to get the first valid data point from the active series
    getFirstDataPoint() {
      const series = this.w.config.series;
      const sr = new Series(this.w);
      this.activeSeriesIndex = sr.getActiveConfigSeriesIndex();
      const activeItem = (
        /** @type {any} */
        series[this.activeSeriesIndex]
      );
      if (activeItem && activeItem.data && activeItem.data.length > 0 && activeItem.data[0] !== null && typeof activeItem.data[0] !== "undefined") {
        return activeItem.data[0];
      }
      return null;
    }
    isMultiFormat() {
      return this.isFormatXY() || this.isFormat2DArray();
    }
    // given format is [{x, y}, {x, y}]
    isFormatXY() {
      var _a;
      const firstDataPoint = this.getFirstDataPoint();
      if (!firstDataPoint || typeof firstDataPoint.x === "undefined") return false;
      const data = (
        /** @type {any} */
        (_a = this.w.config.series[this.activeSeriesIndex]) == null ? void 0 : _a.data
      );
      if (data) {
        const isXY = (pt) => pt && typeof pt.x !== "undefined";
        for (let k = 1; k < Math.min(3, data.length); k++) {
          if (isXY(data[k]) !== true) {
            console.warn(
              `ApexCharts: series data has mixed formats starting at index ${k}`
            );
            break;
          }
        }
      }
      return true;
    }
    // given format is [[x, y], [x, y]]
    isFormat2DArray() {
      const firstDataPoint = this.getFirstDataPoint();
      return firstDataPoint && Array.isArray(firstDataPoint);
    }
    /**
     * @param {any[]} ser
     * @param {number} i
     */
    handleFormat2DArray(ser, i) {
      const cnf = this.w.config;
      const data = ser[i].data;
      const isBoxPlot = cnf.chart.type === "boxPlot" || /** @type {any} */
      cnf.series[i].type === "boxPlot";
      for (let j = 0; j < data.length; j++) {
        const point = data[j];
        const x = point[0];
        const y = point[1];
        const z = point[2];
        if (typeof y !== "undefined") {
          if (Array.isArray(y) && y.length === 4 && !isBoxPlot) {
            this.twoDSeries.push(Utils$1.parseNumber(y[3]));
          } else if (point.length >= 5) {
            this.twoDSeries.push(Utils$1.parseNumber(point[4]));
          } else {
            this.twoDSeries.push(Utils$1.parseNumber(y));
          }
          this.w.axisFlags.dataFormatXNumeric = true;
        }
        if (cnf.xaxis.type === "datetime") {
          const ts = new Date(x).getTime();
          this.twoDSeriesX.push(ts);
        } else {
          this.twoDSeriesX.push(x);
        }
        if (typeof z !== "undefined") {
          this.threeDSeries.push(z);
          this.w.axisFlags.isDataXYZ = true;
        }
      }
    }
    /**
     * @param {any[]} ser
     * @param {number} i
     */
    handleFormatXY(ser, i) {
      const cnf = this.w.config;
      const gl = this.w.globals;
      const dt = new DateTime(this.w);
      const data = ser[i].data;
      let activeI = i;
      if (gl.collapsedSeriesIndices.indexOf(i) > -1) {
        activeI = this.activeSeriesIndex;
      }
      const activeData = ser[activeI].data;
      for (let j = 0; j < data.length; j++) {
        const point = data[j];
        if (typeof point.y !== "undefined") {
          const val = Array.isArray(point.y) ? Utils$1.parseNumber(point.y[point.y.length - 1]) : Utils$1.parseNumber(point.y);
          this.twoDSeries.push(val);
        }
        if (typeof this.seriesGoals[i] === "undefined") {
          this.seriesGoals[i] = [];
        }
        if (typeof point.goals !== "undefined" && Array.isArray(point.goals)) {
          this.seriesGoals[i].push(point.goals);
        } else {
          this.seriesGoals[i].push(null);
        }
        if (typeof point.z !== "undefined") {
          this.threeDSeries.push(point.z);
          this.w.axisFlags.isDataXYZ = true;
        }
      }
      for (let j = 0; j < activeData.length; j++) {
        const point = activeData[j];
        const x = point.x;
        const isXString = typeof x === "string";
        const isXArr = Array.isArray(x);
        const isXDate = !isXArr && !!dt.isValidDate(x);
        if (isXString || isXDate) {
          if (isXString || cnf.xaxis.convertedCatToNumeric) {
            const isRangeColumn = gl.isBarHorizontal && this.w.axisFlags.isRangeData;
            if (cnf.xaxis.type === "datetime" && !isRangeColumn) {
              this.twoDSeriesX.push(dt.parseDate(x));
            } else {
              this.fallbackToCategory = true;
              this.twoDSeriesX.push(x);
              if (!isNaN(x) && this.w.config.xaxis.type !== "category" && typeof x !== "string") {
                this.w.axisFlags.isXNumeric = true;
              }
            }
          } else {
            if (cnf.xaxis.type === "datetime") {
              this.twoDSeriesX.push(dt.parseDate(x.toString()));
            } else {
              this.w.axisFlags.dataFormatXNumeric = true;
              this.w.axisFlags.isXNumeric = true;
              this.twoDSeriesX.push(parseFloat(x));
            }
          }
        } else if (isXArr) {
          this.fallbackToCategory = true;
          this.twoDSeriesX.push(x);
        } else {
          this.w.axisFlags.isXNumeric = true;
          this.w.axisFlags.dataFormatXNumeric = true;
          this.twoDSeriesX.push(x);
        }
      }
    }
    /**
     * @param {any[]} ser
     * @param {number} i
     */
    handleRangeData(ser, i) {
      let range = { start: [], end: [], rangeUniques: [] };
      if (this.isFormat2DArray()) {
        range = this.handleRangeDataFormat("array", ser, i);
      } else if (this.isFormatXY()) {
        range = this.handleRangeDataFormat("xy", ser, i);
      }
      this.w.rangeData.seriesRangeStart[i] = range.start === void 0 ? [] : range.start;
      this.w.rangeData.seriesRangeEnd[i] = range.end === void 0 ? [] : range.end;
      this.w.rangeData.seriesRange[i] = range.rangeUniques;
      this.w.rangeData.seriesRange.forEach((sr) => {
        if (!sr) return;
        sr.forEach((sarr) => {
          const yItems = (
            /** @type {any} */
            sarr.y
          );
          const len = (
            /** @type {any[]} */
            yItems.length
          );
          if (len <= 1) return;
          for (let arri = 0; arri < len; arri++) {
            const arr = (
              /** @type {any} */
              yItems[arri]
            );
            const range1y1 = arr.y1;
            const range1y2 = arr.y2;
            for (let sri = arri + 1; sri < len; sri++) {
              const range2 = (
                /** @type {any} */
                yItems[sri]
              );
              const range2y1 = range2.y1;
              const range2y2 = range2.y2;
              if (range1y1 <= range2y2 && range2y1 <= range1y2) {
                const sarrAny = (
                  /** @type {any} */
                  sarr
                );
                sarrAny.overlaps.add(arr.rangeName);
                sarrAny.overlaps.add(range2.rangeName);
              }
            }
          }
        });
      });
      return range;
    }
    /**
     * @param {any[]} ser
     * @param {number} i
     */
    handleCandleStickBoxData(ser, i) {
      let ohlc = { o: [], h: [], m: [], l: [], c: [] };
      if (this.isFormat2DArray()) {
        ohlc = this.handleCandleStickBoxDataFormat("array", ser, i);
      } else if (this.isFormatXY()) {
        ohlc = this.handleCandleStickBoxDataFormat("xy", ser, i);
      }
      this.w.candleData.seriesCandleO[i] = ohlc.o;
      this.w.candleData.seriesCandleH[i] = ohlc.h;
      this.w.candleData.seriesCandleM[i] = ohlc.m;
      this.w.candleData.seriesCandleL[i] = ohlc.l;
      this.w.candleData.seriesCandleC[i] = ohlc.c;
      return ohlc;
    }
    /**
     * @param {string} format
     * @param {any[]} ser
     * @param {number} i
     */
    handleRangeDataFormat(format, ser, i) {
      const rangeStart = [];
      const rangeEnd = [];
      const uniqueKeysMap = /* @__PURE__ */ new Map();
      const uniqueKeys = [];
      ser[i].data.forEach((item) => {
        if (!uniqueKeysMap.has(item.x)) {
          const keyObj = {
            x: item.x,
            overlaps: /* @__PURE__ */ new Set(),
            y: []
          };
          uniqueKeysMap.set(item.x, keyObj);
          uniqueKeys.push(keyObj);
        }
      });
      if (format === "array") {
        for (let j = 0; j < ser[i].data.length; j++) {
          if (Array.isArray(ser[i].data[j])) {
            rangeStart.push(ser[i].data[j][1][0]);
            rangeEnd.push(ser[i].data[j][1][1]);
          } else {
            rangeStart.push(ser[i].data[j]);
            rangeEnd.push(ser[i].data[j]);
          }
        }
      } else if (format === "xy") {
        for (let j = 0; j < ser[i].data.length; j++) {
          const isDataPoint2D = Array.isArray(ser[i].data[j].y);
          const id = Utils$1.randomId();
          const x = ser[i].data[j].x;
          const y = {
            y1: isDataPoint2D ? ser[i].data[j].y[0] : ser[i].data[j].y,
            y2: isDataPoint2D ? ser[i].data[j].y[1] : ser[i].data[j].y,
            rangeName: id
          };
          ser[i].data[j].rangeName = id;
          const keyObj = uniqueKeysMap.get(x);
          if (keyObj) {
            keyObj.y.push(y);
          }
          rangeStart.push(y.y1);
          rangeEnd.push(y.y2);
        }
      }
      return {
        start: rangeStart,
        end: rangeEnd,
        rangeUniques: uniqueKeys
      };
    }
    /**
     * @param {string} format
     * @param {any[]} ser
     * @param {number} i
     */
    handleCandleStickBoxDataFormat(format, ser, i) {
      const w = this.w;
      const isBoxPlot = w.config.chart.type === "boxPlot" || /** @type {Record<string,any>} */
      w.config.series[i].type === "boxPlot";
      const serO = [];
      const serH = [];
      const serM = [];
      const serL = [];
      const serC = [];
      const data = ser[i].data;
      let getVals;
      if (format === "array") {
        const isFlat = isBoxPlot && data[0].length === 6 || !isBoxPlot && data[0].length === 5;
        if (isFlat) {
          getVals = (d) => d.slice(1);
        } else {
          getVals = (d) => Array.isArray(d[1]) ? d[1] : [];
        }
      } else {
        getVals = (d) => Array.isArray(d.y) ? d.y : [];
      }
      for (let j = 0; j < data.length; j++) {
        const vals = getVals(data[j]);
        if (vals && vals.length >= 2) {
          serO.push(vals[0]);
          serH.push(vals[1]);
          if (isBoxPlot) {
            serM.push(vals[2]);
            serL.push(vals[3]);
            serC.push(vals[4]);
          } else {
            serL.push(vals[2]);
            serC.push(vals[3]);
          }
        }
      }
      return {
        o: serO,
        h: serH,
        m: serM,
        l: serL,
        c: serC
      };
    }
    /**
     * @param {any[]} ser
     */
    parseDataAxisCharts(ser) {
      var _a, _b;
      const cnf = this.w.config;
      const gl = this.w.globals;
      const dt = new DateTime(this.w);
      const xlabels = cnf.labels.length > 0 ? cnf.labels.slice() : cnf.xaxis.categories.slice();
      this.w.axisFlags.isRangeBar = cnf.chart.type === "rangeBar" && gl.isBarHorizontal;
      this.w.labelData.hasXaxisGroups = cnf.xaxis.type === "category" && cnf.xaxis.group.groups.length > 0;
      if (this.w.labelData.hasXaxisGroups) {
        this.w.labelData.groups = cnf.xaxis.group.groups;
      }
      ser.forEach((s, i) => {
        if (s.name !== void 0) {
          this.w.seriesData.seriesNames.push(s.name);
        } else {
          this.w.seriesData.seriesNames.push(
            "series-" + parseInt(String(i + 1), 10)
          );
        }
      });
      this.coreUtils.setSeriesYAxisMappings();
      const buckets = [];
      const groups = [
        ...new Set(cnf.series.map((s) => s.group))
      ];
      cnf.series.forEach((s, i) => {
        const index = groups.indexOf(s.group);
        if (!buckets[index]) buckets[index] = [];
        buckets[index].push(this.w.seriesData.seriesNames[i]);
      });
      this.w.labelData.seriesGroups = buckets;
      const handleDates = () => {
        for (let j = 0; j < xlabels.length; j++) {
          if (typeof xlabels[j] === "string") {
            const isDate = dt.isValidDate(xlabels[j]);
            if (isDate) {
              this.twoDSeriesX.push(dt.parseDate(xlabels[j]));
            } else {
              throw new Error(
                "You have provided invalid Date format. Please provide a valid JavaScript Date"
              );
            }
          } else {
            this.twoDSeriesX.push(xlabels[j]);
          }
        }
      };
      for (let i = 0; i < ser.length; i++) {
        this.twoDSeries = [];
        this.twoDSeriesX = [];
        this.threeDSeries = [];
        if (typeof ser[i].data === "undefined") {
          console.error(
            "It is a possibility that you may have not included 'data' property in series."
          );
          return;
        }
        const dr = cnf.chart.dataReducer;
        if ((dr == null ? void 0 : dr.enabled) && this.isMultiFormat() && ser[i].data.length > ((_a = dr.threshold) != null ? _a : 500)) {
          ser[i] = __spreadProps(__spreadValues({}, ser[i]), {
            data: Data.lttbDownsample(ser[i].data, (_b = dr.targetPoints) != null ? _b : 250)
          });
        }
        if (cnf.chart.type === "rangeBar" || cnf.chart.type === "rangeArea" || ser[i].type === "rangeBar" || ser[i].type === "rangeArea") {
          this.w.axisFlags.isRangeData = true;
          this.handleRangeData(ser, i);
        }
        if (this.isMultiFormat()) {
          if (this.isFormat2DArray()) {
            this.handleFormat2DArray(ser, i);
          } else if (this.isFormatXY()) {
            this.handleFormatXY(ser, i);
          }
          if (cnf.chart.type === "candlestick" || ser[i].type === "candlestick" || cnf.chart.type === "boxPlot" || ser[i].type === "boxPlot") {
            this.handleCandleStickBoxData(ser, i);
          }
          this.w.seriesData.series.push(this.twoDSeries);
          this.w.labelData.labels.push(this.twoDSeriesX);
          this.w.seriesData.seriesX.push(this.twoDSeriesX);
          this.w.seriesData.seriesGoals = this.seriesGoals;
          if (i === this.activeSeriesIndex && !this.fallbackToCategory) {
            this.w.axisFlags.isXNumeric = true;
          }
        } else {
          if (cnf.xaxis.type === "datetime") {
            this.w.axisFlags.isXNumeric = true;
            handleDates();
            this.w.seriesData.seriesX.push(this.twoDSeriesX);
          } else if (cnf.xaxis.type === "numeric") {
            this.w.axisFlags.isXNumeric = true;
            if (xlabels.length > 0) {
              this.twoDSeriesX = xlabels;
              this.w.seriesData.seriesX.push(this.twoDSeriesX);
            }
          }
          this.w.labelData.labels.push(this.twoDSeriesX);
          const singleArray = ser[i].data.map(
            (d) => Utils$1.parseNumber(d)
          );
          this.w.seriesData.series.push(singleArray);
        }
        this.w.seriesData.seriesZ.push(this.threeDSeries);
        if (ser[i].color !== void 0) {
          this.w.seriesData.seriesColors.push(ser[i].color);
        } else {
          this.w.seriesData.seriesColors.push(
            /** @type {any} */
            void 0
          );
        }
      }
      return this.w;
    }
    /**
     * @param {any[]} ser
     */
    parseDataNonAxisCharts(ser) {
      const cnf = this.w.config;
      const hasOldFormat = Array.isArray(ser) && ser.every((s) => typeof s === "number") && cnf.labels.length > 0;
      const hasNewFormat = Array.isArray(ser) && ser.some(
        (s) => s && typeof s === "object" && s.data || s && typeof s === "object" && s.parsing
      );
      if (hasOldFormat && hasNewFormat) {
        console.warn(
          "ApexCharts: Both old format (numeric series + labels) and new format (series objects with data/parsing) detected. Using old format for backward compatibility."
        );
      }
      if (hasOldFormat) {
        this.w.seriesData.series = /** @type {any} */
        ser.slice();
        this.w.seriesData.seriesNames = cnf.labels.slice();
        for (let i = 0; i < this.w.seriesData.series.length; i++) {
          if (this.w.seriesData.seriesNames[i] === void 0) {
            this.w.seriesData.seriesNames.push("series-" + (i + 1));
          }
        }
        return this.w;
      }
      if (Array.isArray(ser) && ser.every((s) => typeof s === "number")) {
        this.w.seriesData.series = /** @type {any} */
        ser.slice();
        this.w.seriesData.seriesNames = [];
        for (let i = 0; i < this.w.seriesData.series.length; i++) {
          this.w.seriesData.seriesNames.push(cnf.labels[i] || `series-${i + 1}`);
        }
        return this.w;
      }
      const processedData = this.extractPieDataFromSeries(ser);
      this.w.seriesData.series = processedData.values;
      this.w.seriesData.seriesNames = processedData.labels;
      if (cnf.chart.type === "radialBar") {
        this.w.seriesData.series = this.w.seriesData.series.map((val) => {
          const numVal = Utils$1.parseNumber(val);
          if (numVal > 100) {
            console.warn(
              `ApexCharts: RadialBar value ${numVal} > 100, consider using percentage values (0-100)`
            );
          }
          return numVal;
        });
      }
      for (let i = 0; i < this.w.seriesData.series.length; i++) {
        if (this.w.seriesData.seriesNames[i] === void 0) {
          this.w.seriesData.seriesNames.push("series-" + (i + 1));
        }
      }
      return this.w;
    }
    /**
     * Reset parsing flags to allow re-parsing of data during updates
     */
    resetParsingFlags() {
      const w = this.w;
      w.axisFlags.dataWasParsed = false;
      w.globals.originalSeries = null;
      if (w.config.series) {
        w.config.series.forEach((serie) => {
          if (
            /** @type {any} */
            serie.__apexParsed
          ) {
            delete /** @type {any} */
            serie.__apexParsed;
          }
        });
      }
    }
    /**
     * @param {any[]} ser
     */
    extractPieDataFromSeries(ser) {
      const values = [];
      const labels = [];
      if (!Array.isArray(ser)) {
        console.warn("ApexCharts: Expected array for series data");
        return { values: [], labels: [] };
      }
      if (ser.length === 0) {
        console.warn("ApexCharts: Empty series array");
        return { values: [], labels: [] };
      }
      const firstItem = ser[0];
      if (typeof firstItem === "object" && firstItem !== null && firstItem.data) {
        this.extractPieDataFromSeriesObjects(ser, values, labels);
      } else {
        console.warn(
          "ApexCharts: Unsupported series format for pie/donut/radialBar. Expected series objects with data property."
        );
        return { values: [], labels: [] };
      }
      return { values, labels };
    }
    // Extract data from series objects: [{ data: [...], parsing: {...} }]
    /**
     * @param {any[]} seriesArray
     * @param {any[]} values
     * @param {any[]} labels
     */
    extractPieDataFromSeriesObjects(seriesArray, values, labels) {
      seriesArray.forEach((serie, serieIndex) => {
        if (!serie.data || !Array.isArray(serie.data)) {
          console.warn(`ApexCharts: Series ${serieIndex} has no valid data array`);
          return;
        }
        serie.data.forEach((dataPoint) => {
          if (typeof dataPoint === "object" && dataPoint !== null) {
            if (dataPoint.x !== void 0 && dataPoint.y !== void 0) {
              labels.push(String(dataPoint.x));
              values.push(Utils$1.parseNumber(dataPoint.y));
            } else {
              console.warn(
                "ApexCharts: Invalid data point format for pie chart. Expected {x, y} format:",
                dataPoint
              );
            }
          } else {
            console.warn(
              "ApexCharts: Expected object data point, got:",
              typeof dataPoint
            );
          }
        });
      });
    }
    /** User possibly set string categories in xaxis.categories or labels prop
     * Or didn't set xaxis labels at all - in which case we manually do it.
     * If user passed series data as [[3, 2], [4, 5]] or [{ x: 3, y: 55 }],
     * this shouldn't be called
     * @param {any[]} ser - the series which user passed to the config
     */
    handleExternalLabelsData(ser) {
      const cnf = this.w.config;
      if (cnf.xaxis.categories.length > 0) {
        this.w.labelData.labels = cnf.xaxis.categories;
      } else if (cnf.labels.length > 0) {
        this.w.labelData.labels = cnf.labels.slice();
      } else if (this.fallbackToCategory) {
        this.w.labelData.labels = /** @type {string[]} */
        /** @type {unknown} */
        this.w.labelData.labels[0];
        if (this.w.rangeData.seriesRange.length) {
          this.w.rangeData.seriesRange.map((srt) => {
            srt.forEach((sr) => {
              if (this.w.labelData.labels.indexOf(sr.x) < 0 && sr.x) {
                this.w.labelData.labels.push(sr.x);
              }
            });
          });
          const _labels = this.w.labelData.labels;
          if (_labels.length > 0 && (typeof _labels[0] === "number" || typeof _labels[0] === "string")) {
            this.w.labelData.labels = [...new Set(_labels)];
          } else {
            const _seen = /* @__PURE__ */ new Map();
            for (const _label of _labels) {
              const _key = JSON.stringify(_label);
              if (!_seen.has(_key)) _seen.set(_key, _label);
            }
            this.w.labelData.labels = Array.from(_seen.values());
          }
        }
        if (cnf.xaxis.convertedCatToNumeric) {
          const defaults = new Defaults(cnf);
          defaults.convertCatToNumericXaxis(cnf, this.w.seriesData.seriesX[0]);
          this._generateExternalLabels(ser);
        }
      } else {
        this._generateExternalLabels(ser);
      }
    }
    /**
     * @param {any[]} ser
     */
    _generateExternalLabels(ser) {
      const gl = this.w.globals;
      const cnf = this.w.config;
      let labelArr = [];
      if (gl.axisCharts) {
        if (this.w.seriesData.series.length > 0) {
          if (this.isFormatXY()) {
            const seriesDataFiltered = cnf.series.map(
              (serie) => {
                const seen = /* @__PURE__ */ new Map();
                for (const point of serie.data) {
                  if (!seen.has(point.x)) seen.set(point.x, point);
                }
                return Array.from(seen.values());
              }
            );
            const len = seriesDataFiltered.reduce(
              (p, c, i, a) => a[p].length > c.length ? p : i,
              0
            );
            for (let i = 0; i < seriesDataFiltered[len].length; i++) {
              labelArr.push(i + 1);
            }
          } else {
            for (let i = 0; i < this.w.seriesData.series[gl.maxValsInArrayIndex].length; i++) {
              labelArr.push(i + 1);
            }
          }
        }
        this.w.seriesData.seriesX = [];
        for (let i = 0; i < ser.length; i++) {
          this.w.seriesData.seriesX.push(labelArr);
        }
        if (!this.w.globals.isBarHorizontal) {
          this.w.axisFlags.isXNumeric = true;
        }
      }
      if (labelArr.length === 0) {
        labelArr = gl.axisCharts ? [] : (
          /**
           * @param {Record<string, any>} gls
           * @param {number} glsi
           */
          this.w.seriesData.series.map((gls, glsi) => {
            return glsi + 1;
          })
        );
        for (let i = 0; i < ser.length; i++) {
          this.w.seriesData.seriesX.push(labelArr);
        }
      }
      this.w.labelData.labels = /** @type {string[]} */
      /** @type {unknown} */
      labelArr;
      if (cnf.xaxis.convertedCatToNumeric) {
        this.w.labelData.categoryLabels = labelArr.map((l) => {
          return cnf.xaxis.labels.formatter(l);
        });
      }
      this.w.axisFlags.noLabelsProvided = true;
    }
    /**
     * @param {any[]} series
     */
    parseRawDataIfNeeded(series) {
      const cnf = this.w.config;
      const gl = this.w.globals;
      const globalParsing = cnf.parsing;
      if (this.w.axisFlags.dataWasParsed) {
        return series;
      }
      if (!globalParsing && !series.some((s) => s.parsing)) {
        return series;
      }
      const processedSeries = series.map((serie, index) => {
        var _a, _b, _c;
        if (!serie.data || !Array.isArray(serie.data) || serie.data.length === 0) {
          return serie;
        }
        const effectiveParsing = {
          x: ((_a = serie.parsing) == null ? void 0 : _a.x) || (globalParsing == null ? void 0 : globalParsing.x),
          y: ((_b = serie.parsing) == null ? void 0 : _b.y) || (globalParsing == null ? void 0 : globalParsing.y),
          z: ((_c = serie.parsing) == null ? void 0 : _c.z) || (globalParsing == null ? void 0 : globalParsing.z)
        };
        if (!effectiveParsing.x && !effectiveParsing.y) {
          return serie;
        }
        const firstDataPoint = serie.data[0];
        if (typeof firstDataPoint === "object" && firstDataPoint !== null && (Object.prototype.hasOwnProperty.call(firstDataPoint, "x") || Object.prototype.hasOwnProperty.call(firstDataPoint, "y")) || Array.isArray(firstDataPoint)) {
          return serie;
        }
        if (!effectiveParsing.x || !effectiveParsing.y || Array.isArray(effectiveParsing.y) && effectiveParsing.y.length === 0) {
          console.warn(
            `ApexCharts: Series ${index} has parsing config but missing x or y field specification`
          );
          return serie;
        }
        const transformedData = serie.data.map(
          (item, itemIndex) => {
            if (typeof item !== "object" || item === null) {
              console.warn(
                `ApexCharts: Series ${index}, data point ${itemIndex} is not an object, skipping parsing`
              );
              return item;
            }
            const x = this.getNestedValue(item, effectiveParsing.x);
            let y;
            let z = void 0;
            if (Array.isArray(effectiveParsing.y)) {
              const yValues = effectiveParsing.y.map(
                (fieldName) => this.getNestedValue(item, fieldName)
              );
              if (this.w.config.chart.type === "bubble") {
                if (yValues.length < 2) {
                  console.warn(
                    `ApexCharts: series[${index}] bubble chart requires parseData.y to have at least 2 fields (y and z). Got: ${JSON.stringify(effectiveParsing.y)}`
                  );
                }
                y = yValues[0];
              } else {
                y = yValues;
              }
            } else {
              y = this.getNestedValue(item, effectiveParsing.y);
            }
            if (effectiveParsing.z) {
              z = this.getNestedValue(item, effectiveParsing.z);
            }
            if (x === void 0) {
              console.warn(
                `ApexCharts: Series ${index}, data point ${itemIndex} missing field '${effectiveParsing.x}'`
              );
            }
            if (y === void 0) {
              console.warn(
                `ApexCharts: Series ${index}, data point ${itemIndex} missing field '${effectiveParsing.y}'`
              );
            }
            const result = { x, y, z: void 0 };
            if (this.w.config.chart.type === "bubble" && Array.isArray(effectiveParsing.y) && effectiveParsing.y.length === 2) {
              const zValue = this.getNestedValue(item, effectiveParsing.y[1]);
              if (zValue !== void 0) {
                result.z = zValue;
              }
            }
            if (z !== void 0) {
              result.z = z;
            }
            return result;
          }
        );
        return __spreadProps(__spreadValues({}, serie), {
          data: transformedData,
          __apexParsed: true
        });
      });
      this.w.axisFlags.dataWasParsed = true;
      if (!gl.originalSeries) {
        gl.originalSeries = Utils$1.clone(series);
      }
      return processedSeries;
    }
    /**
     * Get nested object value using dot notation path
     * @param {Object} obj - The object to search in
     * @param {string} path - Dot notation path (e.g., 'user.profile.name')
     * @returns {*} The value at the path, or undefined if not found
     */
    getNestedValue(obj, path) {
      if (!obj || typeof obj !== "object" || !path) {
        return void 0;
      }
      if (path.indexOf(".") === -1) {
        return (
          /** @type {any} */
          obj[path]
        );
      }
      const keys = path.split(".");
      let current = obj;
      for (let i = 0; i < keys.length; i++) {
        if (current === null || current === void 0 || typeof current !== "object") {
          return void 0;
        }
        current = /** @type {any} */
        current[keys[i]];
      }
      return current;
    }
    // Segregate user provided data into appropriate vars
    /**
     * @param {any[]} ser
     */
    parseData(ser) {
      const w = this.w;
      const cnf = w.config;
      const gl = w.globals;
      ser = this.parseRawDataIfNeeded(ser);
      cnf.series = ser;
      gl.initialSeries = Utils$1.clone(ser);
      this.excludeCollapsedSeriesInYAxis();
      this.fallbackToCategory = false;
      this.resetGlobals();
      this.isMultipleY();
      if (gl.axisCharts) {
        this.parseDataAxisCharts(ser);
        this.coreUtils.getLargestSeries();
      } else {
        this.parseDataNonAxisCharts(ser);
      }
      if (cnf.chart.stacked) {
        const series = new Series(this.w);
        this.w.seriesData.series = series.setNullSeriesToZeroValues(
          this.w.seriesData.series
        );
      }
      this.coreUtils.getSeriesTotals();
      if (gl.axisCharts) {
        this.w.seriesData.stackedSeriesTotals = this.coreUtils.getStackedSeriesTotals();
        this.w.seriesData.stackedSeriesTotalsByGroups = this.coreUtils.getStackedSeriesTotalsByGroups();
      }
      this.coreUtils.getPercentSeries();
      if (!this.w.axisFlags.dataFormatXNumeric && (!this.w.axisFlags.isXNumeric || cnf.xaxis.type === "numeric" && cnf.labels.length === 0 && cnf.xaxis.categories.length === 0)) {
        this.handleExternalLabelsData(ser);
      }
      const catLabels = this.coreUtils.getCategoryLabels(this.w.labelData.labels);
      for (let l = 0; l < catLabels.length; l++) {
        if (Array.isArray(catLabels[l])) {
          this.w.axisFlags.isMultiLineX = true;
          break;
        }
      }
      return {
        // w.seriesData (future slice)
        seriesData: {
          series: this.w.seriesData.series,
          seriesNames: this.w.seriesData.seriesNames,
          seriesX: this.w.seriesData.seriesX,
          seriesZ: this.w.seriesData.seriesZ,
          seriesColors: this.w.seriesData.seriesColors,
          seriesGoals: this.w.seriesData.seriesGoals,
          initialSeries: gl.initialSeries,
          originalSeries: gl.originalSeries,
          stackedSeriesTotals: this.w.seriesData.stackedSeriesTotals,
          stackedSeriesTotalsByGroups: this.w.seriesData.stackedSeriesTotalsByGroups,
          noLabelsProvided: this.w.axisFlags.noLabelsProvided
        },
        // w.rangeData (future slice)
        rangeData: {
          seriesRangeStart: this.w.rangeData.seriesRangeStart,
          seriesRangeEnd: this.w.rangeData.seriesRangeEnd,
          seriesRange: this.w.rangeData.seriesRange
        },
        // w.candleData (future slice)
        candleData: {
          seriesCandleO: this.w.candleData.seriesCandleO,
          seriesCandleH: this.w.candleData.seriesCandleH,
          seriesCandleM: this.w.candleData.seriesCandleM,
          seriesCandleL: this.w.candleData.seriesCandleL,
          seriesCandleC: this.w.candleData.seriesCandleC
        },
        // w.labelData (future slice)
        labelData: {
          labels: this.w.labelData.labels,
          categoryLabels: this.w.labelData.categoryLabels
        },
        // w.axisFlags (future slice)
        axisFlags: {
          isXNumeric: this.w.axisFlags.isXNumeric,
          dataFormatXNumeric: this.w.axisFlags.dataFormatXNumeric,
          isDataXYZ: this.w.axisFlags.isDataXYZ,
          isRangeData: this.w.axisFlags.isRangeData,
          isRangeBar: this.w.axisFlags.isRangeBar,
          isMultiLineX: this.w.axisFlags.isMultiLineX,
          dataWasParsed: this.w.axisFlags.dataWasParsed,
          hasXaxisGroups: this.w.labelData.hasXaxisGroups,
          groups: this.w.labelData.groups,
          seriesGroups: this.w.labelData.seriesGroups
        }
      };
    }
    /**
     * Largest-Triangle-Three-Bucket (LTTB) downsampling.
     *
     * Reduces `data` to `targetPoints` points while preserving the visual shape
     * of the series as perceived by the human eye.
     *
     * @param {any[]} data   - Raw series data in [{x,y}] or [[x,y]] format.
     * @param {number} targetPoints - Desired output length (>= 3).
     * @returns {any[]} Downsampled array in the same format as the input.
     */
    static lttbDownsample(data, targetPoints) {
      const len = data.length;
      if (targetPoints >= len || targetPoints < 3) return data;
      const isXY = !Array.isArray(data[0]);
      const getX = isXY ? (p) => p.x : (p) => p[0];
      const getY = isXY ? (p) => p.y : (p) => p[1];
      const sampled = [];
      sampled.push(data[0]);
      const bucketSize = (len - 2) / (targetPoints - 2);
      let a = 0;
      for (let i = 0; i < targetPoints - 2; i++) {
        const avgRangeStart = Math.floor((i + 1) * bucketSize) + 1;
        const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketSize) + 1, len);
        let avgX = 0;
        let avgY = 0;
        const avgRangeLen = avgRangeEnd - avgRangeStart;
        for (let j = avgRangeStart; j < avgRangeEnd; j++) {
          avgX += getX(data[j]);
          avgY += getY(data[j]);
        }
        avgX /= avgRangeLen;
        avgY /= avgRangeLen;
        const rangeStart = Math.floor(i * bucketSize) + 1;
        const rangeEnd = Math.min(Math.floor((i + 1) * bucketSize) + 1, len);
        const pointAX = getX(data[a]);
        const pointAY = getY(data[a]);
        let maxArea = -1;
        let maxAreaIdx = rangeStart;
        for (let j = rangeStart; j < rangeEnd; j++) {
          const area = Math.abs(
            (pointAX - avgX) * (getY(data[j]) - pointAY) - (pointAX - getX(data[j])) * (avgY - pointAY)
          ) * 0.5;
          if (area > maxArea) {
            maxArea = area;
            maxAreaIdx = j;
          }
        }
        sampled.push(data[maxAreaIdx]);
        a = maxAreaIdx;
      }
      sampled.push(data[len - 1]);
      return sampled;
    }
    excludeCollapsedSeriesInYAxis() {
      const w = this.w;
      const yAxisIndexes = [];
      w.globals.seriesYAxisMap.forEach((yAxisArr, yi) => {
        let collapsedCount = 0;
        yAxisArr.forEach((seriesIndex) => {
          if (w.globals.collapsedSeriesIndices.indexOf(seriesIndex) !== -1) {
            collapsedCount++;
          }
        });
        if (collapsedCount > 0 && collapsedCount == yAxisArr.length) {
          yAxisIndexes.push(yi);
        }
      });
      w.globals.ignoreYAxisIndexes = yAxisIndexes.map((x) => x);
    }
  }
  class UpdateHelpers {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
    }
    /**
     * private method to update Options.
     *
     * @param {Record<string, any>} options - A new config object can be passed which will be merged with the existing config object
     * @param {boolean} redraw - should redraw from beginning or should use existing paths and redraw from there
     * @param {boolean} animate - should animate or not on updating Options
     * @param {boolean} overwriteInitialConfig - should update the initial config or not
     */
    _updateOptions(options2, redraw = false, animate = true, updateSyncedCharts = true, overwriteInitialConfig = false) {
      return new Promise((resolve) => {
        let charts = [this.ctx];
        if (updateSyncedCharts) {
          charts = this.ctx.getSyncedCharts();
        }
        if (this.w.globals.isExecCalled) {
          charts = [this.ctx];
          this.w.globals.isExecCalled = false;
        }
        charts.forEach((ch, chartIndex) => {
          const w = ch.w;
          w.globals.shouldAnimate = animate;
          if (!redraw) {
            w.globals.resized = true;
            w.globals.dataChanged = true;
            if (animate) {
              ch.series.getPreviousPaths();
            }
          }
          if (options2 && typeof options2 === "object") {
            ch.config = new Config(options2);
            options2 = CoreUtils.extendArrayProps(ch.config, options2, w);
            if (ch.w.globals.chartID !== this.w.globals.chartID) {
              delete options2.series;
            }
            w.config = Utils$1.extend(w.config, options2);
            if (overwriteInitialConfig) {
              w.globals.lastXAxis = options2.xaxis ? Utils$1.clone(options2.xaxis) : [];
              w.globals.lastYAxis = options2.yaxis ? Utils$1.clone(options2.yaxis) : [];
              w.globals.initialConfig = Utils$1.extend({}, w.config);
              w.globals.initialSeries = Utils$1.clone(w.config.series);
              if (options2.series) {
                for (let i = 0; i < w.globals.collapsedSeriesIndices.length; i++) {
                  const series = w.config.series[w.globals.collapsedSeriesIndices[i]];
                  w.globals.collapsedSeries[i].data = w.globals.axisCharts ? (
                    /** @type {any} */
                    series.data.slice()
                  ) : series;
                }
                for (let i = 0; i < w.globals.ancillaryCollapsedSeriesIndices.length; i++) {
                  const series = w.config.series[w.globals.ancillaryCollapsedSeriesIndices[i]];
                  w.globals.ancillaryCollapsedSeries[i].data = w.globals.axisCharts ? (
                    /** @type {any} */
                    series.data.slice()
                  ) : series;
                }
                ch.series.emptyCollapsedSeries(w.config.series);
              }
            }
          }
          return ch.update(options2).then(() => {
            if (chartIndex === charts.length - 1) {
              resolve(ch);
            }
          });
        });
      });
    }
    /**
     * Private method to update Series.
     *
     * @param {any[]} newSeries - New series which will override the existing
     * @param {boolean} animate
     */
    _updateSeries(newSeries, animate, overwriteInitialSeries = false) {
      return new Promise((resolve) => {
        const w = this.w;
        w.globals.shouldAnimate = animate;
        w.globals.dataChanged = true;
        PerformanceCache.invalidateSelectors(w);
        if (animate) {
          this.ctx.series.getPreviousPaths();
        }
        const prevSeriesCount = w.config.series.length;
        this.ctx.data.resetParsingFlags();
        const parsedState = this.ctx.data.parseData(newSeries);
        this.ctx._writeParsedSeriesData(parsedState.seriesData);
        this.ctx._writeParsedRangeData(parsedState.rangeData);
        this.ctx._writeParsedCandleData(parsedState.candleData);
        this.ctx._writeParsedLabelData(parsedState.labelData);
        this.ctx._writeParsedAxisFlags(parsedState.axisFlags);
        if (overwriteInitialSeries) {
          if (w.globals.initialConfig) {
            w.globals.initialConfig.series = Utils$1.clone(w.config.series);
          }
          w.globals.initialSeries = Utils$1.clone(w.config.series);
        }
        if (this._canUseFastPath(newSeries, prevSeriesCount, w)) {
          return this.ctx.fastUpdate(animate).then(() => {
            resolve(this.ctx);
          });
        }
        return this.ctx.update().then(() => {
          resolve(this.ctx);
        });
      });
    }
    /**
     * Returns true if the data-only fast path can be used for this update.
     * Fast path skips rebuilding grid, axes, legend, annotations, and tooltip DOM.
     *
     * Requirements:
     * - Chart has been fully rendered (DOM exists)
     * - Axis chart (non-axis charts like pie always need full rebuild due to radial layout)
     * - Series count unchanged (grid column/row counts depend on it)
     * - No series currently collapsing (collapsed series changes visible data range)
     * - Not a combo chart (combo charts mix types and need coordinated axis recalc)
     * - Not currently zoomed (zoomed charts have altered x-labels that need recalculation)
     * @param {any[]} newSeries
     * @param {number} prevSeriesCount
     * @param {import('../../types/internal').ChartStateW} w
     */
    _canUseFastPath(newSeries, prevSeriesCount, w) {
      if (!w.dom.elGraphical) return false;
      if (!w.globals.axisCharts) return false;
      if (newSeries.length !== prevSeriesCount) return false;
      if (w.globals.collapsedSeries.length > 0) return false;
      if (w.globals.ancillaryCollapsedSeries.length > 0) return false;
      if (w.globals.risingSeries.length > 0) return false;
      if (w.globals.comboCharts) return false;
      if (w.interact.zoomed) return false;
      return true;
    }
    /**
     * @param {any} s
     * @param {number} i
     */
    _extendSeries(s, i) {
      const w = this.w;
      const ser = w.config.series[i];
      return __spreadProps(__spreadValues(
        {},
        /** @type {Record<string,any>} */
        w.config.series[i]
      ), {
        name: s.name ? s.name : (
          /** @type {any} */
          ser == null ? void 0 : ser.name
        ),
        color: s.color ? s.color : (
          /** @type {any} */
          ser == null ? void 0 : ser.color
        ),
        type: s.type ? s.type : (
          /** @type {any} */
          ser == null ? void 0 : ser.type
        ),
        group: s.group ? s.group : (
          /** @type {any} */
          ser == null ? void 0 : ser.group
        ),
        hidden: typeof s.hidden !== "undefined" ? s.hidden : (
          /** @type {any} */
          ser == null ? void 0 : ser.hidden
        ),
        data: s.data ? s.data : (
          /** @type {any} */
          ser == null ? void 0 : ser.data
        ),
        zIndex: typeof s.zIndex !== "undefined" ? s.zIndex : i
      });
    }
    /**
     * @param {number} seriesIndex
     * @param {number} dataPointIndex
     */
    toggleDataPointSelection(seriesIndex, dataPointIndex) {
      const w = this.w;
      let elPath = null;
      const parent = `.apexcharts-series[data\\:realIndex='${seriesIndex}']`;
      if (w.globals.axisCharts) {
        elPath = w.dom.Paper.findOne(
          `${parent} path[j='${dataPointIndex}'], ${parent} circle[j='${dataPointIndex}'], ${parent} rect[j='${dataPointIndex}']`
        );
      } else {
        if (typeof dataPointIndex === "undefined") {
          elPath = w.dom.Paper.findOne(`${parent} path[j='${seriesIndex}']`);
          if (w.config.chart.type === "pie" || w.config.chart.type === "polarArea" || w.config.chart.type === "donut") {
            this.ctx.pie.pieClicked(seriesIndex);
          }
        }
      }
      if (elPath) {
        const graphics = new Graphics(this.w);
        graphics.pathMouseDown(
          elPath,
          /** @type {any} */
          null
        );
      } else {
        console.warn("toggleDataPointSelection: Element not found");
        return null;
      }
      return elPath.node ? elPath.node : null;
    }
    /**
     * @param {Record<string, any>} options
     */
    forceXAxisUpdate(options2) {
      const w = this.w;
      const minmax = ["min", "max"];
      minmax.forEach((a) => {
        if (typeof options2.xaxis[a] !== "undefined") {
          w.config.xaxis[a] = options2.xaxis[a];
          w.globals.lastXAxis[a] = options2.xaxis[a];
        }
      });
      if (options2.xaxis.categories && options2.xaxis.categories.length) {
        w.config.xaxis.categories = options2.xaxis.categories;
      }
      if (w.config.xaxis.convertedCatToNumeric) {
        const defaults = new Defaults(options2);
        options2 = defaults.convertCatToNumericXaxis(options2, this.ctx);
      }
      return options2;
    }
    /**
     * @param {Record<string, any>} options
     */
    forceYAxisUpdate(options2) {
      if (options2.chart && options2.chart.stacked && options2.chart.stackType === "100%") {
        if (Array.isArray(options2.yaxis)) {
          options2.yaxis.forEach(
            (yaxe, index) => {
              options2.yaxis[index].min = 0;
              options2.yaxis[index].max = 100;
            }
          );
        } else {
          options2.yaxis.min = 0;
          options2.yaxis.max = 100;
        }
      }
      return options2;
    }
    /**
     * This function reverts the yaxis and xaxis min/max values to what it was when the chart was defined.
     * This function fixes an important bug where a user might load a new series after zooming in/out of previous series which resulted in wrong min/max
     * Also, this should never be called internally on zoom/pan - the reset should only happen when user calls the updateSeries() function externally
     * The function also accepts an object {xaxis, yaxis} which when present is set as the new xaxis/yaxis
     * @param {Record<string, any>} opts
     */
    revertDefaultAxisMinMax(opts) {
      const w = this.w;
      let xaxis = w.globals.lastXAxis;
      let yaxis = w.globals.lastYAxis;
      if (opts && opts.xaxis) {
        xaxis = opts.xaxis;
      }
      if (opts && opts.yaxis) {
        yaxis = opts.yaxis;
      }
      const _xaxis = (
        /** @type {any} */
        xaxis
      );
      w.config.xaxis.min = _xaxis.min;
      w.config.xaxis.max = _xaxis.max;
      const getLastYAxis = (index) => {
        if (typeof yaxis[index] !== "undefined") {
          const _y = (
            /** @type {any} */
            yaxis[index]
          );
          w.config.yaxis[index].min = _y.min;
          w.config.yaxis[index].max = _y.max;
        }
      };
      w.config.yaxis.map((yaxe, index) => {
        if (w.interact.zoomed) {
          getLastYAxis(index);
        } else {
          if (typeof yaxis[index] !== "undefined") {
            getLastYAxis(index);
          } else {
            if (typeof this.ctx.opts.yaxis[index] !== "undefined") {
              yaxe.min = this.ctx.opts.yaxis[index].min;
              yaxe.max = this.ctx.opts.yaxis[index].max;
            }
          }
        }
      });
    }
  }
  class Utils {
    /**
     * @param {import('./Tooltip').default} tooltipContext
     */
    constructor(tooltipContext) {
      this.w = tooltipContext.w;
      this.ttCtx = tooltipContext;
    }
    /**
     ** When hovering over series, you need to capture which series is being hovered on.
     ** This function will return both capturedseries index as well as inner index of that series
     * @memberof Utils
     * @param {{ hoverArea: any, elGrid: any, clientX: any, clientY: any, context?: any }} opts
     */
    getNearestValues({ hoverArea, elGrid, clientX, clientY }) {
      var _a, _b;
      const w = this.w;
      const seriesBound = elGrid.getBoundingClientRect();
      const hoverWidth = seriesBound.width;
      const hoverHeight = seriesBound.height;
      let xDivisor = hoverWidth / (w.globals.dataPoints - 1);
      const yDivisor = hoverHeight / w.globals.dataPoints;
      const hasBars = this.hasBars();
      if ((w.globals.comboCharts || hasBars) && !w.config.xaxis.convertedCatToNumeric) {
        xDivisor = hoverWidth / w.globals.dataPoints;
      }
      const hoverX = clientX - seriesBound.left - w.globals.barPadForNumericAxis;
      const hoverY = clientY - seriesBound.top;
      const notInRect = hoverX < 0 || hoverY < 0 || hoverX > hoverWidth || hoverY > hoverHeight;
      if (notInRect) {
        hoverArea.classList.remove("hovering-zoom");
        hoverArea.classList.remove("hovering-pan");
      } else {
        if (w.interact.zoomEnabled) {
          hoverArea.classList.remove("hovering-pan");
          hoverArea.classList.add("hovering-zoom");
        } else if (w.interact.panEnabled) {
          hoverArea.classList.remove("hovering-zoom");
          hoverArea.classList.add("hovering-pan");
        }
      }
      let j = Math.round(hoverX / xDivisor);
      const jHorz = Math.floor(hoverY / yDivisor);
      if (hasBars && !w.config.xaxis.convertedCatToNumeric) {
        j = Math.ceil(hoverX / xDivisor);
        j = j - 1;
      }
      let capturedSeries = null;
      let closest = null;
      let seriesXValArr = w.globals.seriesXvalues.map(
        (seriesXVal) => {
          return seriesXVal.filter(
            (s) => Utils$1.isNumber(s)
          );
        }
      );
      const seriesYValArr = w.globals.seriesYvalues.map(
        (seriesYVal) => {
          return seriesYVal.filter(
            (s) => Utils$1.isNumber(s)
          );
        }
      );
      if (w.axisFlags.isXNumeric) {
        const chartGridEl = this.ttCtx.getElGrid();
        if (!chartGridEl) return { hoverX, hoverY };
        const chartGridElBoundingRect = chartGridEl.getBoundingClientRect();
        const transformedHoverX = hoverX * (chartGridElBoundingRect.width / hoverWidth);
        const transformedHoverY = hoverY * (chartGridElBoundingRect.height / hoverHeight);
        closest = this.closestInMultiArray(
          transformedHoverX,
          transformedHoverY,
          seriesXValArr,
          seriesYValArr
        );
        capturedSeries = closest.index;
        j = (_a = closest.j) != null ? _a : 0;
        if (capturedSeries !== null && w.globals.hasNullValues) {
          seriesXValArr = w.globals.seriesXvalues[capturedSeries];
          closest = this.closestInArray(transformedHoverX, seriesXValArr);
          j = (_b = closest.j) != null ? _b : 0;
        }
      }
      w.interact.capturedSeriesIndex = capturedSeries === null ? -1 : capturedSeries;
      if (!j || j < 1) j = 0;
      if (w.globals.isBarHorizontal) {
        w.interact.capturedDataPointIndex = jHorz;
      } else {
        w.interact.capturedDataPointIndex = j;
      }
      return {
        capturedSeries,
        j: w.globals.isBarHorizontal ? jHorz : j,
        hoverX,
        hoverY
      };
    }
    /**
     * @param {any[]} Xarrays
     */
    getFirstActiveXArray(Xarrays) {
      const w = this.w;
      let activeIndex = 0;
      const firstActiveSeriesIndex = Xarrays.map(
        (xarr, index) => {
          return xarr.length > 0 ? index : -1;
        }
      );
      for (let a = 0; a < firstActiveSeriesIndex.length; a++) {
        if (firstActiveSeriesIndex[a] !== -1 && w.globals.collapsedSeriesIndices.indexOf(a) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(a) === -1) {
          activeIndex = firstActiveSeriesIndex[a];
          break;
        }
      }
      return activeIndex;
    }
    /**
     * @param {number} hoverX
     * @param {number} hoverY
     * @param {any[]} Xarrays
     * @param {any[]} Yarrays
     */
    closestInMultiArray(hoverX, hoverY, Xarrays, Yarrays) {
      const w = this.w;
      const isActiveSeries = (seriesIndex) => {
        return w.globals.collapsedSeriesIndices.indexOf(seriesIndex) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(seriesIndex) === -1;
      };
      let closestDist = Infinity;
      let closestSeriesIndex = null;
      let closestPointIndex = null;
      for (let i = 0; i < Xarrays.length; i++) {
        if (!isActiveSeries(i)) {
          continue;
        }
        const xArr = Xarrays[i];
        const yArr = Yarrays[i];
        const len = Math.min(xArr.length, yArr.length);
        for (let j = 0; j < len; j++) {
          const xVal = xArr[j];
          const distX = hoverX - xVal;
          let dist = Math.sqrt(distX * distX);
          if (!w.globals.allSeriesHasEqualX) {
            const yVal = yArr[j];
            const distY = hoverY - yVal;
            dist = Math.sqrt(distX * distX + distY * distY);
          }
          if (dist < closestDist) {
            closestDist = dist;
            closestSeriesIndex = i;
            closestPointIndex = j;
          }
        }
      }
      return {
        index: closestSeriesIndex,
        j: closestPointIndex
      };
    }
    /**
     * @param {number} val
     * @param {any[]} arr
     */
    closestInArray(val, arr) {
      const curr = arr[0];
      let currIndex = null;
      let diff = Math.abs(val - curr);
      for (let i = 0; i < arr.length; i++) {
        const newdiff = Math.abs(val - arr[i]);
        if (newdiff < diff) {
          diff = newdiff;
          currIndex = i;
        }
      }
      return {
        j: currIndex
      };
    }
    /**
     * When there are multiple series, it is possible to have different x values for each series.
     * But it may be possible in those multiple series, that there is same x value for 2 or more
     * series.
     * @memberof Utils
     * @param {number} j - the inner index of series (series[i][j])
     * @return {boolean}
     */
    isXoverlap(j) {
      const w = this.w;
      const xSameForAllSeriesJArr = [];
      const seriesX = w.seriesData.seriesX.filter(
        (s) => typeof s[0] !== "undefined"
      );
      if (seriesX.length > 0) {
        for (let i = 0; i < seriesX.length - 1; i++) {
          if (typeof seriesX[i][j] !== "undefined" && typeof seriesX[i + 1][j] !== "undefined") {
            if (seriesX[i][j] !== seriesX[i + 1][j]) {
              xSameForAllSeriesJArr.push("unEqual");
            }
          }
        }
      }
      if (xSameForAllSeriesJArr.length === 0) {
        return true;
      }
      return false;
    }
    isInitialSeriesSameLen() {
      var _a, _b, _c;
      let sameLen = true;
      const initialSeries = (
        /** @type {any[]} */
        ((_a = this.w.globals.initialSeries) == null ? void 0 : _a.filter(
          /**
           * @param {Record<string, any>} s
           * @param {number} i
           */
          (s, i) => {
            var _a2;
            return !((_a2 = this.w.globals.collapsedSeriesIndices) == null ? void 0 : _a2.includes(i));
          }
        )) || []
      );
      for (let i = 0; i < initialSeries.length - 1; i++) {
        if (!((_b = initialSeries[i]) == null ? void 0 : _b.data) || !((_c = initialSeries[i + 1]) == null ? void 0 : _c.data)) return true;
        if (initialSeries[i].data.length !== initialSeries[i + 1].data.length) {
          sameLen = false;
          break;
        }
      }
      return sameLen;
    }
    /**
     * @param {any[]} allbars
     */
    getBarsHeight(allbars) {
      const bars = [...allbars];
      const totalHeight = bars.reduce((acc, bar) => acc + bar.getBBox().height, 0);
      return totalHeight;
    }
    /**
     * @param {number} capturedSeries
     */
    getElMarkers(capturedSeries) {
      if (typeof capturedSeries == "number") {
        return this.w.dom.baseEl.querySelectorAll(
          `.apexcharts-series[data\\:realIndex='${capturedSeries}'] .apexcharts-series-markers-wrap > *`
        );
      }
      return this.w.dom.baseEl.querySelectorAll(
        ".apexcharts-series-markers-wrap > *"
      );
    }
    getAllMarkers(filterCollapsed = false) {
      let markersWraps = (
        /** @type {any[]} */
        [
          ...this.w.dom.baseEl.querySelectorAll(".apexcharts-series-markers-wrap")
        ]
      );
      if (filterCollapsed) {
        markersWraps = markersWraps.filter((m) => {
          const realIndex = Number(m.getAttribute("data:realIndex"));
          return this.w.globals.collapsedSeriesIndices.indexOf(realIndex) === -1;
        });
      }
      markersWraps.sort((a, b) => {
        var indexA = Number(a.getAttribute("data:realIndex"));
        var indexB = Number(b.getAttribute("data:realIndex"));
        return indexB < indexA ? 1 : indexB > indexA ? -1 : 0;
      });
      const markers = [];
      markersWraps.forEach((m) => {
        markers.push(m.querySelector(".apexcharts-marker"));
      });
      return markers;
    }
    /**
     * @param {number} capturedSeries
     */
    hasMarkers(capturedSeries) {
      const markers = this.getElMarkers(capturedSeries);
      return markers.length > 0;
    }
    /**
     * @param {any} point
     * @param {number} size
     */
    getPathFromPoint(point, size) {
      const cx = Number(point.getAttribute("cx"));
      const cy = Number(point.getAttribute("cy"));
      const shape = point.getAttribute("shape");
      return new Graphics(this.w).getMarkerPath(cx, cy, shape, size);
    }
    getElBars() {
      return this.w.dom.baseEl.querySelectorAll(
        ".apexcharts-bar-series,  .apexcharts-candlestick-series, .apexcharts-boxPlot-series, .apexcharts-rangebar-series"
      );
    }
    hasBars() {
      const bars = this.getElBars();
      return bars.length > 0;
    }
    /**
     * @param {number} index
     */
    getHoverMarkerSize(index) {
      const w = this.w;
      let hoverSize = w.config.markers.hover.size;
      if (hoverSize === void 0) {
        hoverSize = w.globals.markers.size[index] + w.config.markers.hover.sizeOffset;
      }
      return hoverSize;
    }
    /**
     * @param {string} state
     */
    toggleAllTooltipSeriesGroups(state) {
      const w = this.w;
      const ttCtx = this.ttCtx;
      if (ttCtx.allTooltipSeriesGroups.length === 0) {
        ttCtx.allTooltipSeriesGroups = w.dom.baseEl.querySelectorAll(
          ".apexcharts-tooltip-series-group"
        );
      }
      const allTooltipSeriesGroups = ttCtx.allTooltipSeriesGroups;
      for (let i = 0; i < allTooltipSeriesGroups.length; i++) {
        if (state === "enable") {
          allTooltipSeriesGroups[i].classList.add("apexcharts-active");
          allTooltipSeriesGroups[i].style.display = w.config.tooltip.items.display;
        } else {
          allTooltipSeriesGroups[i].classList.remove("apexcharts-active");
          allTooltipSeriesGroups[i].style.display = "none";
        }
      }
    }
  }
  class Labels {
    /**
     * @param {import('./Tooltip').default} tooltipContext
     */
    constructor(tooltipContext) {
      this.w = tooltipContext.w;
      this.ttCtx = tooltipContext;
      this.tooltipUtil = new Utils(tooltipContext);
    }
    /** @param {{ shared?: boolean, ttItems?: any, i?: number, j?: any, y1?: any, y2?: any, e?: any }} opts */
    drawSeriesTexts({ shared = true, ttItems, i = 0, j = null, y1, y2, e }) {
      const w = this.w;
      if (w.config.tooltip.custom !== void 0) {
        this.handleCustomTooltip({ i, j, y1, y2, w });
      } else {
        this.toggleActiveInactiveSeries(shared, i);
      }
      const values = this.getValuesToPrint({
        i,
        j
      });
      this.printLabels({
        i,
        j,
        values,
        ttItems,
        shared,
        e
      });
      const tooltipEl = this.ttCtx.getElTooltip();
      if (tooltipEl) {
        this.ttCtx.tooltipRect.ttWidth = tooltipEl.getBoundingClientRect().width;
        this.ttCtx.tooltipRect.ttHeight = tooltipEl.getBoundingClientRect().height;
      }
    }
    /** @param {{i: any, j: any, values: any, ttItems: any, shared: any, e: any}} opts */
    printLabels({ i, j, values, ttItems, shared, e }) {
      var _a;
      const w = this.w;
      let val;
      let goalVals = (
        /** @type {any[]} */
        []
      );
      const hasGoalValues = (gi) => {
        return w.seriesData.seriesGoals[gi] && w.seriesData.seriesGoals[gi][j] && Array.isArray(w.seriesData.seriesGoals[gi][j]);
      };
      const { xVal, zVal, xAxisTTVal } = values;
      let seriesName = "";
      let pColor = w.globals.colors[i];
      if (j !== null && w.config.plotOptions.bar.distributed) {
        pColor = w.globals.colors[j];
      }
      for (let t = 0, inverset = w.seriesData.series.length - 1; t < w.seriesData.series.length; t++, inverset--) {
        let f = this.getFormatters(i);
        seriesName = this.getSeriesName({
          fn: f.yLbTitleFormatter,
          index: i,
          seriesIndex: i,
          j
        });
        if (w.config.chart.type === "treemap") {
          seriesName = f.yLbTitleFormatter(
            String(
              /** @type {any} */
              w.config.series[i].data[j].x
            ),
            {
              series: w.seriesData.series,
              seriesIndex: i,
              dataPointIndex: j,
              w
            }
          );
        }
        const tIndex = w.config.tooltip.inverseOrder ? inverset : t;
        if (w.globals.axisCharts) {
          const getValBySeriesIndex = (index) => {
            var _a2, _b, _c, _d;
            if (w.axisFlags.isRangeData) {
              return f.yLbFormatter((_b = (_a2 = w.rangeData.seriesRangeStart) == null ? void 0 : _a2[index]) == null ? void 0 : _b[j], {
                series: w.rangeData.seriesRangeStart,
                seriesIndex: index,
                dataPointIndex: j,
                w
              }) + " - " + f.yLbFormatter((_d = (_c = w.rangeData.seriesRangeEnd) == null ? void 0 : _c[index]) == null ? void 0 : _d[j], {
                series: w.rangeData.seriesRangeEnd,
                seriesIndex: index,
                dataPointIndex: j,
                w
              });
            }
            return f.yLbFormatter(w.seriesData.series[index][j], {
              series: w.seriesData.series,
              seriesIndex: index,
              dataPointIndex: j,
              w
            });
          };
          if (shared) {
            f = this.getFormatters(tIndex);
            seriesName = this.getSeriesName({
              fn: f.yLbTitleFormatter,
              index: tIndex,
              seriesIndex: i,
              j
            });
            pColor = w.globals.colors[tIndex];
            val = getValBySeriesIndex(tIndex);
            if (hasGoalValues(tIndex)) {
              goalVals = w.seriesData.seriesGoals[tIndex][j].map(
                (goal) => {
                  return {
                    attrs: goal,
                    val: f.yLbFormatter(goal.value, {
                      seriesIndex: tIndex,
                      dataPointIndex: j,
                      w
                    })
                  };
                }
              );
            }
          } else {
            const targetFill = (_a = e == null ? void 0 : e.target) == null ? void 0 : _a.getAttribute("fill");
            if (targetFill) {
              if (targetFill.indexOf("url") !== -1) {
                if (targetFill.indexOf("Pattern") !== -1) {
                  pColor = w.dom.baseEl.querySelector(targetFill.substr(4).slice(0, -1)).childNodes[0].getAttribute("stroke");
                }
              } else {
                pColor = targetFill;
              }
            }
            val = getValBySeriesIndex(i);
            if (hasGoalValues(i) && Array.isArray(w.seriesData.seriesGoals[i][j])) {
              goalVals = w.seriesData.seriesGoals[i][j].map(
                (goal) => {
                  return {
                    attrs: goal,
                    val: f.yLbFormatter(goal.value, {
                      seriesIndex: i,
                      dataPointIndex: j,
                      w
                    })
                  };
                }
              );
            }
          }
        }
        if (j === null) {
          val = f.yLbFormatter(w.seriesData.series[i], __spreadProps(__spreadValues({}, w), {
            seriesIndex: i,
            dataPointIndex: i
          }));
        }
        this.DOMHandling({
          i,
          t: tIndex,
          j,
          ttItems,
          values: {
            val,
            goalVals,
            xVal,
            xAxisTTVal,
            zVal
          },
          seriesName,
          shared,
          pColor
        });
      }
    }
    /**
     * @param {number} i
     */
    getFormatters(i) {
      const w = this.w;
      let yLbFormatter = w.formatters.yLabelFormatters[i];
      let yLbTitleFormatter;
      if (w.formatters.ttVal !== void 0) {
        if (Array.isArray(w.formatters.ttVal)) {
          yLbFormatter = /** @type {any} */
          w.formatters.ttVal[i] && /** @type {any} */
          w.formatters.ttVal[i].formatter;
          yLbTitleFormatter = /** @type {any} */
          w.formatters.ttVal[i] && /** @type {any} */
          w.formatters.ttVal[i].title && /** @type {any} */
          w.formatters.ttVal[i].title.formatter;
        } else {
          yLbFormatter = /** @type {any} */
          w.formatters.ttVal.formatter;
          if (typeof /** @type {any} */
          w.formatters.ttVal.title.formatter === "function") {
            yLbTitleFormatter = /** @type {any} */
            w.formatters.ttVal.title.formatter;
          }
        }
      } else {
        yLbTitleFormatter = w.config.tooltip.y.title.formatter;
      }
      if (typeof yLbFormatter !== "function") {
        if (w.formatters.yLabelFormatters[0]) {
          yLbFormatter = w.formatters.yLabelFormatters[0];
        } else {
          yLbFormatter = function(label) {
            return label;
          };
        }
      }
      if (typeof yLbTitleFormatter !== "function") {
        yLbTitleFormatter = function(label) {
          return label ? label + ": " : "";
        };
      }
      return {
        yLbFormatter,
        yLbTitleFormatter
      };
    }
    /** @param {{fn: any, index: any, seriesIndex: any, j: any}} opts */
    getSeriesName({ fn, index, seriesIndex, j }) {
      const w = this.w;
      return fn(String(w.seriesData.seriesNames[index]), {
        series: w.seriesData.series,
        seriesIndex,
        dataPointIndex: j,
        w
      });
    }
    /** @param {{ t?: any, j?: any, i?: any, ttItems?: any, values?: any, seriesName?: any, shared?: any, pColor?: any }} opts */
    DOMHandling({ t, j, ttItems, values, seriesName, shared, pColor }) {
      const w = this.w;
      const ttCtx = this.ttCtx;
      const { val, goalVals, xVal, xAxisTTVal, zVal } = values;
      let ttItemsChildren = null;
      ttItemsChildren = ttItems[t].children;
      if (w.config.tooltip.fillSeriesColor) {
        ttItems[t].style.backgroundColor = pColor;
        ttItemsChildren[0].style.display = "none";
      }
      if (ttCtx.showTooltipTitle) {
        if (ttCtx.tooltipTitle === null) {
          ttCtx.tooltipTitle = w.dom.baseEl.querySelector(
            ".apexcharts-tooltip-title"
          );
        }
        if (ttCtx.tooltipTitle) {
          ttCtx.tooltipTitle.innerHTML = xVal;
        }
      }
      if (ttCtx.isXAxisTooltipEnabled) {
        if (ttCtx.xaxisTooltipText) {
          ttCtx.xaxisTooltipText.innerHTML = xAxisTTVal !== "" ? xAxisTTVal : xVal;
        }
      }
      const ttYLabel = ttItems[t].querySelector(
        ".apexcharts-tooltip-text-y-label"
      );
      if (ttYLabel) {
        ttYLabel.innerHTML = seriesName ? seriesName : "";
      }
      const ttYVal = ttItems[t].querySelector(".apexcharts-tooltip-text-y-value");
      if (ttYVal) {
        ttYVal.innerHTML = typeof val !== "undefined" ? val : "";
      }
      if (ttItemsChildren[0] && ttItemsChildren[0].classList.contains("apexcharts-tooltip-marker")) {
        if (w.config.tooltip.marker.fillColors && Array.isArray(w.config.tooltip.marker.fillColors)) {
          pColor = w.config.tooltip.marker.fillColors[t];
        }
        if (w.config.tooltip.fillSeriesColor) {
          ttItemsChildren[0].style.backgroundColor = pColor;
        } else {
          ttItemsChildren[0].style.color = pColor;
        }
      }
      if (!w.config.tooltip.marker.show) {
        ttItemsChildren[0].style.display = "none";
      }
      const ttGLabel = ttItems[t].querySelector(
        ".apexcharts-tooltip-text-goals-label"
      );
      const ttGVal = ttItems[t].querySelector(
        ".apexcharts-tooltip-text-goals-value"
      );
      if (goalVals.length && w.seriesData.seriesGoals[t]) {
        const createGoalsHtml = () => {
          let gLabels = "<div>";
          let gVals = "<div>";
          goalVals.forEach((goal) => {
            gLabels += ` <div style="display: flex"><span class="apexcharts-tooltip-marker" style="background-color: ${goal.attrs.strokeColor}; height: 3px; border-radius: 0; top: 5px;"></span> ${goal.attrs.name}</div>`;
            gVals += `<div>${goal.val}</div>`;
          });
          ttGLabel.innerHTML = gLabels + `</div>`;
          ttGVal.innerHTML = gVals + `</div>`;
        };
        if (shared) {
          if (w.seriesData.seriesGoals[t][j] && Array.isArray(w.seriesData.seriesGoals[t][j])) {
            createGoalsHtml();
          } else {
            ttGLabel.innerHTML = "";
            ttGVal.innerHTML = "";
          }
        } else {
          createGoalsHtml();
        }
      } else {
        ttGLabel.innerHTML = "";
        ttGVal.innerHTML = "";
      }
      if (zVal !== null) {
        const ttZLabel = ttItems[t].querySelector(
          ".apexcharts-tooltip-text-z-label"
        );
        ttZLabel.innerHTML = w.config.tooltip.z.title;
        const ttZVal = ttItems[t].querySelector(
          ".apexcharts-tooltip-text-z-value"
        );
        ttZVal.innerHTML = typeof zVal !== "undefined" ? zVal : "";
      }
      if (shared && ttItemsChildren[0]) {
        if (w.config.tooltip.hideEmptySeries) {
          const ttItemMarker = ttItems[t].querySelector(
            ".apexcharts-tooltip-marker"
          );
          const ttItemText = ttItems[t].querySelector(".apexcharts-tooltip-text");
          if (parseFloat(val) == 0) {
            ttItemMarker.style.display = "none";
            ttItemText.style.display = "none";
          } else {
            ttItemMarker.style.display = "block";
            ttItemText.style.display = "block";
          }
        }
        if (typeof val === "undefined" || val === null || w.globals.ancillaryCollapsedSeriesIndices.indexOf(t) > -1 || w.globals.collapsedSeriesIndices.indexOf(t) > -1 || Array.isArray(ttCtx.tConfig.enabledOnSeries) && ttCtx.tConfig.enabledOnSeries.indexOf(t) === -1) {
          ttItemsChildren[0].parentNode.style.display = "none";
        } else {
          ttItemsChildren[0].parentNode.style.display = w.config.tooltip.items.display;
        }
      } else {
        if (Array.isArray(ttCtx.tConfig.enabledOnSeries) && ttCtx.tConfig.enabledOnSeries.indexOf(t) === -1) {
          ttItemsChildren[0].parentNode.style.display = "none";
        }
      }
    }
    /**
     * @param {boolean} shared
     * @param {number} i
     */
    toggleActiveInactiveSeries(shared, i) {
      const w = this.w;
      if (shared) {
        this.tooltipUtil.toggleAllTooltipSeriesGroups("enable");
      } else {
        this.tooltipUtil.toggleAllTooltipSeriesGroups("disable");
        const firstTooltipSeriesGroup = w.dom.baseEl.querySelector(
          `.apexcharts-tooltip-series-group-${i}`
        );
        if (firstTooltipSeriesGroup) {
          const ftsGroup = (
            /** @type {HTMLElement} */
            firstTooltipSeriesGroup
          );
          ftsGroup.classList.add("apexcharts-active");
          ftsGroup.style.display = w.config.tooltip.items.display;
        }
      }
    }
    /** @param {{i: any, j: any}} opts */
    getValuesToPrint({ i, j }) {
      var _a, _b, _c, _d, _e, _f, _g, _h;
      const w = this.w;
      const filteredSeriesX = w.seriesData.seriesX.map(
        (ser) => ser.length > 0 ? ser : []
      );
      let xVal = "";
      let xAxisTTVal = "";
      let zVal = null;
      let val = null;
      const customFormatterOpts = {
        series: w.seriesData.series,
        seriesIndex: i,
        dataPointIndex: j,
        w
      };
      const zFormatter = w.formatters.ttZFormatter;
      if (j === null) {
        val = w.seriesData.series[i];
      } else {
        if (w.axisFlags.isXNumeric && w.config.chart.type !== "treemap") {
          xVal = filteredSeriesX[i][j];
          if (filteredSeriesX[i].length === 0) {
            const firstActiveSeriesIndex = this.tooltipUtil.getFirstActiveXArray(filteredSeriesX);
            xVal = filteredSeriesX[firstActiveSeriesIndex][j];
          }
        } else {
          const dataFormat = new Data(this.w);
          if (dataFormat.isFormatXY()) {
            xVal = typeof /** @type {any} */
            w.config.series[i].data[j] !== "undefined" ? (
              /** @type {any} */
              w.config.series[i].data[j].x
            ) : "";
          } else {
            xVal = typeof w.labelData.labels[j] !== "undefined" ? w.labelData.labels[j] : "";
          }
        }
      }
      const bufferXVal = xVal;
      if (w.axisFlags.isXNumeric && w.config.xaxis.type === "datetime") {
        const xFormat = new Formatters(this.w);
        xVal = xFormat.xLabelFormat(
          /** @type {Function} */
          w.formatters.ttKeyFormatter,
          bufferXVal,
          bufferXVal,
          {
            i: void 0,
            dateFormatter: new DateTime(this.w).formatDate,
            w: this.w
          }
        );
      } else {
        if (w.globals.isBarHorizontal) {
          xVal = w.formatters.yLabelFormatters[0](bufferXVal, customFormatterOpts);
        } else {
          xVal = (_c = (_b = (_a = w.formatters).xLabelFormatter) == null ? void 0 : _b.call(_a, bufferXVal, customFormatterOpts)) != null ? _c : bufferXVal;
        }
      }
      if (w.config.tooltip.x.formatter !== void 0) {
        xVal = (_f = (_e = (_d = w.formatters).ttKeyFormatter) == null ? void 0 : _e.call(_d, bufferXVal, customFormatterOpts)) != null ? _f : bufferXVal;
      }
      if (w.seriesData.seriesZ.length > 0 && w.seriesData.seriesZ[i].length > 0) {
        zVal = zFormatter == null ? void 0 : zFormatter(w.seriesData.seriesZ[i][j], w);
      }
      if (typeof w.config.xaxis.tooltip.formatter === "function") {
        xAxisTTVal = (_h = (_g = w.formatters).xaxisTooltipFormatter) == null ? void 0 : _h.call(
          _g,
          bufferXVal,
          customFormatterOpts
        );
      } else {
        xAxisTTVal = xVal;
      }
      return {
        val: Array.isArray(val) ? val.join(" ") : val,
        xVal: Array.isArray(xVal) ? xVal.join(" ") : xVal,
        xAxisTTVal: Array.isArray(xAxisTTVal) ? xAxisTTVal.join(" ") : xAxisTTVal,
        zVal
      };
    }
    /** @param {{i: any, j: any, y1: any, y2: any, w: any}} opts */
    handleCustomTooltip({ i, j, y1, y2, w }) {
      const tooltipEl = this.ttCtx.getElTooltip();
      let fn = w.config.tooltip.custom;
      if (Array.isArray(fn) && fn[i]) {
        fn = fn[i];
      }
      const customTooltip = fn({
        series: w.seriesData.series,
        seriesIndex: i,
        dataPointIndex: j,
        y1,
        y2,
        w
      });
      if (tooltipEl) {
        if (typeof customTooltip === "string" || typeof customTooltip === "number") {
          tooltipEl.innerHTML = String(customTooltip);
        } else if (customTooltip instanceof Element || typeof customTooltip.nodeName === "string") {
          tooltipEl.innerHTML = "";
          tooltipEl.appendChild(customTooltip.cloneNode(true));
        }
      }
    }
  }
  class Position {
    /**
     * @param {import('./Tooltip').default} tooltipContext
     */
    constructor(tooltipContext) {
      this.ttCtx = tooltipContext;
      this.w = tooltipContext.w;
    }
    /**
     * This will move the crosshair (the vertical/horz line that moves along with mouse)
     * Along with this, this function also calls the xaxisMove function
     * @memberof Position
     * @param {number} cx - point's x position, wherever point's x is, you need to move crosshair
     * @param {number | null} [j]
     */
    moveXCrosshairs(cx, j = null) {
      const ttCtx = this.ttCtx;
      const w = this.w;
      const xcrosshairs = ttCtx.getElXCrosshairs();
      let x = cx - ttCtx.xcrosshairsWidth / 2;
      const tickAmount = w.labelData.labels.slice().length;
      if (j !== null) {
        x = w.layout.gridWidth / tickAmount * j;
      }
      if (xcrosshairs !== null && !w.globals.isBarHorizontal) {
        xcrosshairs.setAttribute("x", String(x));
        xcrosshairs.setAttribute("x1", String(x));
        xcrosshairs.setAttribute("x2", String(x));
        xcrosshairs.setAttribute("y2", String(w.layout.gridHeight));
        xcrosshairs.classList.add("apexcharts-active");
      }
      if (x < 0) {
        x = 0;
      }
      if (x > w.layout.gridWidth) {
        x = w.layout.gridWidth;
      }
      if (ttCtx.isXAxisTooltipEnabled) {
        let tx = x;
        if (w.config.xaxis.crosshairs.width === "tickWidth" || w.config.xaxis.crosshairs.width === "barWidth") {
          tx = x + ttCtx.xcrosshairsWidth / 2;
        }
        this.moveXAxisTooltip(tx);
      }
    }
    /**
     * This will move the crosshair (the vertical/horz line that moves along with mouse)
     * Along with this, this function also calls the xaxisMove function
     * @memberof Position
     * @param {number} cy - point's y position, wherever point's y is, you need to move crosshair
     */
    moveYCrosshairs(cy) {
      const ttCtx = this.ttCtx;
      if (ttCtx.ycrosshairs !== null) {
        Graphics.setAttrs(ttCtx.ycrosshairs, {
          y1: cy,
          y2: cy
        });
      }
      if (ttCtx.ycrosshairsHidden !== null) {
        Graphics.setAttrs(ttCtx.ycrosshairsHidden, {
          y1: cy,
          y2: cy
        });
      }
    }
    /**
     ** AxisTooltip is the small rectangle which appears on x axis with x value, when user moves
     * @memberof Position
     * @param {number} cx - point's x position, wherever point's x is, you need to move
     */
    moveXAxisTooltip(cx) {
      var _a, _b;
      const w = this.w;
      const ttCtx = this.ttCtx;
      if (ttCtx.xaxisTooltip !== null && ttCtx.xcrosshairsWidth !== 0) {
        ttCtx.xaxisTooltip.classList.add("apexcharts-active");
        const cy = ttCtx.xaxisOffY + w.config.xaxis.tooltip.offsetY + w.layout.translateY + 1 + w.config.xaxis.offsetY;
        const xaxisTTText = ttCtx.xaxisTooltip.getBoundingClientRect();
        const xaxisTTTextWidth = xaxisTTText.width;
        cx = cx - xaxisTTTextWidth / 2;
        if (!isNaN(cx)) {
          cx = cx + w.layout.translateX;
          const graphics = new Graphics(this.w);
          const textRect = graphics.getTextRects(
            (_b = (_a = ttCtx.xaxisTooltipText) == null ? void 0 : _a.innerHTML) != null ? _b : "",
            w.config.xaxis.labels.style.fontSize
          );
          if (ttCtx.xaxisTooltipText) {
            ttCtx.xaxisTooltipText.style.minWidth = textRect.width + "px";
          }
          ttCtx.xaxisTooltip.style.left = cx + "px";
          ttCtx.xaxisTooltip.style.top = cy + "px";
        }
      }
    }
    /**
     * @param {number} index
     */
    moveYAxisTooltip(index) {
      var _a, _b;
      const w = this.w;
      const ttCtx = this.ttCtx;
      if (ttCtx.yaxisTTEls === null) {
        ttCtx.yaxisTTEls = /** @type {any[]} */
        [
          ...w.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip")
        ];
      }
      const ycrosshairsHiddenRectY1 = parseInt(
        (_b = (_a = ttCtx.ycrosshairsHidden) == null ? void 0 : _a.getAttribute("y1")) != null ? _b : "0",
        10
      );
      let cy = w.layout.translateY + ycrosshairsHiddenRectY1;
      if (ttCtx.yaxisTTEls) {
        const yAxisTTRect = ttCtx.yaxisTTEls[index].getBoundingClientRect();
        const yAxisTTHeight = yAxisTTRect.height;
        let cx = w.globals.translateYAxisX[index] - 2;
        if (w.config.yaxis[index].opposite) {
          cx = cx - yAxisTTRect.width;
        }
        cy = cy - yAxisTTHeight / 2;
        if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1 && cy > 0 && cy < w.layout.gridHeight) {
          ttCtx.yaxisTTEls[index].classList.add("apexcharts-active");
          ttCtx.yaxisTTEls[index].style.top = cy + "px";
          ttCtx.yaxisTTEls[index].style.left = cx + w.config.yaxis[index].tooltip.offsetX + "px";
        } else {
          ttCtx.yaxisTTEls[index].classList.remove("apexcharts-active");
        }
      }
    }
    /**
     ** moves the whole tooltip by changing x, y attrs
     * @memberof Position
     * @param {number} cx - point's x position, wherever point's x is, you need to move tooltip
     * @param {number} cy - point's y position, wherever point's y is, you need to move tooltip
     * @param {number | null} [markerSize] - point's size
     */
    moveTooltip(cx, cy, markerSize = null) {
      const w = this.w;
      const ttCtx = this.ttCtx;
      const tooltipEl = ttCtx.getElTooltip();
      const tooltipRect = ttCtx.tooltipRect;
      const pointSize = markerSize !== null ? parseFloat(String(markerSize)) : 1;
      let x = parseFloat(String(cx)) + pointSize + 5;
      let y = parseFloat(String(cy)) + pointSize / 2;
      if (x > w.layout.gridWidth / 2) {
        x = x - tooltipRect.ttWidth - pointSize - 10;
      }
      if (x > w.layout.gridWidth - tooltipRect.ttWidth - 10) {
        x = w.layout.gridWidth - tooltipRect.ttWidth;
      }
      if (x < -20) {
        x = -20;
      }
      if (w.config.tooltip.followCursor) {
        const elGrid = ttCtx.getElGrid();
        if (!elGrid) return;
        const seriesBound = elGrid.getBoundingClientRect();
        x = ttCtx.e.clientX - seriesBound.left;
        if (x > w.layout.gridWidth / 2) {
          x = x - ttCtx.tooltipRect.ttWidth;
        }
        y = ttCtx.e.clientY + w.layout.translateY - seriesBound.top;
        if (y > w.layout.gridHeight / 2) {
          y = y - ttCtx.tooltipRect.ttHeight;
        }
      } else {
        if (!w.globals.isBarHorizontal) {
          if (tooltipRect.ttHeight / 2 + y > w.layout.gridHeight) {
            y = w.layout.gridHeight - tooltipRect.ttHeight + w.layout.translateY;
          }
        }
      }
      if (!isNaN(x)) {
        x = x + w.layout.translateX;
        if (tooltipEl) {
          tooltipEl.style.left = x + "px";
          tooltipEl.style.top = y + "px";
        }
      }
    }
    /**
     * @param {number} i
     * @param {number} j
     */
    moveMarkers(i, j) {
      var _a;
      const w = this.w;
      const ttCtx = this.ttCtx;
      if (w.globals.markers.size[i] > 0) {
        const allPoints = w.dom.baseEl.querySelectorAll(
          ` .apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker`
        );
        for (let p = 0; p < allPoints.length; p++) {
          if (parseInt((_a = allPoints[p].getAttribute("rel")) != null ? _a : "0", 10) === j) {
            ttCtx.marker.resetPointsSize();
            ttCtx.marker.enlargeCurrentPoint(j, allPoints[p]);
          }
        }
      } else {
        ttCtx.marker.resetPointsSize();
        this.moveDynamicPointOnHover(j, i);
      }
    }
    // This function is used when you need to show markers/points only on hover -
    // DIFFERENT X VALUES in multiple series
    /**
     * @param {number} j
     * @param {number} capturedSeries
     */
    moveDynamicPointOnHover(j, capturedSeries) {
      var _a, _b, _c, _d, _e;
      const w = this.w;
      const ttCtx = this.ttCtx;
      let cx = 0;
      let cy = 0;
      const graphics = new Graphics(this.w);
      const pointsArr = w.globals.pointsArray;
      const hoverSize = ttCtx.tooltipUtil.getHoverMarkerSize(capturedSeries);
      const serType = (
        /** @type {any} */
        w.config.series[capturedSeries].type
      );
      if (serType && (serType === "column" || serType === "candlestick" || serType === "boxPlot")) {
        return;
      }
      cx = (_b = (_a = pointsArr[capturedSeries]) == null ? void 0 : _a[j]) == null ? void 0 : _b[0];
      cy = ((_d = (_c = pointsArr[capturedSeries]) == null ? void 0 : _c[j]) == null ? void 0 : _d[1]) || 0;
      const point = w.dom.baseEl.querySelector(
        `.apexcharts-series[data\\:realIndex='${capturedSeries}'] .apexcharts-series-markers path`
      );
      if (point && cy < w.layout.gridHeight && cy > 0) {
        const shape = (_e = point.getAttribute("shape")) != null ? _e : "circle";
        const path = graphics.getMarkerPath(cx, cy, shape, hoverSize * 1.5);
        point.setAttribute("d", path);
      }
      this.moveXCrosshairs(cx);
      if (!ttCtx.fixedTooltip) {
        this.moveTooltip(cx, cy, hoverSize);
      }
    }
    // This function is used when you need to show markers/points only on hover -
    // SAME X VALUES in multiple series
    /**
     * @param {number} j
     */
    moveDynamicPointsOnHover(j) {
      var _a, _b;
      const ttCtx = this.ttCtx;
      const w = ttCtx.w;
      let cx = 0;
      let cy = 0;
      let activeSeries = 0;
      const pointsArr = w.globals.pointsArray;
      const series = new Series(this.w);
      const graphics = new Graphics(this.w);
      activeSeries = series.getActiveConfigSeriesIndex("asc", [
        "line",
        "area",
        "scatter",
        "bubble"
      ]);
      const hoverSize = ttCtx.tooltipUtil.getHoverMarkerSize(activeSeries);
      if ((_a = pointsArr[activeSeries]) == null ? void 0 : _a[j]) {
        cx = pointsArr[activeSeries][j][0];
        cy = pointsArr[activeSeries][j][1];
      }
      if (isNaN(cx)) {
        return;
      }
      const points = ttCtx.tooltipUtil.getAllMarkers();
      if (points.length) {
        for (let p = 0; p < w.seriesData.series.length; p++) {
          const pointArr = pointsArr[p];
          if (w.globals.comboCharts) {
            if (typeof pointArr === "undefined") {
              points.splice(p, 0, null);
            }
          }
          if (pointArr && pointArr.length) {
            let pcy = pointsArr[p][j][1];
            let pcy2;
            points[p].setAttribute("cx", cx);
            const shape = (_b = points[p].getAttribute("shape")) != null ? _b : "circle";
            if (w.config.chart.type === "rangeArea" && !w.globals.comboCharts) {
              const rangeStartIndex = j + w.seriesData.series[p].length;
              pcy2 = pointsArr[p][rangeStartIndex][1];
              const pcyDiff = Math.abs(pcy - pcy2) / 2;
              pcy = pcy - pcyDiff;
            }
            if (pcy !== null && !isNaN(pcy) && pcy < w.layout.gridHeight + hoverSize && pcy + hoverSize > 0) {
              const path = graphics.getMarkerPath(cx, pcy, shape, hoverSize);
              points[p].setAttribute("d", path);
            } else {
              points[p].setAttribute("d", "");
            }
          }
        }
      }
      this.moveXCrosshairs(cx);
      if (!ttCtx.fixedTooltip) {
        this.moveTooltip(cx, cy || w.layout.gridHeight, hoverSize);
      }
    }
    /**
     * @param {number} j
     * @param {number} capturedSeries
     */
    moveStickyTooltipOverBars(j, capturedSeries) {
      var _a, _b, _c;
      const w = this.w;
      const ttCtx = this.ttCtx;
      let barLen = w.globals.columnSeries ? (
        /** @type {any} */
        w.globals.columnSeries.length
      ) : w.seriesData.series.length;
      if (w.config.chart.stacked) {
        barLen = w.globals.barGroups.length;
      }
      let i = barLen >= 2 && barLen % 2 === 0 ? Math.floor(barLen / 2) : Math.floor(barLen / 2) + 1;
      if (w.globals.isBarHorizontal) {
        const series = new Series(this.w);
        i = series.getActiveConfigSeriesIndex("desc") + 1;
      }
      let jBar = w.dom.baseEl.querySelector(
        `.apexcharts-bar-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-candlestick-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-boxPlot-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-rangebar-series .apexcharts-series[rel='${i}'] path[j='${j}']`
      );
      if (!jBar && typeof capturedSeries === "number") {
        jBar = w.dom.baseEl.querySelector(
          `.apexcharts-bar-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
        .apexcharts-candlestick-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
        .apexcharts-boxPlot-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
        .apexcharts-rangebar-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}']`
        );
      }
      let bcx = jBar ? parseFloat((_a = jBar.getAttribute("cx")) != null ? _a : "0") : 0;
      let bcy = jBar ? parseFloat((_b = jBar.getAttribute("cy")) != null ? _b : "0") : 0;
      const bw = jBar ? parseFloat((_c = jBar.getAttribute("barWidth")) != null ? _c : "0") : 0;
      const elGrid = ttCtx.getElGrid();
      if (!elGrid) return;
      const seriesBound = elGrid.getBoundingClientRect();
      const isBoxOrCandle = jBar && (jBar.classList.contains("apexcharts-candlestick-area") || jBar.classList.contains("apexcharts-boxPlot-area"));
      if (w.axisFlags.isXNumeric) {
        if (jBar && !isBoxOrCandle) {
          bcx = bcx - (barLen % 2 !== 0 ? bw / 2 : 0);
        }
        if (jBar && // fixes apexcharts.js#2354
        isBoxOrCandle) {
          bcx = bcx - bw / 2;
        }
      } else {
        if (!w.globals.isBarHorizontal) {
          bcx = ttCtx.xAxisTicksPositions[j - 1] + ttCtx.dataPointsDividedWidth / 2;
          if (isNaN(bcx)) {
            bcx = ttCtx.xAxisTicksPositions[j] - ttCtx.dataPointsDividedWidth / 2;
          }
        }
      }
      if (!w.globals.isBarHorizontal) {
        if (w.config.tooltip.followCursor) {
          bcy = ttCtx.e.clientY - seriesBound.top - ttCtx.tooltipRect.ttHeight / 2;
        } else {
          if (bcy + ttCtx.tooltipRect.ttHeight + 15 > w.layout.gridHeight) {
            bcy = w.layout.gridHeight;
          }
        }
      } else {
        bcy = bcy - ttCtx.tooltipRect.ttHeight;
      }
      if (!w.globals.isBarHorizontal) {
        this.moveXCrosshairs(bcx);
      }
      if (!ttCtx.fixedTooltip) {
        this.moveTooltip(bcx, bcy || w.layout.gridHeight);
      }
    }
  }
  class Marker {
    /**
     * @param {import('./Tooltip').default} tooltipContext
     */
    constructor(tooltipContext) {
      this.w = tooltipContext.w;
      this.ttCtx = tooltipContext;
      this.ctx = tooltipContext.ctx;
      this.tooltipPosition = new Position(tooltipContext);
    }
    drawDynamicPoints() {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const marker = new Markers(this.w, this.ctx);
      const elsSeries = (
        /** @type {any[]} */
        [
          ...w.dom.baseEl.querySelectorAll(".apexcharts-series")
        ]
      );
      if (w.config.chart.stacked) {
        elsSeries.sort((a, b) => {
          return parseFloat(a.getAttribute("data:realIndex")) - parseFloat(b.getAttribute("data:realIndex"));
        });
      }
      for (let i = 0; i < elsSeries.length; i++) {
        const pointsMain = elsSeries[i].querySelector(
          `.apexcharts-series-markers-wrap`
        );
        if (pointsMain !== null) {
          let PointClasses = `apexcharts-marker w${(Math.random() + 1).toString(36).substring(4)}`;
          if ((w.config.chart.type === "line" || w.config.chart.type === "area") && !w.globals.comboCharts && !w.config.tooltip.intersect) {
            PointClasses += " no-pointer-events";
          }
          const elPointOptions = marker.getMarkerConfig({
            cssClass: PointClasses,
            seriesIndex: Number(pointsMain.getAttribute("data:realIndex"))
            // fixes apexcharts/apexcharts.js #1427
          });
          const point = graphics.drawMarker(0, 0, elPointOptions);
          point.node.setAttribute("default-marker-size", 0);
          const elPointsG = BrowserAPIs.createElementNS(SVGNS, "g");
          elPointsG.classList.add("apexcharts-series-markers");
          elPointsG.appendChild(point.node);
          pointsMain.appendChild(elPointsG);
        }
      }
    }
    /**
     * @param {any} rel
     * @param {any} point
     * @param {number | null} [x]
     * @param {number | null} [y]
     */
    enlargeCurrentPoint(rel, point, x = null, y = null) {
      const w = this.w;
      if (w.config.chart.type !== "bubble") {
        this.newPointSize(rel, point);
      }
      let cx = point.getAttribute("cx");
      let cy = point.getAttribute("cy");
      if (x !== null && y !== null) {
        cx = x;
        cy = y;
      }
      this.tooltipPosition.moveXCrosshairs(cx);
      if (!this.fixedTooltip) {
        if (w.config.chart.type === "radar") {
          const elGrid = this.ttCtx.getElGrid();
          if (!elGrid) return;
          const seriesBound = elGrid.getBoundingClientRect();
          cx = this.ttCtx.e.clientX - seriesBound.left;
        }
        this.tooltipPosition.moveTooltip(cx, cy, w.config.markers.hover.size);
      }
    }
    /**
     * @param {number} j
     */
    enlargePoints(j) {
      var _a, _b;
      const w = this.w;
      const me = this;
      const ttCtx = this.ttCtx;
      const col = j;
      const points = w.dom.baseEl.querySelectorAll(
        ".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"
      );
      let newSize = w.config.markers.hover.size;
      for (let p = 0; p < points.length; p++) {
        const rel = points[p].getAttribute("rel");
        const index = points[p].getAttribute("index");
        if (newSize === void 0) {
          newSize = w.globals.markers.size[
            /** @type {any} */
            index
          ] + w.config.markers.hover.sizeOffset;
        }
        if (col === parseInt(rel != null ? rel : "0", 10)) {
          me.newPointSize(col, points[p]);
          const cx = (_a = points[p].getAttribute("cx")) != null ? _a : "0";
          const cy = (_b = points[p].getAttribute("cy")) != null ? _b : "0";
          me.tooltipPosition.moveXCrosshairs(parseFloat(cx));
          if (!ttCtx.fixedTooltip) {
            me.tooltipPosition.moveTooltip(
              parseFloat(cx),
              parseFloat(cy),
              newSize
            );
          }
        } else {
          me.oldPointSize(points[p]);
        }
      }
    }
    /**
     * @param {any} rel
     * @param {any} point
     */
    newPointSize(rel, point) {
      const w = this.w;
      let newSize = w.config.markers.hover.size;
      const elPoint = rel === 0 ? point.parentNode.firstChild : point.parentNode.lastChild;
      if (elPoint.getAttribute("default-marker-size") !== "0") {
        const index = parseInt(elPoint.getAttribute("index"), 10);
        if (newSize === void 0) {
          newSize = w.globals.markers.size[index] + w.config.markers.hover.sizeOffset;
        }
        if (newSize < 0) {
          newSize = 0;
        }
        const path = this.ttCtx.tooltipUtil.getPathFromPoint(point, newSize);
        point.setAttribute("d", path);
      }
    }
    /**
     * @param {any} point
     */
    oldPointSize(point) {
      const size = parseFloat(point.getAttribute("default-marker-size"));
      const path = this.ttCtx.tooltipUtil.getPathFromPoint(point, size);
      point.setAttribute("d", path);
    }
    resetPointsSize() {
      var _a;
      const w = this.w;
      const points = w.dom.baseEl.querySelectorAll(
        ".apexcharts-series:not(.apexcharts-series-collapsed) .apexcharts-marker"
      );
      for (let p = 0; p < points.length; p++) {
        const size = parseFloat(
          (_a = points[p].getAttribute("default-marker-size")) != null ? _a : "0"
        );
        if (Utils$1.isNumber(size) && size > 0) {
          const path = this.ttCtx.tooltipUtil.getPathFromPoint(points[p], size);
          points[p].setAttribute("d", path);
        } else {
          points[p].setAttribute("d", "M0,0");
        }
      }
    }
  }
  class Intersect {
    /**
     * @param {import('./Tooltip').default} tooltipContext
     */
    constructor(tooltipContext) {
      this.w = tooltipContext.w;
      const w = this.w;
      this.ttCtx = tooltipContext;
      this.isVerticalGroupedRangeBar = !w.globals.isBarHorizontal && w.config.chart.type === "rangeBar" && w.config.plotOptions.bar.rangeBarGroupRows;
    }
    // a helper function to get an element's attribute value
    /**
     * @param {Event} e
     * @param {string} attr
     */
    getAttr(e, attr) {
      var _a;
      return parseFloat(
        /** @type {Element} */
        (_a = e.target.getAttribute(attr)) != null ? _a : ""
      );
    }
    // handle tooltip for heatmaps and treemaps
    /** @param {{e: any, opt: any, x: any, y: any, type: any}} opts */
    handleHeatTreeTooltip({ e, opt, x, y, type }) {
      var _a, _b;
      const ttCtx = this.ttCtx;
      const w = this.w;
      if (e.target.classList.contains(`apexcharts-${type}-rect`)) {
        const i = this.getAttr(e, "i");
        const j = this.getAttr(e, "j");
        const cx = this.getAttr(e, "cx");
        const cy = this.getAttr(e, "cy");
        const width = this.getAttr(e, "width");
        const height = this.getAttr(e, "height");
        ttCtx.tooltipLabels.drawSeriesTexts({
          ttItems: opt.ttItems,
          i,
          j,
          shared: false,
          e
        });
        w.interact.capturedSeriesIndex = i;
        w.interact.capturedDataPointIndex = j;
        x = cx + ttCtx.tooltipRect.ttWidth / 2 + width;
        y = cy + ttCtx.tooltipRect.ttHeight / 2 - height / 2;
        ttCtx.tooltipPosition.moveXCrosshairs(cx + width / 2);
        if (x > w.layout.gridWidth / 2) {
          x = cx - ttCtx.tooltipRect.ttWidth / 2 + width;
        }
        if (ttCtx.w.config.tooltip.followCursor) {
          const seriesBound = w.dom.elWrap.getBoundingClientRect();
          x = ((_a = w.interact.clientX) != null ? _a : 0) - seriesBound.left - (x > w.layout.gridWidth / 2 ? ttCtx.tooltipRect.ttWidth : 0);
          y = ((_b = w.interact.clientY) != null ? _b : 0) - seriesBound.top - (y > w.layout.gridHeight / 2 ? ttCtx.tooltipRect.ttHeight : 0);
        }
      }
      return {
        x,
        y
      };
    }
    /**
     * handle tooltips for line/area/scatter charts where tooltip.intersect is true
     * when user hovers over the marker directly, this function is executed
     */
    /** @param {{e: any, opt: any, x: any, y: any}} opts */
    handleMarkerTooltip({ e, opt, x, y }) {
      const w = this.w;
      const ttCtx = this.ttCtx;
      let i;
      let j;
      if (e.target.classList.contains("apexcharts-marker")) {
        const cx = parseInt(opt.paths.getAttribute("cx"), 10);
        const cy = parseInt(opt.paths.getAttribute("cy"), 10);
        const val = parseFloat(opt.paths.getAttribute("val"));
        j = parseInt(opt.paths.getAttribute("rel"), 10);
        i = parseInt(
          opt.paths.parentNode.parentNode.parentNode.getAttribute("rel"),
          10
        ) - 1;
        if (ttCtx.intersect) {
          const el = Utils$1.findAncestor(opt.paths, "apexcharts-series");
          if (el) {
            i = parseInt(el.getAttribute("data:realIndex"), 10);
          }
        }
        ttCtx.tooltipLabels.drawSeriesTexts({
          ttItems: opt.ttItems,
          i,
          j,
          shared: ttCtx.showOnIntersect ? false : w.config.tooltip.shared,
          e
        });
        if (e.type === "mouseup") {
          ttCtx.markerClick(e, i, j);
        }
        w.interact.capturedSeriesIndex = i;
        w.interact.capturedDataPointIndex = j;
        x = cx;
        y = cy + w.layout.translateY - ttCtx.tooltipRect.ttHeight * 1.4;
        if (ttCtx.w.config.tooltip.followCursor) {
          const elGrid = ttCtx.getElGrid();
          if (!elGrid) return { x, y };
          const seriesBound = elGrid.getBoundingClientRect();
          y = ttCtx.e.clientY + w.layout.translateY - seriesBound.top;
        }
        if (val < 0) {
          y = cy;
        }
        ttCtx.marker.enlargeCurrentPoint(j, opt.paths, x, y);
      }
      return {
        x,
        y
      };
    }
    /**
     * handle tooltips for bar/column charts
     */
    /** @param {{e: any, opt: any}} opts */
    handleBarTooltip({ e, opt }) {
      const w = this.w;
      const ttCtx = this.ttCtx;
      const tooltipEl = ttCtx.getElTooltip();
      let bx = 0;
      let x = 0;
      let y = 0;
      let i = 0;
      let strokeWidth;
      const barXY = this.getBarTooltipXY({
        e,
        opt
      });
      if (barXY.j === null && barXY.barHeight === 0 && barXY.barWidth === 0) {
        return;
      }
      i = barXY.i;
      const j = barXY.j;
      w.interact.capturedSeriesIndex = i;
      w.interact.capturedDataPointIndex = j !== null ? j : w.interact.capturedDataPointIndex;
      if (w.globals.isBarHorizontal && ttCtx.tooltipUtil.hasBars() || !w.config.tooltip.shared) {
        x = barXY.x;
        y = barXY.y;
        strokeWidth = Array.isArray(w.config.stroke.width) ? w.config.stroke.width[i] : w.config.stroke.width;
        bx = x;
      } else {
        if (!w.globals.comboCharts && !w.config.tooltip.shared) {
          bx = bx / 2;
        }
      }
      if (isNaN(y)) {
        y = w.globals.svgHeight - ttCtx.tooltipRect.ttHeight;
      }
      if (x + ttCtx.tooltipRect.ttWidth > w.layout.gridWidth) {
        x = x - ttCtx.tooltipRect.ttWidth;
      } else if (x < 0) {
        x = 0;
      }
      if (ttCtx.w.config.tooltip.followCursor) {
        const elGrid = ttCtx.getElGrid();
        if (!elGrid) return;
      }
      if (ttCtx.tooltip === null) {
        ttCtx.tooltip = w.dom.baseEl.querySelector(".apexcharts-tooltip");
      }
      if (!w.config.tooltip.shared) {
        if (w.globals.comboBarCount > 0) {
          ttCtx.tooltipPosition.moveXCrosshairs(bx + strokeWidth / 2);
        } else {
          ttCtx.tooltipPosition.moveXCrosshairs(bx);
        }
      }
      if (!ttCtx.fixedTooltip && (!w.config.tooltip.shared || w.globals.isBarHorizontal && ttCtx.tooltipUtil.hasBars())) {
        y = y + w.layout.translateY - ttCtx.tooltipRect.ttHeight / 2;
        if (tooltipEl) {
          tooltipEl.style.left = x + w.layout.translateX + "px";
          tooltipEl.style.top = y + "px";
        }
      }
    }
    /** @param {{e: any, opt: any}} opts */
    getBarTooltipXY({ e, opt }) {
      const w = this.w;
      let j = null;
      const ttCtx = this.ttCtx;
      let i = 0;
      let x = 0;
      let y = 0;
      let barWidth = 0;
      let barHeight = 0;
      const cl = e.target.classList;
      if (cl.contains("apexcharts-bar-area") || cl.contains("apexcharts-candlestick-area") || cl.contains("apexcharts-boxPlot-area") || cl.contains("apexcharts-rangebar-area")) {
        const bar = e.target;
        const barRect = bar.getBoundingClientRect();
        const seriesBound = opt.elGrid.getBoundingClientRect();
        const bh = barRect.height;
        barHeight = barRect.height;
        const bw = barRect.width;
        const cx = parseInt(bar.getAttribute("cx"), 10);
        const cy = parseInt(bar.getAttribute("cy"), 10);
        barWidth = parseFloat(bar.getAttribute("barWidth"));
        const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
        j = parseInt(bar.getAttribute("j"), 10);
        i = parseInt(bar.parentNode.getAttribute("rel"), 10) - 1;
        const y1 = bar.getAttribute("data-range-y1");
        const y2 = bar.getAttribute("data-range-y2");
        if (w.globals.comboCharts) {
          i = parseInt(bar.parentNode.getAttribute("data:realIndex"), 10);
        }
        const handleXForColumns = (x2) => {
          if (w.axisFlags.isXNumeric) {
            x2 = cx - bw / 2;
          } else {
            if (this.isVerticalGroupedRangeBar) {
              x2 = cx + bw / 2;
            } else {
              x2 = cx - ttCtx.dataPointsDividedWidth + bw / 2;
            }
          }
          return x2;
        };
        const handleYForBars = () => {
          return cy - ttCtx.dataPointsDividedHeight + bh / 2 - ttCtx.tooltipRect.ttHeight / 2;
        };
        ttCtx.tooltipLabels.drawSeriesTexts({
          ttItems: opt.ttItems,
          i,
          j,
          y1: y1 ? parseInt(y1, 10) : null,
          y2: y2 ? parseInt(y2, 10) : null,
          shared: ttCtx.showOnIntersect ? false : w.config.tooltip.shared,
          e
        });
        if (w.config.tooltip.followCursor) {
          if (w.globals.isBarHorizontal) {
            x = clientX - seriesBound.left + 15;
            y = handleYForBars();
          } else {
            x = handleXForColumns(x);
            y = e.clientY - seriesBound.top - ttCtx.tooltipRect.ttHeight / 2 - 15;
          }
        } else {
          if (w.globals.isBarHorizontal) {
            x = cx;
            if (ttCtx.xyRatios && x < ttCtx.xyRatios.baseLineInvertedY) {
              x = cx - ttCtx.tooltipRect.ttWidth;
            }
            y = handleYForBars();
          } else {
            x = handleXForColumns(x);
            y = cy;
          }
        }
      }
      return {
        x,
        y,
        barHeight,
        barWidth,
        i,
        j
      };
    }
  }
  class AxesTooltip {
    /**
     * @param {import('./Tooltip').default} tooltipContext
     */
    constructor(tooltipContext) {
      this.w = tooltipContext.w;
      this.ttCtx = tooltipContext;
    }
    /**
     * This method adds the secondary tooltip which appears below x axis
     * @memberof Tooltip
     **/
    drawXaxisTooltip() {
      const w = this.w;
      const ttCtx = this.ttCtx;
      const isBottom = w.config.xaxis.position === "bottom";
      ttCtx.xaxisOffY = isBottom ? w.layout.gridHeight + 1 : -w.layout.xAxisHeight - w.config.xaxis.axisTicks.height + 3;
      const tooltipCssClass = isBottom ? "apexcharts-xaxistooltip apexcharts-xaxistooltip-bottom" : "apexcharts-xaxistooltip apexcharts-xaxistooltip-top";
      const renderTo = w.dom.elWrap;
      if (ttCtx.isXAxisTooltipEnabled) {
        const xaxisTooltip = w.dom.baseEl.querySelector(
          ".apexcharts-xaxistooltip"
        );
        if (xaxisTooltip === null) {
          ttCtx.xaxisTooltip = BrowserAPIs.createElementNS(
            "http://www.w3.org/1999/xhtml",
            "div"
          );
          ttCtx.xaxisTooltip.setAttribute(
            "class",
            tooltipCssClass + " apexcharts-theme-" + w.config.tooltip.theme
          );
          renderTo.appendChild(ttCtx.xaxisTooltip);
          ttCtx.xaxisTooltipText = BrowserAPIs.createElementNS(
            "http://www.w3.org/1999/xhtml",
            "div"
          );
          ttCtx.xaxisTooltipText.classList.add("apexcharts-xaxistooltip-text");
          ttCtx.xaxisTooltipText.style.fontFamily = w.config.xaxis.tooltip.style.fontFamily || w.config.chart.fontFamily;
          ttCtx.xaxisTooltipText.style.fontSize = w.config.xaxis.tooltip.style.fontSize;
          ttCtx.xaxisTooltip.appendChild(ttCtx.xaxisTooltipText);
        }
      }
    }
    /**
     * This method adds the secondary tooltip which appears below x axis
     * @memberof Tooltip
     **/
    drawYaxisTooltip() {
      const w = this.w;
      const ttCtx = this.ttCtx;
      for (let i = 0; i < w.config.yaxis.length; i++) {
        const isRight = w.config.yaxis[i].opposite || w.config.yaxis[i].crosshairs.opposite;
        ttCtx.yaxisOffX = isRight ? w.layout.gridWidth + 1 : 1;
        const tooltipCssClass = isRight ? `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-right` : `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-left`;
        const renderTo = w.dom.elWrap;
        const yaxisTooltip = w.dom.baseEl.querySelector(
          `.apexcharts-yaxistooltip apexcharts-yaxistooltip-${i}`
        );
        if (yaxisTooltip === null) {
          ttCtx.yaxisTooltip = BrowserAPIs.createElementNS(
            "http://www.w3.org/1999/xhtml",
            "div"
          );
          ttCtx.yaxisTooltip.setAttribute(
            "class",
            tooltipCssClass + " apexcharts-theme-" + w.config.tooltip.theme
          );
          renderTo.appendChild(ttCtx.yaxisTooltip);
          if (i === 0) ttCtx.yaxisTooltipText = [];
          ttCtx.yaxisTooltipText[i] = BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div");
          ttCtx.yaxisTooltipText[i].classList.add(
            "apexcharts-yaxistooltip-text"
          );
          ttCtx.yaxisTooltip.appendChild(
            /** @type {any} */
            ttCtx.yaxisTooltipText[i]
          );
        }
      }
    }
    /**
     * @memberof Tooltip
     **/
    setXCrosshairWidth() {
      var _a, _b;
      const w = this.w;
      const ttCtx = this.ttCtx;
      const xcrosshairs = ttCtx.getElXCrosshairs();
      ttCtx.xcrosshairsWidth = parseInt(w.config.xaxis.crosshairs.width, 10);
      if (!w.globals.comboCharts) {
        if (w.config.xaxis.crosshairs.width === "tickWidth") {
          const count = w.labelData.labels.length;
          ttCtx.xcrosshairsWidth = w.layout.gridWidth / count;
        } else if (w.config.xaxis.crosshairs.width === "barWidth") {
          const bar = w.dom.baseEl.querySelector(".apexcharts-bar-area");
          if (bar !== null) {
            const barWidth = parseFloat((_a = bar.getAttribute("barWidth")) != null ? _a : "0");
            ttCtx.xcrosshairsWidth = barWidth;
          } else {
            ttCtx.xcrosshairsWidth = 1;
          }
        }
      } else {
        const bar = w.dom.baseEl.querySelector(".apexcharts-bar-area");
        if (bar !== null && w.config.xaxis.crosshairs.width === "barWidth") {
          const barWidth = parseFloat((_b = bar.getAttribute("barWidth")) != null ? _b : "0");
          ttCtx.xcrosshairsWidth = barWidth;
        } else {
          if (w.config.xaxis.crosshairs.width === "tickWidth") {
            const count = w.labelData.labels.length;
            ttCtx.xcrosshairsWidth = w.layout.gridWidth / count;
          }
        }
      }
      if (w.globals.isBarHorizontal) {
        ttCtx.xcrosshairsWidth = 0;
      }
      if (xcrosshairs !== null && ttCtx.xcrosshairsWidth > 0) {
        xcrosshairs.setAttribute("width", String(ttCtx.xcrosshairsWidth));
      }
    }
    handleYCrosshair() {
      const w = this.w;
      const ttCtx = this.ttCtx;
      ttCtx.ycrosshairs = w.dom.baseEl.querySelector(".apexcharts-ycrosshairs");
      ttCtx.ycrosshairsHidden = w.dom.baseEl.querySelector(
        ".apexcharts-ycrosshairs-hidden"
      );
    }
    /**
     * @param {number} index
     * @param {number} clientY
     * @param {import('../../types/internal').XYRatios} xyRatios
     */
    drawYaxisTooltipText(index, clientY, xyRatios) {
      const ttCtx = this.ttCtx;
      const w = this.w;
      const gl = w.globals;
      const yAxisSeriesArr = gl.seriesYAxisMap[index];
      if (ttCtx.yaxisTooltips[index] && yAxisSeriesArr.length > 0) {
        const lbFormatter = w.formatters.yLabelFormatters[index];
        const elGrid = ttCtx.getElGrid();
        if (!elGrid) return;
        const seriesBound = elGrid.getBoundingClientRect();
        const seriesIndex = yAxisSeriesArr[0];
        let translationsIndex = 0;
        if (xyRatios.yRatio.length > 1) {
          translationsIndex = seriesIndex;
        }
        const hoverY = (clientY - seriesBound.top) * xyRatios.yRatio[translationsIndex];
        const height = gl.maxYArr[seriesIndex] - gl.minYArr[seriesIndex];
        let val = gl.minYArr[seriesIndex] + (height - hoverY);
        if (w.config.yaxis[index].reversed) {
          val = gl.maxYArr[seriesIndex] - (height - hoverY);
        }
        ttCtx.tooltipPosition.moveYCrosshairs(clientY - seriesBound.top);
        ttCtx.yaxisTooltipText[index].innerHTML = lbFormatter(val);
        ttCtx.tooltipPosition.moveYAxisTooltip(index);
      }
    }
  }
  class Tooltip {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.tConfig = w.config.tooltip;
      this.tooltipUtil = new Utils(this);
      this.tooltipLabels = new Labels(this);
      this.tooltipPosition = new Position(this);
      this.marker = new Marker(this);
      this.intersect = new Intersect(this);
      this.axesTooltip = new AxesTooltip(this);
      this.showOnIntersect = this.tConfig.intersect;
      this.showTooltipTitle = this.tConfig.x.show;
      this.fixedTooltip = this.tConfig.fixed.enabled;
      this.xaxisTooltip = null;
      this.xaxisTooltipText = null;
      this.yaxisTooltip = null;
      this.yaxisTooltipText = null;
      this.yaxisTTEls = null;
      this.xaxisOffY = 0;
      this.yaxisOffX = 0;
      this.xcrosshairsWidth = 0;
      this.ycrosshairs = null;
      this.ycrosshairsHidden = null;
      this.tooltip = null;
      this.e = null;
      this.isBarShared = !w.globals.isBarHorizontal && this.tConfig.shared;
      this.lastHoverTime = Date.now();
      this.dimensionUpdateScheduled = false;
      this.xyRatios = null;
      this.isXAxisTooltipEnabled = false;
      this.yaxisTooltips = [];
      this.allTooltipSeriesGroups = [];
      this.xAxisTicksPositions = null;
      this.dataPointsDividedHeight = 0;
      this.dataPointsDividedWidth = 0;
      this.tooltipTitle = null;
      this.legendLabels = null;
      this.ttItems = null;
      this.seriesBound = null;
      this.seriesHoverTimeout = void 0;
      this.clientX = 0;
      this.clientY = 0;
      this.barSeriesHeight = 0;
      this.tooltipRect = { x: 0, y: 0, ttWidth: 0, ttHeight: 0 };
    }
    setupDimensionCache() {
      const w = this.w;
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return;
      this.updateDimensionCache();
      if (typeof ResizeObserver !== "undefined" && !w.globals.resizeObserver) {
        w.globals.resizeObserver = new ResizeObserver(() => {
          if (!this.dimensionUpdateScheduled) {
            this.dimensionUpdateScheduled = true;
            requestAnimationFrame(() => {
              this.updateDimensionCache();
              this.dimensionUpdateScheduled = false;
            });
          }
        });
        w.globals.resizeObserver.observe(tooltipEl);
      }
    }
    updateDimensionCache() {
      const w = this.w;
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return;
      const rect = tooltipEl.getBoundingClientRect();
      w.globals.dimensionCache.tooltip = /** @type {any} */
      {
        width: rect.width,
        height: rect.height,
        lastUpdate: Date.now()
      };
    }
    getCachedDimensions() {
      const w = this.w;
      if (w.globals.dimensionCache.tooltip) {
        const cache2 = (
          /** @type {Record<string,any>} */
          w.globals.dimensionCache.tooltip
        );
        const age = Date.now() - cache2.lastUpdate;
        if (age < 1e3) {
          return {
            ttWidth: cache2.width,
            ttHeight: cache2.height
          };
        }
      }
      this.updateDimensionCache();
      const cache = (
        /** @type {Record<string,any>} */
        w.globals.dimensionCache.tooltip
      );
      return cache ? {
        ttWidth: cache.width,
        ttHeight: cache.height
      } : { ttWidth: 0, ttHeight: 0 };
    }
    /**
     * @param {{ w: import('../../types/internal').ChartStateW }} [ctx]
     * @returns {HTMLElement | null}
     */
    getElTooltip(ctx) {
      if (!ctx) ctx = this;
      if (!ctx.w.dom.baseEl) return null;
      return (
        /** @type {HTMLElement | null} */
        ctx.w.dom.baseEl.querySelector(".apexcharts-tooltip")
      );
    }
    getElXCrosshairs() {
      return this.w.dom.baseEl.querySelector(".apexcharts-xcrosshairs");
    }
    getElGrid() {
      return this.w.dom.baseEl.querySelector(".apexcharts-grid");
    }
    /**
     * @param {import('../../types/internal').XYRatios} xyRatios
     */
    drawTooltip(xyRatios) {
      const w = this.w;
      this.xyRatios = xyRatios;
      this.isXAxisTooltipEnabled = w.config.xaxis.tooltip.enabled && w.globals.axisCharts;
      this.yaxisTooltips = w.config.yaxis.map((y) => {
        return y.show && y.tooltip.enabled && w.globals.axisCharts ? true : false;
      });
      this.allTooltipSeriesGroups = [];
      if (!w.globals.axisCharts) {
        this.showTooltipTitle = false;
      }
      const existingTooltip = this.getElTooltip();
      if (existingTooltip == null ? void 0 : existingTooltip.parentNode) {
        existingTooltip.parentNode.removeChild(existingTooltip);
      }
      this.tooltipTitle = null;
      const tooltipEl = BrowserAPIs.createElementNS(
        "http://www.w3.org/1999/xhtml",
        "div"
      );
      tooltipEl.classList.add("apexcharts-tooltip");
      if (w.config.tooltip.cssClass) {
        tooltipEl.classList.add(w.config.tooltip.cssClass);
      }
      tooltipEl.classList.add(`apexcharts-theme-${this.tConfig.theme || "light"}`);
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
        tooltipEl.setAttribute("role", "tooltip");
        tooltipEl.setAttribute("aria-live", "polite");
        tooltipEl.setAttribute("aria-atomic", "true");
        tooltipEl.setAttribute("aria-hidden", "true");
      }
      w.dom.elWrap.appendChild(tooltipEl);
      if (w.globals.axisCharts) {
        this.axesTooltip.drawXaxisTooltip();
        this.axesTooltip.drawYaxisTooltip();
        this.axesTooltip.setXCrosshairWidth();
        this.axesTooltip.handleYCrosshair();
        const xAxis = new XAxis(this.w, this.ctx, void 0);
        this.xAxisTicksPositions = xAxis.getXAxisTicksPositions();
      }
      if ((w.globals.comboCharts || this.tConfig.intersect || w.config.chart.type === "rangeBar") && !this.tConfig.shared) {
        this.showOnIntersect = true;
      }
      if (w.config.markers.size === 0 || w.globals.markers.largestSize === 0) {
        this.marker.drawDynamicPoints();
      }
      if (w.globals.collapsedSeries.length === w.seriesData.series.length) return;
      this.dataPointsDividedHeight = w.layout.gridHeight / w.globals.dataPoints;
      this.dataPointsDividedWidth = w.layout.gridWidth / w.globals.dataPoints;
      if (this.showTooltipTitle) {
        this.tooltipTitle = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        this.tooltipTitle.classList.add("apexcharts-tooltip-title");
        this.tooltipTitle.style.fontFamily = this.tConfig.style.fontFamily || w.config.chart.fontFamily;
        this.tooltipTitle.style.fontSize = this.tConfig.style.fontSize;
        tooltipEl.appendChild(this.tooltipTitle);
      }
      let ttItemsCnt = w.seriesData.series.length;
      if ((w.globals.xyCharts || w.globals.comboCharts) && this.tConfig.shared) {
        if (!this.showOnIntersect) {
          ttItemsCnt = w.seriesData.series.length;
        } else {
          ttItemsCnt = 1;
        }
      }
      this.legendLabels = w.dom.baseEl.querySelectorAll(".apexcharts-legend-text");
      this.ttItems = this.createTTElements(ttItemsCnt);
      this.addSVGEvents();
      this.setupDimensionCache();
    }
    /**
     * @param {number} ttItemsCnt
     */
    createTTElements(ttItemsCnt) {
      const w = this.w;
      const ttItems = [];
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return ttItems;
      for (let i = 0; i < ttItemsCnt; i++) {
        const gTxt = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        gTxt.classList.add(
          "apexcharts-tooltip-series-group",
          `apexcharts-tooltip-series-group-${i}`
        );
        gTxt.style.order = String(
          w.config.tooltip.inverseOrder ? ttItemsCnt - i : i + 1
        );
        const point = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "span"
        );
        point.classList.add("apexcharts-tooltip-marker");
        if (w.config.tooltip.fillSeriesColor) {
          point.style.backgroundColor = w.globals.colors[i];
        } else {
          point.style.color = w.globals.colors[i];
        }
        const mShape = w.config.markers.shape;
        let shape = mShape;
        if (Array.isArray(mShape)) {
          shape = mShape[i];
        }
        point.setAttribute("shape", shape);
        gTxt.appendChild(point);
        const gYZ = BrowserAPIs.createElementNS(
          "http://www.w3.org/1999/xhtml",
          "div"
        );
        gYZ.classList.add("apexcharts-tooltip-text");
        gYZ.style.fontFamily = this.tConfig.style.fontFamily || w.config.chart.fontFamily;
        gYZ.style.fontSize = this.tConfig.style.fontSize;
        ["y", "goals", "z"].forEach((g) => {
          const gValText = BrowserAPIs.createElementNS(
            "http://www.w3.org/1999/xhtml",
            "div"
          );
          gValText.classList.add(`apexcharts-tooltip-${g}-group`);
          const txtLabel = BrowserAPIs.createElementNS(
            "http://www.w3.org/1999/xhtml",
            "span"
          );
          txtLabel.classList.add(`apexcharts-tooltip-text-${g}-label`);
          gValText.appendChild(txtLabel);
          const txtValue = BrowserAPIs.createElementNS(
            "http://www.w3.org/1999/xhtml",
            "span"
          );
          txtValue.classList.add(`apexcharts-tooltip-text-${g}-value`);
          gValText.appendChild(txtValue);
          gYZ.appendChild(gValText);
        });
        gTxt.appendChild(gYZ);
        tooltipEl.appendChild(gTxt);
        ttItems.push(gTxt);
      }
      return ttItems;
    }
    addSVGEvents() {
      const w = this.w;
      const type = w.config.chart.type;
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return;
      const commonBar = !!(type === "bar" || type === "candlestick" || type === "boxPlot" || type === "rangeBar");
      const chartWithmarkers = type === "area" || type === "line" || type === "scatter" || type === "bubble" || type === "radar";
      const hoverArea = w.dom.Paper.node;
      const elGrid = this.getElGrid();
      if (elGrid) {
        this.seriesBound = elGrid.getBoundingClientRect();
      }
      const tooltipY = [];
      const tooltipX = [];
      const seriesHoverParams = {
        hoverArea,
        elGrid,
        tooltipEl,
        tooltipY,
        tooltipX,
        ttItems: this.ttItems
      };
      let points;
      if (w.globals.axisCharts) {
        if (chartWithmarkers) {
          points = w.dom.baseEl.querySelectorAll(
            ".apexcharts-series[data\\:longestSeries='true'] .apexcharts-marker"
          );
        } else if (commonBar) {
          points = w.dom.baseEl.querySelectorAll(
            ".apexcharts-series .apexcharts-bar-area, .apexcharts-series .apexcharts-candlestick-area, .apexcharts-series .apexcharts-boxPlot-area, .apexcharts-series .apexcharts-rangebar-area"
          );
        } else if (type === "heatmap" || type === "treemap") {
          points = w.dom.baseEl.querySelectorAll(
            ".apexcharts-series .apexcharts-heatmap, .apexcharts-series .apexcharts-treemap"
          );
        }
        if (points && points.length) {
          for (let p = 0; p < points.length; p++) {
            tooltipY.push(points[p].getAttribute("cy"));
            tooltipX.push(points[p].getAttribute("cx"));
          }
        }
      }
      const validSharedChartTypes = w.globals.xyCharts && !this.showOnIntersect || w.globals.comboCharts && !this.showOnIntersect || commonBar && this.tooltipUtil.hasBars() && this.tConfig.shared;
      if (validSharedChartTypes) {
        this.addPathsEventListeners([hoverArea], seriesHoverParams);
      } else if (commonBar && !w.globals.comboCharts || chartWithmarkers && this.showOnIntersect) {
        this.addDatapointEventsListeners(seriesHoverParams);
      } else if (!w.globals.axisCharts || type === "heatmap" || type === "treemap") {
        const seriesAll = w.dom.baseEl.querySelectorAll(".apexcharts-series");
        this.addPathsEventListeners(seriesAll, seriesHoverParams);
      }
      if (this.showOnIntersect) {
        const lineAreaPoints = w.dom.baseEl.querySelectorAll(
          ".apexcharts-line-series .apexcharts-marker, .apexcharts-area-series .apexcharts-marker"
        );
        if (lineAreaPoints.length > 0) {
          this.addPathsEventListeners(lineAreaPoints, seriesHoverParams);
        }
        if (this.tooltipUtil.hasBars() && !this.tConfig.shared) {
          this.addDatapointEventsListeners(seriesHoverParams);
        }
      }
    }
    drawFixedTooltipRect() {
      const w = this.w;
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return { x: 0, y: 0, ttWidth: 0, ttHeight: 0 };
      const tooltipRect = tooltipEl.getBoundingClientRect();
      const ttWidth = tooltipRect.width + 10;
      const ttHeight = tooltipRect.height + 10;
      let x = this.tConfig.fixed.offsetX;
      let y = this.tConfig.fixed.offsetY;
      const fixed = this.tConfig.fixed.position.toLowerCase();
      if (fixed.indexOf("right") > -1) {
        x = x + w.globals.svgWidth - ttWidth + 10;
      }
      if (fixed.indexOf("bottom") > -1) {
        y = y + w.globals.svgHeight - ttHeight - 10;
      }
      tooltipEl.style.left = x + "px";
      tooltipEl.style.top = y + "px";
      return {
        x,
        y,
        ttWidth,
        ttHeight
      };
    }
    /**
     * @param {Record<string, any>} seriesHoverParams
     */
    addDatapointEventsListeners(seriesHoverParams) {
      const w = this.w;
      const points = w.dom.baseEl.querySelectorAll(
        ".apexcharts-series-markers .apexcharts-marker, .apexcharts-bar-area, .apexcharts-candlestick-area, .apexcharts-boxPlot-area, .apexcharts-rangebar-area"
      );
      this.addPathsEventListeners(points, seriesHoverParams);
    }
    /**
     * @param {any} paths
     * @param {Record<string, any>} opts
     */
    addPathsEventListeners(paths, opts) {
      const self2 = this;
      for (let p = 0; p < paths.length; p++) {
        const extendedOpts = {
          paths: paths[p],
          tooltipEl: opts.tooltipEl,
          tooltipY: opts.tooltipY,
          tooltipX: opts.tooltipX,
          elGrid: opts.elGrid,
          hoverArea: opts.hoverArea,
          ttItems: opts.ttItems
        };
        const events = [
          "mousemove",
          "mouseup",
          "touchmove",
          "mouseout",
          "touchend"
        ];
        events.map((ev) => {
          return paths[p].addEventListener(
            ev,
            self2.onSeriesHover.bind(self2, extendedOpts),
            { capture: false, passive: true }
          );
        });
      }
    }
    /*
     ** Check to see if the tooltips should be updated based on a mouse / touch event
     * @param {Record<string, any>} opt
     * @param {Event} e
     */
    /** @param {Record<string, any>} opt @param {any} e */
    onSeriesHover(opt, e) {
      const targetDelay = 20;
      const timeSinceLastUpdate = Date.now() - this.lastHoverTime;
      if (timeSinceLastUpdate >= targetDelay) {
        this.seriesHover(opt, e);
      } else {
        clearTimeout(this.seriesHoverTimeout);
        this.seriesHoverTimeout = setTimeout(() => {
          this.seriesHover(opt, e);
        }, targetDelay - timeSinceLastUpdate);
      }
    }
    /*
     ** The actual series hover function
     * @param {Record<string, any>} opt
     * @param {Event} e
     */
    /** @param {Record<string, any>} opt @param {any} e */
    seriesHover(opt, e) {
      this.lastHoverTime = Date.now();
      let chartGroups = [];
      const w = this.w;
      if (w.config.chart.group) {
        chartGroups = this.ctx.getGroupedCharts();
      }
      if (w.globals.axisCharts && (w.globals.minX === -Infinity && w.globals.maxX === Infinity || w.globals.dataPoints === 0)) {
        return;
      }
      if (chartGroups.length) {
        chartGroups.forEach((ch) => {
          const tooltipEl = this.getElTooltip(ch);
          const newOpts = {
            paths: opt.paths,
            tooltipEl,
            tooltipY: opt.tooltipY,
            tooltipX: opt.tooltipX,
            elGrid: opt.elGrid,
            hoverArea: opt.hoverArea,
            ttItems: ch.w.globals.tooltip.ttItems
          };
          if (ch.w.globals.minX === this.w.globals.minX && ch.w.globals.maxX === this.w.globals.maxX) {
            ch.w.globals.tooltip.seriesHoverByContext({
              chartCtx: ch,
              ttCtx: ch.w.globals.tooltip,
              opt: newOpts,
              e
            });
          }
        });
      } else {
        this.seriesHoverByContext({
          chartCtx: this.ctx,
          ttCtx: this.w.globals.tooltip,
          opt,
          e
        });
      }
    }
    /** @param {{chartCtx: any, ttCtx: any, opt: any, e: any}} opts */
    seriesHoverByContext({ chartCtx, ttCtx, opt, e }) {
      const w = chartCtx.w;
      const tooltipEl = this.getElTooltip(chartCtx);
      if (!tooltipEl) return;
      const cachedDims = ttCtx.getCachedDimensions();
      ttCtx.tooltipRect = {
        x: 0,
        y: 0,
        ttWidth: cachedDims.ttWidth,
        ttHeight: cachedDims.ttHeight
      };
      ttCtx.e = e;
      if (ttCtx.tooltipUtil.hasBars() && !w.globals.comboCharts && !ttCtx.isBarShared) {
        if (this.tConfig.onDatasetHover.highlightDataSeries) {
          const series = new Series(chartCtx.w);
          series.toggleSeriesOnHover(e, e.target.parentNode);
        }
      }
      if (w.globals.axisCharts) {
        ttCtx.axisChartsTooltips({
          e,
          opt,
          tooltipRect: ttCtx.tooltipRect
        });
      } else {
        ttCtx.nonAxisChartsTooltips({
          e,
          opt,
          tooltipRect: ttCtx.tooltipRect
        });
      }
      if (ttCtx.fixedTooltip) {
        ttCtx.drawFixedTooltipRect();
      }
    }
    // tooltip handling for line/area/bar/columns/scatter
    /** @param {{e: any, opt: any}} opts */
    axisChartsTooltips({ e, opt }) {
      var _a;
      const w = this.w;
      let x, y;
      const seriesBound = opt.elGrid.getBoundingClientRect();
      const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
      const clientY = e.type === "touchmove" ? e.touches[0].clientY : e.clientY;
      this.clientY = clientY;
      this.clientX = clientX;
      w.interact.capturedSeriesIndex = -1;
      w.interact.capturedDataPointIndex = -1;
      if (clientY < seriesBound.top || clientY > seriesBound.top + seriesBound.height) {
        this.handleMouseOut(opt);
        return;
      }
      if (Array.isArray(this.tConfig.enabledOnSeries) && !w.config.tooltip.shared) {
        const index = parseInt(opt.paths.getAttribute("index"), 10);
        if (this.tConfig.enabledOnSeries.indexOf(index) < 0) {
          this.handleMouseOut(opt);
          return;
        }
      }
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return;
      const xcrosshairs = this.getElXCrosshairs();
      let syncedCharts = [];
      if (w.config.chart.group) {
        syncedCharts = this.ctx.getSyncedCharts();
      }
      const isStickyTooltip = w.globals.xyCharts || w.config.chart.type === "bar" && !w.globals.isBarHorizontal && this.tooltipUtil.hasBars() && this.tConfig.shared || w.globals.comboCharts && this.tooltipUtil.hasBars();
      if (e.type === "mousemove" || e.type === "touchmove" || e.type === "mouseup") {
        if (w.globals.collapsedSeries.length + w.globals.ancillaryCollapsedSeries.length === w.seriesData.series.length) {
          return;
        }
        if (xcrosshairs !== null) {
          xcrosshairs.classList.add("apexcharts-active");
        }
        const hasYAxisTooltip = (_a = this.yaxisTooltips) == null ? void 0 : _a.filter(
          (b) => {
            return b === true;
          }
        );
        const _yc = (
          /** @type {any} */
          this.ycrosshairs
        );
        if (_yc !== null && (hasYAxisTooltip == null ? void 0 : hasYAxisTooltip.length)) {
          _yc.classList.add("apexcharts-active");
        }
        if (isStickyTooltip && !this.showOnIntersect || syncedCharts.length > 1) {
          this.handleStickyTooltip(e, clientX, clientY, opt);
        } else {
          if (w.config.chart.type === "heatmap" || w.config.chart.type === "treemap") {
            const markerXY = this.intersect.handleHeatTreeTooltip({
              e,
              opt,
              x,
              y,
              type: w.config.chart.type
            });
            x = markerXY.x;
            y = markerXY.y;
            tooltipEl.style.left = x + "px";
            tooltipEl.style.top = y + "px";
          } else {
            if (this.tooltipUtil.hasBars()) {
              this.intersect.handleBarTooltip({
                e,
                opt
              });
            }
            if (this.tooltipUtil.hasMarkers(0)) {
              this.intersect.handleMarkerTooltip({
                e,
                opt,
                x,
                y
              });
            }
          }
        }
        if (this.yaxisTooltips && this.yaxisTooltips.length) {
          for (let yt = 0; yt < w.config.yaxis.length; yt++) {
            this.axesTooltip.drawYaxisTooltipText(
              yt,
              clientY,
              /** @type {import('../../types/internal').XYRatios} */
              this.xyRatios
            );
          }
        }
        w.dom.baseEl.classList.add("apexcharts-tooltip-active");
        opt.tooltipEl.classList.add("apexcharts-active");
        if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
          opt.tooltipEl.removeAttribute("aria-hidden");
        }
      } else if (e.type === "mouseout" || e.type === "touchend") {
        this.handleMouseOut(opt);
      }
    }
    // tooltip handling for pie/donuts
    /** @param {{e: any, opt: any, tooltipRect: any}} opts */
    nonAxisChartsTooltips({ e, opt, tooltipRect }) {
      var _a, _b, _c, _d;
      const w = this.w;
      const rel = opt.paths.getAttribute("rel");
      const tooltipEl = this.getElTooltip();
      if (!tooltipEl) return;
      const seriesBound = w.dom.elWrap.getBoundingClientRect();
      if (e.type === "mousemove" || e.type === "touchmove") {
        w.dom.baseEl.classList.add("apexcharts-tooltip-active");
        tooltipEl.classList.add("apexcharts-active");
        if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
          tooltipEl.removeAttribute("aria-hidden");
        }
        this.tooltipLabels.drawSeriesTexts({
          ttItems: opt.ttItems,
          i: parseInt(rel, 10) - 1,
          shared: false
        });
        let x, y;
        const arcPath = opt.paths.querySelector("path[data\\:cx]") || opt.paths;
        if (w.config.tooltip.intersect && arcPath.hasAttribute("data:cx") && arcPath.hasAttribute("data:cy")) {
          const svgBound = w.dom.Paper.node.getBoundingClientRect();
          x = svgBound.left - seriesBound.left + parseFloat(arcPath.getAttribute("data:cx")) - tooltipRect.ttWidth / 2;
          y = svgBound.top - seriesBound.top + parseFloat(arcPath.getAttribute("data:cy")) - tooltipRect.ttHeight - 10;
        } else {
          x = ((_a = w.interact.clientX) != null ? _a : 0) - seriesBound.left - tooltipRect.ttWidth / 2;
          y = ((_b = w.interact.clientY) != null ? _b : 0) - seriesBound.top - tooltipRect.ttHeight - 10;
        }
        tooltipEl.style.left = x + "px";
        tooltipEl.style.top = y + "px";
        if (w.config.legend.tooltipHoverFormatter) {
          const legendFormatter = w.config.legend.tooltipHoverFormatter;
          const i = rel - 1;
          const legendEl = (
            /** @type {HTMLElement | undefined} */
            (_c = this.legendLabels) == null ? void 0 : _c[i]
          );
          if (!legendEl) return;
          const legendName = legendEl.getAttribute("data:default-text");
          const text = legendFormatter(legendName, {
            seriesIndex: i,
            dataPointIndex: i,
            w
          });
          legendEl.innerHTML = text;
        }
      } else if (e.type === "mouseout" || e.type === "touchend") {
        tooltipEl.classList.remove("apexcharts-active");
        w.dom.baseEl.classList.remove("apexcharts-tooltip-active");
        if (w.config.legend.tooltipHoverFormatter) {
          (_d = this.legendLabels) == null ? void 0 : _d.forEach((l) => {
            const defaultText = l.getAttribute("data:default-text");
            l.innerHTML = decodeURIComponent(
              defaultText != null ? defaultText : ""
            );
          });
        }
      }
    }
    /**
     * @param {Event} e
     * @param {number} clientX
     * @param {number} clientY
     * @param {Record<string, any>} opt
     */
    handleStickyTooltip(e, clientX, clientY, opt) {
      const w = this.w;
      const capj = this.tooltipUtil.getNearestValues({
        context: this,
        hoverArea: opt.hoverArea,
        elGrid: opt.elGrid,
        clientX,
        clientY
      });
      const j = capj.j;
      let capturedSeries = capj.capturedSeries;
      if (capturedSeries !== null && w.globals.collapsedSeriesIndices.includes(capturedSeries != null ? capturedSeries : -1))
        capturedSeries = null;
      const bounds = opt.elGrid.getBoundingClientRect();
      if (capj.hoverX < 0 || capj.hoverX > bounds.width) {
        this.handleMouseOut(opt);
        return;
      }
      if (capturedSeries !== null) {
        this.handleStickyCapturedSeries(e, capturedSeries != null ? capturedSeries : -1, opt, j != null ? j : 0);
      } else {
        if (this.tooltipUtil.isXoverlap(j != null ? j : 0) || w.globals.isBarHorizontal) {
          const firstVisibleSeries = w.seriesData.series.findIndex(
            /**
             * @param {any} s
             * @param {number} i
             */
            (s, i) => !w.globals.collapsedSeriesIndices.includes(i)
          );
          this.create(e, this, firstVisibleSeries, j != null ? j : 0, opt.ttItems);
        }
      }
    }
    /**
     * @param {Event} e
     * @param {number} capturedSeries
     * @param {Record<string, any>} opt
     * @param {number} j
     */
    handleStickyCapturedSeries(e, capturedSeries, opt, j) {
      const w = this.w;
      if (!this.tConfig.shared) {
        const ignoreNull = w.seriesData.series[capturedSeries][j] === null;
        if (ignoreNull) {
          this.handleMouseOut(opt);
          return;
        }
      }
      if (typeof w.seriesData.series[capturedSeries][j] !== "undefined") {
        if (this.tConfig.shared && this.tooltipUtil.isXoverlap(j) && this.tooltipUtil.isInitialSeriesSameLen()) {
          this.create(e, this, capturedSeries, j, opt.ttItems);
        } else {
          this.create(e, this, capturedSeries, j, opt.ttItems, false);
        }
      } else {
        if (this.tooltipUtil.isXoverlap(j)) {
          const firstVisibleSeries = w.seriesData.series.findIndex(
            /**
             * @param {any} s
             * @param {number} i
             */
            (s, i) => !w.globals.collapsedSeriesIndices.includes(i)
          );
          this.create(e, this, firstVisibleSeries, j, opt.ttItems);
        }
      }
    }
    deactivateHoverFilter() {
      const w = this.w;
      const graphics = new Graphics(this.w, this.ctx);
      const allPaths = w.dom.Paper.find(`.apexcharts-bar-area`);
      for (let b = 0; b < allPaths.length; b++) {
        graphics.pathMouseLeave(
          /** @type {any} */
          allPaths[b],
          /** @type {any} */
          void 0
        );
      }
    }
    /**
     * @param {Record<string, any>} opt
     */
    handleMouseOut(opt) {
      var _a, _b;
      const w = this.w;
      const xcrosshairs = this.getElXCrosshairs();
      w.dom.baseEl.classList.remove("apexcharts-tooltip-active");
      opt.tooltipEl.classList.remove("apexcharts-active");
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
        opt.tooltipEl.setAttribute("aria-hidden", "true");
      }
      this.deactivateHoverFilter();
      if (w.config.chart.type !== "bubble") {
        this.marker.resetPointsSize();
      }
      if (xcrosshairs !== null) {
        xcrosshairs.classList.remove("apexcharts-active");
      }
      const _yc2 = (
        /** @type {any} */
        this.ycrosshairs
      );
      if (_yc2 !== null) {
        _yc2.classList.remove("apexcharts-active");
      }
      if (this.isXAxisTooltipEnabled) {
        (_a = this.xaxisTooltip) == null ? void 0 : _a.classList.remove("apexcharts-active");
      }
      if (this.yaxisTooltips && this.yaxisTooltips.length) {
        if (this.yaxisTTEls === null) {
          this.yaxisTTEls = /** @type {HTMLElement[]} */
          [
            ...w.dom.baseEl.querySelectorAll(".apexcharts-yaxistooltip")
          ];
        }
        for (let i = 0; i < this.yaxisTTEls.length; i++) {
          this.yaxisTTEls[i].classList.remove("apexcharts-active");
        }
      }
      if (w.config.legend.tooltipHoverFormatter) {
        (_b = this.legendLabels) == null ? void 0 : _b.forEach((l) => {
          const defaultText = l.getAttribute("data:default-text");
          l.innerHTML = decodeURIComponent(
            defaultText != null ? defaultText : ""
          );
        });
      }
    }
    /**
     * @param {Event} e
     * @param {number} seriesIndex
     * @param {number} dataPointIndex
     */
    markerClick(e, seriesIndex, dataPointIndex) {
      const w = this.w;
      if (typeof w.config.chart.events.markerClick === "function") {
        w.config.chart.events.markerClick(e, this.ctx, {
          seriesIndex,
          dataPointIndex,
          w
        });
      }
      this.ctx.events.fireEvent("markerClick", [
        e,
        this.ctx,
        { seriesIndex, dataPointIndex, w }
      ]);
    }
    /**
     * @param {Event} e
     * @param {any} context
     * @param {number} capturedSeries
     * @param {number} j
     * @param {any} ttItems
     * @param {boolean | null} shared
     */
    create(e, context, capturedSeries, j, ttItems, shared = null) {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
      const w = this.w;
      const ttCtx = context;
      if (e.type === "mouseup") {
        this.markerClick(e, capturedSeries, j);
      }
      if (shared === null) shared = this.tConfig.shared;
      const hasMarkers = this.tooltipUtil.hasMarkers(capturedSeries);
      const bars = this.tooltipUtil.getElBars();
      const handlePoints = () => {
        if (w.globals.markers.largestSize > 0) {
          ttCtx.marker.enlargePoints(j);
        } else {
          ttCtx.tooltipPosition.moveDynamicPointsOnHover(j);
        }
      };
      if (w.config.legend.tooltipHoverFormatter) {
        const legendFormatter = w.config.legend.tooltipHoverFormatter;
        const els = (
          /** @type {HTMLElement[]} */
          Array.from((_a = this.legendLabels) != null ? _a : [])
        );
        els.forEach((l) => {
          const legendName = l.getAttribute("data:default-text");
          l.innerHTML = decodeURIComponent(legendName != null ? legendName : "");
        });
        for (let i = 0; i < els.length; i++) {
          const l = els[i];
          const lsIndex = parseInt((_b = l.getAttribute("i")) != null ? _b : "", 10);
          const legendName = decodeURIComponent(
            (_c = l.getAttribute("data:default-text")) != null ? _c : ""
          );
          const text = legendFormatter(legendName, {
            seriesIndex: shared ? lsIndex : capturedSeries,
            dataPointIndex: j,
            w
          });
          if (!shared) {
            l.innerHTML = lsIndex === capturedSeries ? text : legendName;
            if (capturedSeries === lsIndex) {
              break;
            }
          } else {
            l.innerHTML = w.globals.collapsedSeriesIndices.indexOf(lsIndex) < 0 ? text : legendName;
          }
        }
      }
      const _rangeData = (
        /** @type {any} */
        w.rangeData
      );
      const commonSeriesTextsParams = __spreadValues(__spreadValues({
        ttItems,
        i: capturedSeries,
        j
      }, ((_g = (_f = (_e = (_d = _rangeData.seriesRange) == null ? void 0 : _d[capturedSeries]) == null ? void 0 : _e[j]) == null ? void 0 : _f.y[0]) == null ? void 0 : _g.y1) !== void 0 && {
        y1: (_k = (_j = (_i = (_h = _rangeData.seriesRange) == null ? void 0 : _h[capturedSeries]) == null ? void 0 : _i[j]) == null ? void 0 : _j.y[0]) == null ? void 0 : _k.y1
      }), ((_o = (_n = (_m = (_l = _rangeData.seriesRange) == null ? void 0 : _l[capturedSeries]) == null ? void 0 : _m[j]) == null ? void 0 : _n.y[0]) == null ? void 0 : _o.y2) !== void 0 && {
        y2: (_s = (_r = (_q = (_p = _rangeData.seriesRange) == null ? void 0 : _p[capturedSeries]) == null ? void 0 : _q[j]) == null ? void 0 : _r.y[0]) == null ? void 0 : _s.y2
      });
      if (shared) {
        ttCtx.tooltipLabels.drawSeriesTexts(__spreadProps(__spreadValues({}, commonSeriesTextsParams), {
          shared: this.showOnIntersect ? false : this.tConfig.shared
        }));
        if (hasMarkers) {
          handlePoints();
        } else if (this.tooltipUtil.hasBars()) {
          this.barSeriesHeight = this.tooltipUtil.getBarsHeight(
            /** @type {any[]} */
            [...bars]
          );
          if (this.barSeriesHeight > 0) {
            const graphics = new Graphics(this.w, this.ctx);
            const paths = w.dom.Paper.find(`.apexcharts-bar-area[j='${j}']`);
            this.deactivateHoverFilter();
            const points = ttCtx.tooltipUtil.getAllMarkers(true);
            if (points.length && !this.barSeriesHeight) {
              handlePoints();
            }
            ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, capturedSeries);
            for (let b = 0; b < paths.length; b++) {
              graphics.pathMouseEnter(
                /** @type {any} */
                paths[b],
                /** @type {any} */
                void 0
              );
            }
          }
        }
      } else {
        ttCtx.tooltipLabels.drawSeriesTexts(__spreadValues({
          shared: false
        }, commonSeriesTextsParams));
        if (this.tooltipUtil.hasBars()) {
          ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, capturedSeries);
        }
        if (hasMarkers) {
          ttCtx.tooltipPosition.moveMarkers(capturedSeries, j);
        }
      }
    }
  }
  class SVGElement {
    /**
     * @param {any} node
     */
    constructor(node) {
      this.node = node;
      if (node) {
        node.instance = this;
      }
      this._listeners = [];
      this._filter = null;
    }
    // ---- Attribute methods ----
    /**
     * @param {any} a
     * @param {any} [v]
     */
    attr(a, v) {
      if (typeof a === "string" && v === void 0) {
        return this.node.getAttribute(a);
      }
      const attrs = typeof a === "string" ? { [a]: v } : a;
      for (const key in attrs) {
        let val = attrs[key];
        if (val === null) {
          this.node.removeAttribute(key);
        } else if (val !== void 0) {
          if (typeof val === "number" && isNaN(val)) val = 0;
          this.node.setAttribute(key, val);
        }
      }
      if (this.node.nodeName === "text" && attrs.x != null) {
        const tspans = this.node.querySelectorAll("tspan[data-newline]");
        for (let i = 0; i < tspans.length; i++) {
          tspans[i].setAttribute("x", attrs.x);
        }
      }
      return this;
    }
    /**
     * @param {Record<string, string>} styles
     */
    css(styles) {
      for (const k in styles) {
        this.node.style[k] = styles[k];
      }
      return this;
    }
    /**
     * @param {any} v
     */
    fill(v) {
      if (typeof v === "object") {
        return this.attr(v);
      }
      return this.attr("fill", v);
    }
    /**
     * @param {any} v
     */
    stroke(v) {
      if (typeof v === "object") {
        if (v.color !== void 0) this.attr("stroke", v.color);
        if (v.width !== void 0) this.attr("stroke-width", v.width);
        if (v.dasharray !== void 0) this.attr("stroke-dasharray", v.dasharray);
        if (v.linecap !== void 0) this.attr("stroke-linecap", v.linecap);
        if (v.opacity !== void 0) this.attr("stroke-opacity", v.opacity);
        return this;
      }
      return this.attr("stroke", v);
    }
    /**
     * @param {number} w
     * @param {number} h
     */
    size(w, h) {
      return this.attr({ width: w, height: h });
    }
    /**
     * @param {number} x
     * @param {number} y
     */
    move(x, y) {
      return this.attr({ x, y });
    }
    /**
     * @param {number} cx
     * @param {number} cy
     */
    center(cx, cy) {
      if (this.node.nodeName === "g") {
        const box = this.bbox();
        const dx = cx - (box.x + box.width / 2);
        const dy = cy - (box.y + box.height / 2);
        return this.attr("transform", `translate(${dx}, ${dy})`);
      }
      return this.attr({ cx, cy });
    }
    // ---- Tree operations ----
    /**
     * @param {any} child
     */
    add(child) {
      this.node.appendChild(child.node || child);
      return this;
    }
    /**
     * @param {any} parent
     */
    addTo(parent) {
      const p = parent.node || parent;
      p.appendChild(this.node);
      return this;
    }
    remove() {
      if (this.node.parentNode) {
        this.node.parentNode.removeChild(this.node);
      }
      return this;
    }
    clear() {
      while (this.node.firstChild) {
        this.node.removeChild(this.node.firstChild);
      }
      return this;
    }
    // ---- Query ----
    /**
     * @param {string} selector
     */
    find(selector) {
      return Array.from(this.node.querySelectorAll(selector)).map(
        (n) => n.instance || new SVGElement(n)
      );
    }
    /**
     * @param {string} selector
     */
    findOne(selector) {
      const n = this.node.querySelector(selector);
      return n ? n.instance || new SVGElement(n) : null;
    }
    // ---- Events ----
    /**
     * @param {Event} event
     * @param {Function} handler
     */
    on(event, handler) {
      const eventType = (
        /** @type {string} */
        /** @type {any} */
        event.split(
          "."
        )[0]
      );
      this._listeners.push({ event, eventType, handler });
      this.node.addEventListener(eventType, handler);
      return this;
    }
    /**
     * @param {Event} event
     * @param {Function} handler
     */
    off(event, handler) {
      if (!event && !handler) {
        this._listeners.forEach((l) => {
          this.node.removeEventListener(l.eventType, l.handler);
        });
        this._listeners = [];
      } else if (event && !handler) {
        const eventType = (
          /** @type {string} */
          /** @type {any} */
          event.split(".")[0]
        );
        this._listeners = this._listeners.filter((l) => {
          if (l.eventType === eventType) {
            this.node.removeEventListener(l.eventType, l.handler);
            return false;
          }
          return true;
        });
      } else {
        const eventType = (
          /** @type {string} */
          /** @type {any} */
          event.split(".")[0]
        );
        this._listeners = this._listeners.filter((l) => {
          if (l.eventType === eventType && l.handler === handler) {
            this.node.removeEventListener(l.eventType, l.handler);
            return false;
          }
          return true;
        });
      }
      return this;
    }
    // ---- Iteration ----
    /**
     * @param {Function} fn
     * @param {boolean} deep
     */
    each(fn, deep) {
      const children = Array.from(this.node.children);
      children.forEach((child) => {
        const inst = child.instance || new SVGElement(child);
        fn.call(inst);
        if (deep) inst.each(fn, deep);
      });
      return this;
    }
    // ---- CSS classes ----
    /**
     * @param {string} cls
     */
    removeClass(cls) {
      if (cls === "*") {
        this.node.removeAttribute("class");
      } else {
        this.node.classList.remove(cls);
      }
      return this;
    }
    // ---- Children ----
    children() {
      return Array.from(this.node.childNodes).filter((n) => n.nodeType === 1).map((n) => n.instance || new SVGElement(n));
    }
    // ---- Visibility ----
    hide() {
      this.node.style.display = "none";
      return this;
    }
    show() {
      this.node.style.display = "";
      return this;
    }
    // ---- Measurement ----
    bbox() {
      if (typeof this.node.getBBox === "function") {
        try {
          return this.node.getBBox();
        } catch (e) {
        }
      }
      return { x: 0, y: 0, width: 0, height: 0 };
    }
    // ---- Text-specific ----
    /**
     * @param {string} text
     */
    tspan(text) {
      const tspan = BrowserAPIs.createElementNS(
        "http://www.w3.org/2000/svg",
        "tspan"
      );
      tspan.textContent = text;
      this.node.appendChild(tspan);
      return new SVGElement(tspan);
    }
    // ---- Path-specific ----
    /**
     * @param {string} d
     */
    plot(d) {
      if (typeof d === "string") {
        this.attr("d", d);
      }
      return this;
    }
    // ---- Animation (overridden by SVGAnimation mixin) ----
    animate() {
      throw new Error("Animation module not loaded");
    }
    // ---- Filter methods (set up by SVGFilter module) ----
    filterWith() {
      throw new Error("Filter module not loaded");
    }
    /**
     * @param {boolean} all
     */
    unfilter(all) {
      if (this._filter) {
        this.node.removeAttribute("filter");
        if (all && this._filter.node && this._filter.node.parentNode) {
          this._filter.node.parentNode.removeChild(this._filter.node);
        }
        this._filter = null;
      }
      return this;
    }
    filterer() {
      return this._filter;
    }
  }
  let gradientCounter = 0;
  class SVGGradient extends SVGElement {
    /**
     * @param {any} container
     * @param {string} type
     * @param {object} builder
     */
    constructor(container, type, builder) {
      const tag = type === "radial" ? "radialGradient" : "linearGradient";
      const node = BrowserAPIs.createElementNS(SVGNS, tag);
      super(node);
      this._id = "SvgjsGradient" + ++gradientCounter;
      this.attr("id", this._id);
      if (typeof builder === "function") {
        builder(new StopBuilder(this));
      }
      let defs = container.node.querySelector("defs");
      if (!defs) {
        defs = BrowserAPIs.createElementNS(SVGNS, "defs");
        container.node.appendChild(defs);
      }
      defs.appendChild(this.node);
    }
    /**
     * @param {any} offset
     * @param {string} color
     * @param {number} opacity
     */
    stop(offset, color, opacity) {
      const s = BrowserAPIs.createElementNS(SVGNS, "stop");
      s.setAttribute("offset", offset);
      s.setAttribute("stop-color", color);
      if (opacity !== void 0) s.setAttribute("stop-opacity", String(opacity));
      this.node.appendChild(s);
      return this;
    }
    /**
     * @param {number} x
     * @param {number} y
     */
    from(x, y) {
      return this.attr({ x1: x, y1: y });
    }
    /**
     * @param {number} x
     * @param {number} y
     */
    to(x, y) {
      return this.attr({ x2: x, y2: y });
    }
    url() {
      return "url(#" + this._id + ")";
    }
    toString() {
      return this.url();
    }
    valueOf() {
      return this.url();
    }
    fill() {
      return this.url();
    }
  }
  class StopBuilder {
    /**
     * @param {any} gradient
     */
    constructor(gradient) {
      this.gradient = gradient;
    }
    /**
     * @param {any} offset
     * @param {string} color
     * @param {number} opacity
     */
    stop(offset, color, opacity) {
      this.gradient.stop(offset, color, opacity);
      return this;
    }
  }
  let patternCounter = 0;
  class SVGPattern extends SVGElement {
    /**
     * @param {any} container
     * @param {number} w
     * @param {number} h
     * @param {Function} builder
     */
    constructor(container, w, h, builder) {
      const node = BrowserAPIs.createElementNS(SVGNS, "pattern");
      super(node);
      this._id = "SvgjsPattern" + ++patternCounter;
      this.attr({
        id: this._id,
        width: w,
        height: h,
        patternUnits: "userSpaceOnUse"
      });
      if (typeof builder === "function") {
        const patternContainer = new SVGContainer(this.node);
        builder(patternContainer);
      }
      let defs = container.node.querySelector("defs");
      if (!defs) {
        defs = BrowserAPIs.createElementNS(SVGNS, "defs");
        container.node.appendChild(defs);
      }
      defs.appendChild(this.node);
    }
    url() {
      return "url(#" + this._id + ")";
    }
    toString() {
      return this.url();
    }
    valueOf() {
      return this.url();
    }
    fill() {
      return this.url();
    }
  }
  class SVGContainer extends SVGElement {
    /**
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     */
    line(x1, y1, x2, y2) {
      const el = this._make("line");
      if (x1 !== void 0) {
        el.attr({ x1, y1, x2, y2 });
      }
      return el;
    }
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {number} h
     */
    rect(w, h) {
      const el = this._make("rect");
      if (w !== void 0) {
        el.attr({ width: w, height: h });
      }
      return el;
    }
    /**
     * @param {number} d
     */
    circle(d) {
      const el = this._make("circle");
      if (d !== void 0) {
        el.attr({ r: d / 2, cx: d / 2, cy: d / 2 });
      }
      return el;
    }
    /**
     * @param {string} d
     */
    path(d) {
      const el = this._make("path");
      if (d) el.attr("d", d);
      return el;
    }
    /**
     * @param {string} pts
     */
    polygon(pts) {
      const el = this._make("polygon");
      if (pts) el.attr("points", pts);
      return el;
    }
    group() {
      return this._makeContainer("g");
    }
    defs() {
      return this._makeContainer("defs");
    }
    /**
     * @param {string} textContent
     */
    plain(textContent) {
      const node = BrowserAPIs.createElementNS(SVGNS, "text");
      node.textContent = textContent;
      const el = new SVGElement(node);
      this.node.appendChild(node);
      return el;
    }
    /**
     * @param {object} builder
     */
    text(builder) {
      const node = BrowserAPIs.createElementNS(SVGNS, "text");
      const el = new SVGElement(node);
      this.node.appendChild(node);
      if (typeof builder === "function") {
        builder(new TspanBuilder(node));
      }
      return el;
    }
    /**
     * @param {string} url
     * @param {Function} callback
     */
    image(url, callback) {
      const node = BrowserAPIs.createElementNS(SVGNS, "image");
      node.setAttributeNS("http://www.w3.org/1999/xlink", "href", url);
      const el = new SVGElement(node);
      this.node.appendChild(node);
      if (typeof callback === "function") {
        const img = new Image();
        img.onload = function() {
          el.size(img.width, img.height);
          callback.call(el, { width: img.width, height: img.height });
        };
        img.src = url;
      }
      return el;
    }
    /**
     * @param {string} type
     * @param {object} builder
     */
    gradient(type, builder) {
      return new SVGGradient(this, type, builder);
    }
    /**
     * @param {number} w
     * @param {number} h
     * @param {Function} builder
     */
    pattern(w, h, builder) {
      return new SVGPattern(this, w, h, builder);
    }
    /**
     * @param {string} tag
     */
    _make(tag) {
      const node = BrowserAPIs.createElementNS(SVGNS, tag);
      this.node.appendChild(node);
      return new SVGElement(node);
    }
    /**
     * @param {string} tag
     */
    _makeContainer(tag) {
      const node = BrowserAPIs.createElementNS(SVGNS, tag);
      this.node.appendChild(node);
      return new SVGContainer(node);
    }
  }
  class TspanBuilder {
    /**
     * @param {any} textNode
     */
    constructor(textNode) {
      this.textNode = textNode;
    }
    /**
     * @param {string} text
     */
    tspan(text) {
      const tspan = BrowserAPIs.createElementNS(SVGNS, "tspan");
      tspan.textContent = text;
      this.textNode.appendChild(tspan);
      return new TspanWrapper(tspan, this.textNode);
    }
  }
  class TspanWrapper {
    /**
     * @param {any} node
     * @param {any} textNode
     */
    constructor(node, textNode) {
      this.node = node;
      this.textNode = textNode;
    }
    newLine() {
      this.node.setAttribute("dy", "1.1em");
      this.node.dataset.newline = "1";
      return this;
    }
  }
  let filterCounter = 0;
  class SVGFilter extends SVGElement {
    constructor() {
      const node = BrowserAPIs.createElementNS(SVGNS, "filter");
      super(node);
      this._id = "SvgjsFilter" + ++filterCounter;
      this.attr("id", this._id);
    }
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {number} h
     * @param {number} x
     * @param {number} y
     */
    /**
     * @param {number} w
     * @param {number} h
     * @param {number} [x]
     * @param {number} [y]
     */
    size(w, h, x, y) {
      return this.attr({ width: w, height: h, x, y });
    }
  }
  class FilterBuilder {
    /**
     * @param {any} filter
     */
    constructor(filter) {
      this.filter = filter;
    }
    /**
     * @param {object} attrs
     */
    colorMatrix(attrs) {
      return this._primitive("feColorMatrix", attrs);
    }
    /**
     * @param {object} attrs
     */
    offset(attrs) {
      return this._primitive("feOffset", attrs);
    }
    /**
     * @param {object} attrs
     */
    gaussianBlur(attrs) {
      return this._primitive("feGaussianBlur", attrs);
    }
    /**
     * @param {object} attrs
     */
    flood(attrs) {
      return this._primitive("feFlood", attrs);
    }
    /**
     * @param {object} attrs
     */
    composite(attrs) {
      return this._primitive("feComposite", attrs);
    }
    /**
     * @param {string[]} sources
     */
    merge(sources) {
      const m = BrowserAPIs.createElementNS(SVGNS, "feMerge");
      sources.forEach((src) => {
        const mn = BrowserAPIs.createElementNS(SVGNS, "feMergeNode");
        mn.setAttribute("in", src);
        m.appendChild(mn);
      });
      this.filter.node.appendChild(m);
      return new SVGElement(m);
    }
    /**
     * @param {string} tag
     * @param {Record<string, any>} attrs
     */
    _primitive(tag, attrs) {
      const el = BrowserAPIs.createElementNS(SVGNS, tag);
      for (const key in attrs) {
        el.setAttribute(key, attrs[key]);
      }
      this.filter.node.appendChild(el);
      return new SVGElement(el);
    }
  }
  function installFilterMethods(ElementClass) {
    ElementClass.prototype.filterWith = function(fn) {
      const filter = new SVGFilter();
      this._filter = filter;
      let svgRoot = this.node;
      while (svgRoot && svgRoot.nodeName !== "svg") {
        svgRoot = svgRoot.parentNode;
      }
      if (svgRoot) {
        let defs = svgRoot.querySelector("defs");
        if (!defs) {
          defs = BrowserAPIs.createElementNS(SVGNS, "defs");
          svgRoot.insertBefore(defs, svgRoot.firstChild);
        }
        defs.appendChild(filter.node);
      }
      fn(new FilterBuilder(filter));
      this.attr("filter", "url(#" + filter._id + ")");
      return this;
    };
    ElementClass.prototype.unfilter = function(all) {
      if (this._filter) {
        this.node.removeAttribute("filter");
        if (all && this._filter.node && this._filter.node.parentNode) {
          this._filter.node.parentNode.removeChild(this._filter.node);
        }
        this._filter = null;
      }
      return this;
    };
    ElementClass.prototype.filterer = function() {
      return this._filter;
    };
  }
  /*!
   * Path morphing for SVG path animations
   * Based on svg.pathmorphing.js by Ulrich-Matthias Schäfer (MIT License)
   * Refactored to be standalone (no SVG.js dependency)
   */
  function parsePath(d) {
    if (!d || typeof d !== "string") return [["M", 0, 0]];
    const commands = [];
    const re = /([MmLlHhVvCcSsQqTtAaZz])\s*/g;
    const numRe = /[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?/gi;
    let match;
    const letters = [];
    const positions = [];
    while ((match = re.exec(d)) !== null) {
      letters.push(match[1]);
      positions.push(match.index);
    }
    for (let i = 0; i < letters.length; i++) {
      const start = positions[i] + letters[i].length;
      const end = i + 1 < positions.length ? positions[i + 1] : d.length;
      const paramStr = d.substring(start, end);
      const nums = [];
      let numMatch;
      numRe.lastIndex = 0;
      while ((numMatch = numRe.exec(paramStr)) !== null) {
        nums.push(parseFloat(numMatch[0]));
      }
      const cmd = letters[i].toUpperCase();
      if (cmd === "Z") {
        commands.push(["Z"]);
      } else if (cmd === "M" || cmd === "L" || cmd === "T") {
        for (let j = 0; j < nums.length; j += 2) {
          commands.push([cmd, nums[j], nums[j + 1]]);
        }
      } else if (cmd === "H") {
        for (let j = 0; j < nums.length; j++) {
          commands.push([cmd, nums[j]]);
        }
      } else if (cmd === "V") {
        for (let j = 0; j < nums.length; j++) {
          commands.push([cmd, nums[j]]);
        }
      } else if (cmd === "C") {
        for (let j = 0; j < nums.length; j += 6) {
          commands.push([
            cmd,
            nums[j],
            nums[j + 1],
            nums[j + 2],
            nums[j + 3],
            nums[j + 4],
            nums[j + 5]
          ]);
        }
      } else if (cmd === "S" || cmd === "Q") {
        for (let j = 0; j < nums.length; j += 4) {
          commands.push([cmd, nums[j], nums[j + 1], nums[j + 2], nums[j + 3]]);
        }
      } else if (cmd === "A") {
        for (let j = 0; j < nums.length; j += 7) {
          commands.push([
            cmd,
            nums[j],
            nums[j + 1],
            nums[j + 2],
            nums[j + 3],
            nums[j + 4],
            nums[j + 5],
            nums[j + 6]
          ]);
        }
      }
    }
    if (commands.length === 0) {
      commands.push(["M", 0, 0]);
    }
    return commands;
  }
  function pathBbox(arr) {
    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
    arr.forEach((cmd) => {
      for (let i = 1; i < cmd.length; i += 2) {
        if (i + 1 <= cmd.length) {
          const x = cmd[i];
          const y = cmd[i + 1];
          if (typeof x === "number" && typeof y === "number") {
            if (x < minX) minX = x;
            if (x > maxX) maxX = x;
            if (y < minY) minY = y;
            if (y > maxY) maxY = y;
          }
        }
      }
    });
    if (minX === Infinity) {
      return { x: 0, y: 0, width: 0, height: 0 };
    }
    return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
  }
  function arrayToPath(arr) {
    return arr.map((cmd) => cmd.join(" ")).join(" ");
  }
  function simplify(val) {
    switch (val[0]) {
      case "z":
      case "Z":
        val[0] = "L";
        val[1] = this.start[0];
        val[2] = this.start[1];
        break;
      case "H":
        val[0] = "L";
        val[2] = this.pos[1];
        break;
      case "V":
        val[0] = "L";
        val[2] = val[1];
        val[1] = this.pos[0];
        break;
      case "T":
        val[0] = "Q";
        val[3] = val[1];
        val[4] = val[2];
        val[1] = this.reflection[1];
        val[2] = this.reflection[0];
        break;
      case "S":
        val[0] = "C";
        val[6] = val[4];
        val[5] = val[3];
        val[4] = val[2];
        val[3] = val[1];
        val[2] = this.reflection[1];
        val[1] = this.reflection[0];
        break;
    }
    return val;
  }
  function setPosAndReflection(val) {
    var len = val.length;
    this.pos = [val[len - 2], val[len - 1]];
    if ("SCQT".indexOf(val[0]) != -1) {
      this.reflection = [
        2 * this.pos[0] - val[len - 4],
        2 * this.pos[1] - val[len - 3]
      ];
    }
    return val;
  }
  function toBezier(val) {
    var _a;
    var retVal = [val];
    switch (val[0]) {
      case "M":
        this.pos = this.start = [val[1], val[2]];
        return retVal;
      case "L":
        val[5] = val[3] = val[1];
        val[6] = val[4] = val[2];
        val[1] = this.pos[0];
        val[2] = this.pos[1];
        break;
      case "Q":
        val[6] = val[4];
        val[5] = val[3];
        val[4] = val[4] * 1 / 3 + val[2] * 2 / 3;
        val[3] = val[3] * 1 / 3 + val[1] * 2 / 3;
        val[2] = this.pos[1] * 1 / 3 + val[2] * 2 / 3;
        val[1] = this.pos[0] * 1 / 3 + val[1] * 2 / 3;
        break;
      case "A":
        retVal = arcToBezier((_a = this.pos) != null ? _a : [], val);
        val = retVal[0];
        break;
    }
    val[0] = "C";
    this.pos = [val[5], val[6]];
    this.reflection = [2 * val[5] - val[3], 2 * val[6] - val[4]];
    return retVal;
  }
  function findNextM(arr, offset) {
    if (offset === false) return false;
    for (var i = offset, len = arr.length; i < len; ++i) {
      if (arr[i][0] == "M") return i;
    }
    return false;
  }
  function arcToBezier(pos, val) {
    var rx = Math.abs(val[1]), ry = Math.abs(val[2]), xAxisRotation = val[3] % 360, largeArcFlag = val[4], sweepFlag = val[5], x = val[6], y = val[7], A = new Point(pos[0], pos[1]), B = new Point(x, y), primedCoord, lambda, mat, k, c, cSquare, t, O, OA, OB, tetaStart, tetaEnd, deltaTeta, nbSectors, f, arcSegPoints, angle, sinAngle, cosAngle, pt, i, il, retVal = [], x1, y1, x2, y2;
    if (rx === 0 || ry === 0 || A.x === B.x && A.y === B.y) {
      return [["C", A.x, A.y, B.x, B.y, B.x, B.y]];
    }
    primedCoord = new Point((A.x - B.x) / 2, (A.y - B.y) / 2).transform(
      /** @type {any} */
      new Matrix(0, 0, 0, 0, 0, 0).rotate(xAxisRotation)
    );
    lambda = primedCoord.x * primedCoord.x / (rx * rx) + primedCoord.y * primedCoord.y / (ry * ry);
    if (lambda > 1) {
      lambda = Math.sqrt(lambda);
      rx = lambda * rx;
      ry = lambda * ry;
    }
    mat = /** @type {any} */
    new Matrix(0, 0, 0, 0, 0, 0).rotate(xAxisRotation).scale(1 / rx, 1 / ry).rotate(-xAxisRotation);
    A = A.transform(mat);
    B = B.transform(mat);
    k = [B.x - A.x, B.y - A.y];
    cSquare = k[0] * k[0] + k[1] * k[1];
    c = Math.sqrt(cSquare);
    k[0] /= c;
    k[1] /= c;
    t = cSquare < 4 ? Math.sqrt(1 - cSquare / 4) : 0;
    if (largeArcFlag === sweepFlag) {
      t *= -1;
    }
    O = new Point((B.x + A.x) / 2 + t * -k[1], (B.y + A.y) / 2 + t * k[0]);
    OA = new Point(A.x - O.x, A.y - O.y);
    OB = new Point(B.x - O.x, B.y - O.y);
    tetaStart = Math.acos(OA.x / Math.sqrt(OA.x * OA.x + OA.y * OA.y));
    if (OA.y < 0) tetaStart *= -1;
    tetaEnd = Math.acos(OB.x / Math.sqrt(OB.x * OB.x + OB.y * OB.y));
    if (OB.y < 0) tetaEnd *= -1;
    if (sweepFlag && tetaStart > tetaEnd) {
      tetaEnd += 2 * Math.PI;
    }
    if (!sweepFlag && tetaStart < tetaEnd) {
      tetaEnd -= 2 * Math.PI;
    }
    nbSectors = Math.ceil(Math.abs(tetaStart - tetaEnd) * 2 / Math.PI);
    arcSegPoints = [];
    angle = tetaStart;
    deltaTeta = (tetaEnd - tetaStart) / nbSectors;
    f = 4 * Math.tan(deltaTeta / 4) / 3;
    for (i = 0; i <= nbSectors; i++) {
      cosAngle = Math.cos(angle);
      sinAngle = Math.sin(angle);
      pt = new Point(O.x + cosAngle, O.y + sinAngle);
      arcSegPoints[i] = [
        new Point(pt.x + f * sinAngle, pt.y - f * cosAngle),
        pt,
        new Point(pt.x - f * sinAngle, pt.y + f * cosAngle)
      ];
      angle += deltaTeta;
    }
    arcSegPoints[0][0] = arcSegPoints[0][1].clone();
    arcSegPoints[arcSegPoints.length - 1][2] = arcSegPoints[arcSegPoints.length - 1][1].clone();
    mat = /** @type {any} */
    new Matrix(0, 0, 0, 0, 0, 0).rotate(xAxisRotation).scale(rx, ry).rotate(-xAxisRotation);
    for (i = 0, il = arcSegPoints.length; i < il; i++) {
      arcSegPoints[i][0] = arcSegPoints[i][0].transform(mat);
      arcSegPoints[i][1] = arcSegPoints[i][1].transform(mat);
      arcSegPoints[i][2] = arcSegPoints[i][2].transform(mat);
    }
    for (i = 1, il = arcSegPoints.length; i < il; i++) {
      pt = arcSegPoints[i - 1][2];
      x1 = pt.x;
      y1 = pt.y;
      pt = arcSegPoints[i][0];
      x2 = pt.x;
      y2 = pt.y;
      pt = arcSegPoints[i][1];
      x = pt.x;
      y = pt.y;
      retVal.push(["C", x1, y1, x2, y2, x, y]);
    }
    return retVal;
  }
  function handleBlock(startArr, startOffsetM, startOffsetNextM, destArr, destOffsetM, destOffsetNextM) {
    var startArrTemp = startArr.slice(startOffsetM, startOffsetNextM || void 0);
    var destArrTemp = destArr.slice(destOffsetM, destOffsetNextM || void 0);
    var i = 0, posStart = { pos: [0, 0], start: [0, 0] }, posDest = { pos: [0, 0], start: [0, 0] };
    while (true) {
      startArrTemp[i] = simplify.call(posStart, startArrTemp[i]);
      destArrTemp[i] = simplify.call(posDest, destArrTemp[i]);
      if (startArrTemp[i][0] != destArrTemp[i][0] || startArrTemp[i][0] == "M" || startArrTemp[i][0] == "A" && (startArrTemp[i][4] != destArrTemp[i][4] || startArrTemp[i][5] != destArrTemp[i][5])) {
        Array.prototype.splice.apply(
          startArrTemp,
          /** @type {[number, number, ...any[]]} */
          [i, 1].concat(
            /** @type {any} */
            toBezier.call(posStart, startArrTemp[i])
          )
        );
        Array.prototype.splice.apply(
          destArrTemp,
          /** @type {[number, number, ...any[]]} */
          [i, 1].concat(
            /** @type {any} */
            toBezier.call(posDest, destArrTemp[i])
          )
        );
      } else {
        startArrTemp[i] = /** @type {any} */
        setPosAndReflection.call(
          posStart,
          startArrTemp[i]
        );
        destArrTemp[i] = /** @type {any} */
        setPosAndReflection.call(
          posDest,
          destArrTemp[i]
        );
      }
      if (++i == startArrTemp.length && i == destArrTemp.length) break;
      if (i == startArrTemp.length) {
        startArrTemp.push([
          "C",
          posStart.pos[0],
          posStart.pos[1],
          posStart.pos[0],
          posStart.pos[1],
          posStart.pos[0],
          posStart.pos[1]
        ]);
      }
      if (i == destArrTemp.length) {
        destArrTemp.push([
          "C",
          posDest.pos[0],
          posDest.pos[1],
          posDest.pos[0],
          posDest.pos[1],
          posDest.pos[0],
          posDest.pos[1]
        ]);
      }
    }
    return { start: startArrTemp, dest: destArrTemp };
  }
  function synchronizePaths(fromD, toD) {
    var startArr = parsePath(fromD);
    var destArr = parsePath(toD);
    var startOffsetM = 0;
    var destOffsetM = 0;
    var startOffsetNextM = false;
    var destOffsetNextM = false;
    var result;
    while (true) {
      if (startOffsetM === false && destOffsetM === false) break;
      startOffsetNextM = findNextM(
        startArr,
        startOffsetM === false ? false : startOffsetM + 1
      );
      destOffsetNextM = findNextM(
        destArr,
        destOffsetM === false ? false : destOffsetM + 1
      );
      if (startOffsetM === false) {
        const bbox = pathBbox(
          /** @type {any} */
          result.start
        );
        if (bbox.height == 0 || bbox.width == 0) {
          startOffsetM = startArr.push(startArr[0]) - 1;
        } else {
          startOffsetM = startArr.push([
            "M",
            bbox.x + bbox.width / 2,
            bbox.y + bbox.height / 2
          ]) - 1;
        }
      }
      if (destOffsetM === false) {
        const bbox = pathBbox(
          /** @type {any} */
          result.dest
        );
        if (bbox.height == 0 || bbox.width == 0) {
          destOffsetM = destArr.push(destArr[0]) - 1;
        } else {
          destOffsetM = destArr.push([
            "M",
            bbox.x + bbox.width / 2,
            bbox.y + bbox.height / 2
          ]) - 1;
        }
      }
      result = handleBlock(
        startArr,
        startOffsetM,
        startOffsetNextM,
        destArr,
        destOffsetM,
        destOffsetNextM
      );
      startArr = startArr.slice(0, startOffsetM).concat(
        result.start,
        startOffsetNextM === false ? [] : startArr.slice(startOffsetNextM)
      );
      destArr = destArr.slice(0, destOffsetM).concat(
        result.dest,
        destOffsetNextM === false ? [] : destArr.slice(destOffsetNextM)
      );
      startOffsetM = startOffsetNextM === false ? false : startOffsetM + result.start.length;
      destOffsetM = destOffsetNextM === false ? false : destOffsetM + result.dest.length;
    }
    return { start: startArr, dest: destArr };
  }
  function morphPaths(fromD, toD) {
    var synced = synchronizePaths(fromD, toD);
    var startArr = synced.start;
    var destArr = synced.dest;
    return function(pos) {
      var result = startArr.map(function(from, idx) {
        return destArr[idx].map(function(to, toIdx) {
          if (toIdx === 0) return to;
          return from[toIdx] + (destArr[idx][toIdx] - from[toIdx]) * pos;
        });
      });
      return arrayToPath(result);
    };
  }
  function easeInOut(t) {
    return -Math.cos(t * Math.PI) / 2 + 0.5;
  }
  function parseColor(str) {
    if (!str || typeof str !== "string") return null;
    if (str[0] === "#") {
      let hex = str.slice(1);
      if (hex.length === 3)
        hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
      const n = parseInt(hex, 16);
      return [n >> 16 & 255, n >> 8 & 255, n & 255, 1];
    }
    const m = str.match(
      /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/
    );
    if (m) return [+m[1], +m[2], +m[3], m[4] !== void 0 ? +m[4] : 1];
    return null;
  }
  function interpolateColor(from, to, pos) {
    return `rgba(${Math.round(from[0] + (to[0] - from[0]) * pos)},${Math.round(from[1] + (to[1] - from[1]) * pos)},${Math.round(from[2] + (to[2] - from[2]) * pos)},${from[3] + (to[3] - from[3]) * pos})`;
  }
  class SVGAnimationRunner {
    /**
     * @param {any} element
     * @param {number} duration
     * @param {number} delay
     */
    constructor(element, duration, delay) {
      this.el = element;
      this.duration = duration != null ? duration : 300;
      this.delay = delay || 0;
      this._attrTarget = null;
      this._plotTarget = null;
      this._afterCb = null;
      this._duringCb = null;
      this._next = null;
      this._root = null;
      this._scheduled = false;
    }
    /**
     * @param {Record<string, any>} to
     */
    attr(to) {
      this._attrTarget = to;
      this._schedule();
      return this;
    }
    /**
     * @param {string} d
     */
    plot(d) {
      this._plotTarget = d;
      this._schedule();
      return this;
    }
    /**
     * @param {Function} fn
     */
    after(fn) {
      this._afterCb = fn;
      this._schedule();
      return this;
    }
    /**
     * @param {Function} fn
     */
    during(fn) {
      this._duringCb = fn;
      this._schedule();
      return this;
    }
    /**
     * @param {number} duration
     * @param {number} delay
     */
    animate(duration, delay) {
      const next = new SVGAnimationRunner(this.el, duration, delay);
      this._next = next;
      next._root = this._root || this;
      return next;
    }
    _schedule() {
      const root = this._root || this;
      if (!root._scheduled) {
        root._scheduled = true;
        queueMicrotask(() => root._executeChain());
      }
    }
    _executeChain() {
      const chain = [];
      let r = this;
      while (r) {
        chain.push(r);
        r = r._next;
      }
      let cumulativeDelay = 0;
      chain.forEach((runner) => {
        cumulativeDelay += runner.delay;
        runner._execute(cumulativeDelay);
        cumulativeDelay += runner.duration;
      });
    }
    /**
     * @param {number} startDelay
     */
    _execute(startDelay) {
      const el = this.el;
      const duration = this.duration;
      if (duration <= 1) {
        const apply = () => {
          if (this._attrTarget) el.attr(this._attrTarget);
          if (this._plotTarget) el.plot(this._plotTarget);
          if (this._afterCb) this._afterCb.call(el);
        };
        if (startDelay > 0) {
          setTimeout(apply, startDelay);
        } else {
          apply();
        }
        return;
      }
      const run = () => {
        const fromAttrs = (
          /** @type {Record<string, any>} */
          {}
        );
        const fromColors = (
          /** @type {Record<string, any>} */
          {}
        );
        const toColors = (
          /** @type {Record<string, any>} */
          {}
        );
        if (this._attrTarget) {
          for (const key of Object.keys(this._attrTarget)) {
            const fromVal = el.attr(key);
            fromAttrs[key] = fromVal;
            const fc = parseColor(fromVal);
            const tc = parseColor(String(this._attrTarget[key]));
            if (fc && tc) {
              fromColors[key] = fc;
              toColors[key] = tc;
            }
          }
        }
        let morphFn = null;
        if (this._plotTarget) {
          const fromPath = el.attr("d") || "";
          try {
            morphFn = morphPaths(fromPath, this._plotTarget);
          } catch (e) {
            morphFn = null;
          }
        }
        const start = performance.now();
        const tick = (now) => {
          const elapsed = now - start;
          const rawPos = Math.min(elapsed / duration, 1);
          const pos = easeInOut(rawPos);
          if (this._attrTarget) {
            if (rawPos >= 1) {
              el.attr(this._attrTarget);
            } else {
              const current = (
                /** @type {Record<string, any>} */
                {}
              );
              for (const key of Object.keys(this._attrTarget)) {
                if (fromColors[key] && toColors[key]) {
                  current[key] = interpolateColor(
                    fromColors[key],
                    toColors[key],
                    pos
                  );
                } else {
                  const from = parseFloat(fromAttrs[key]);
                  const to = parseFloat(this._attrTarget[key]);
                  if (!isNaN(from) && !isNaN(to)) {
                    current[key] = from + (to - from) * pos;
                  }
                }
              }
              el.attr(current);
            }
          }
          if (morphFn && rawPos < 1) {
            el.attr(
              "d",
              /** @type {any} */
              morphFn(pos)
            );
          }
          if (this._duringCb) this._duringCb(pos);
          if (rawPos < 1) {
            BrowserAPIs.requestAnimationFrame(tick);
          } else {
            if (this._plotTarget) {
              el.attr("d", this._plotTarget);
            }
            if (this._afterCb) this._afterCb.call(el);
          }
        };
        BrowserAPIs.requestAnimationFrame(tick);
      };
      if (startDelay > 0) {
        setTimeout(run, startDelay);
      } else {
        run();
      }
    }
  }
  function installAnimationMethods(ElementClass) {
    ElementClass.prototype.animate = function(duration, delay) {
      return new SVGAnimationRunner(this, duration, delay);
    };
  }
  function installDraggable(ElementClass) {
    ElementClass.prototype.draggable = function(opts) {
      if (opts === false) {
        if (this._dragCleanup) {
          this._dragCleanup();
          this._dragCleanup = null;
        }
        return this;
      }
      const el = this;
      const constraints = opts || {};
      const onPointerDown = (e) => {
        if (e.button && e.button !== 0) return;
        e.stopPropagation();
        const isTouch = e.type === "touchstart";
        const ev = isTouch ? e.touches[0] : e;
        const svgEl = el.node;
        const startAttrX = parseFloat(svgEl.getAttribute("x")) || 0;
        const startAttrY = parseFloat(svgEl.getAttribute("y")) || 0;
        const startClientX = ev.clientX;
        const startClientY = ev.clientY;
        const svgRoot = svgEl.ownerSVGElement;
        let ctm = null;
        if (svgRoot) {
          ctm = svgRoot.getScreenCTM();
        }
        const onMove = (me) => {
          const mev = me.type === "touchmove" ? me.touches[0] : me;
          let dx = mev.clientX - startClientX;
          let dy = mev.clientY - startClientY;
          if (ctm) {
            dx = dx / ctm.a;
            dy = dy / ctm.d;
          }
          let newX = startAttrX + dx;
          let newY = startAttrY + dy;
          const w = parseFloat(svgEl.getAttribute("width")) || 0;
          const h = parseFloat(svgEl.getAttribute("height")) || 0;
          if (constraints.minX !== void 0 && newX < constraints.minX)
            newX = constraints.minX;
          if (constraints.minY !== void 0 && newY < constraints.minY)
            newY = constraints.minY;
          if (constraints.maxX !== void 0 && newX + w > constraints.maxX)
            newX = constraints.maxX - w;
          if (constraints.maxY !== void 0 && newY + h > constraints.maxY)
            newY = constraints.maxY - h;
          const box = {
            x: newX,
            y: newY,
            w,
            h,
            x2: newX + w,
            y2: newY + h
          };
          const event = new CustomEvent("dragmove", {
            detail: {
              handler: {
                /**
                 * @param {number} x
                 * @param {number} y
                 */
                move: function(x, y) {
                  svgEl.setAttribute("x", x);
                  svgEl.setAttribute("y", y);
                }
              },
              box
            }
          });
          svgEl.dispatchEvent(event);
        };
        const onUp = () => {
          if (Environment.isBrowser()) {
            document.removeEventListener("mousemove", onMove);
            document.removeEventListener("touchmove", onMove);
            document.removeEventListener("mouseup", onUp);
            document.removeEventListener("touchend", onUp);
          }
        };
        if (Environment.isBrowser()) {
          document.addEventListener("mousemove", onMove);
          document.addEventListener("touchmove", onMove);
          document.addEventListener("mouseup", onUp);
          document.addEventListener("touchend", onUp);
        }
      };
      el.node.addEventListener("mousedown", onPointerDown);
      el.node.addEventListener("touchstart", onPointerDown);
      el._dragCleanup = () => {
        el.node.removeEventListener("mousedown", onPointerDown);
        el.node.removeEventListener("touchstart", onPointerDown);
      };
      return el;
    };
  }
  function installSelectable(ElementClass) {
    ElementClass.prototype.select = function(opts) {
      if (opts === false) {
        if (this._selectCleanup) {
          this._selectCleanup();
          this._selectCleanup = null;
        }
        return this;
      }
      const el = this;
      const { createHandle, updateHandle } = opts;
      const handleGroup = document.createElementNS(SVGNS, "g");
      handleGroup.setAttribute("class", "svg_select_points");
      const parent = el.node.parentNode;
      if (parent) {
        parent.appendChild(handleGroup);
      }
      const handles = {};
      const handleNames = ["t", "b", "l", "r", "lt", "rt", "lb", "rb"];
      handleNames.forEach((name2, index) => {
        const subGroup = new SVGContainer(document.createElementNS(SVGNS, "g"));
        handleGroup.appendChild(subGroup.node);
        const handle = createHandle(subGroup, [0, 0], index, [], name2);
        handles[name2] = { group: subGroup, handle };
      });
      const updatePositions = () => {
        const x = parseFloat(el.attr("x")) || 0;
        const y = parseFloat(el.attr("y")) || 0;
        const w = parseFloat(el.attr("width")) || 0;
        const h = parseFloat(el.attr("height")) || 0;
        const elTransform = el.node.getAttribute("transform");
        if (elTransform) {
          handleGroup.setAttribute("transform", elTransform);
        } else {
          handleGroup.removeAttribute("transform");
        }
        const positions = {
          t: [x + w / 2, y],
          b: [x + w / 2, y + h],
          l: [x, y + h / 2],
          r: [x + w, y + h / 2],
          lt: [x, y],
          rt: [x + w, y],
          lb: [x, y + h],
          rb: [x + w, y + h]
        };
        handleNames.forEach((name2) => {
          if (handles[name2] && positions[name2]) {
            updateHandle(handles[name2].group, positions[name2]);
          }
        });
      };
      updatePositions();
      el._selectHandles = handleGroup;
      el._selectHandlesMap = handles;
      el._updateSelectPositions = updatePositions;
      el._selectCleanup = () => {
        if (handleGroup.parentNode) {
          handleGroup.parentNode.removeChild(handleGroup);
        }
        el._selectHandles = null;
        el._selectHandlesMap = null;
        el._updateSelectPositions = null;
      };
      return el;
    };
    ElementClass.prototype.resize = function(enable) {
      if (enable === false) {
        if (this._resizeCleanup) {
          this._resizeCleanup();
          this._resizeCleanup = null;
        }
        return this;
      }
      const el = this;
      const handles = el._selectHandlesMap;
      if (!handles) return el;
      const cleanupFns = [];
      const makeHandleDraggable = (name2) => {
        const handleInfo = handles[name2];
        if (!handleInfo || !handleInfo.group || !handleInfo.group.node) return;
        const handleNode = handleInfo.group.node;
        const onPointerDown = (e) => {
          if (e.button && e.button !== 0) return;
          e.stopPropagation();
          const isTouch = e.type === "touchstart";
          const ev = isTouch ? e.touches[0] : e;
          const startClientX = ev.clientX;
          const svgRoot = el.node.ownerSVGElement;
          let ctm = null;
          if (svgRoot) {
            ctm = svgRoot.getScreenCTM();
          }
          const startX = parseFloat(el.attr("x")) || 0;
          const startW = parseFloat(el.attr("width")) || 0;
          const onMove = (me) => {
            const mev = me.type === "touchmove" ? me.touches[0] : me;
            let dx = mev.clientX - startClientX;
            if (ctm) dx = dx / /** @type {any} */
            ctm.a;
            let newX = startX;
            let newW = startW;
            if (name2 === "l") {
              newX = startX + dx;
              newW = startW - dx;
            } else if (name2 === "r") {
              newW = startW + dx;
            }
            if (newW < 0) {
              newW = 0;
            }
            el.attr({ x: newX, width: newW });
            if (el._updateSelectPositions) {
              el._updateSelectPositions();
            }
            const event = new CustomEvent("resize", {
              detail: { el }
            });
            el.node.dispatchEvent(event);
          };
          const onUp = () => {
            if (Environment.isBrowser()) {
              document.removeEventListener("mousemove", onMove);
              document.removeEventListener("touchmove", onMove);
              document.removeEventListener("mouseup", onUp);
              document.removeEventListener("touchend", onUp);
            }
            const event = new CustomEvent("resize", {
              detail: { el }
            });
            el.node.dispatchEvent(event);
          };
          if (Environment.isBrowser()) {
            document.addEventListener("mousemove", onMove);
            document.addEventListener("touchmove", onMove);
            document.addEventListener("mouseup", onUp);
            document.addEventListener("touchend", onUp);
          }
        };
        handleNode.addEventListener("mousedown", onPointerDown);
        handleNode.addEventListener("touchstart", onPointerDown);
        cleanupFns.push(() => {
          handleNode.removeEventListener("mousedown", onPointerDown);
          handleNode.removeEventListener("touchstart", onPointerDown);
        });
      };
      makeHandleDraggable("l");
      makeHandleDraggable("r");
      el._resizeCleanup = () => {
        cleanupFns.forEach((fn) => fn());
      };
      return el;
    };
  }
  installFilterMethods(SVGElement);
  installAnimationMethods(SVGElement);
  installDraggable(SVGElement);
  installSelectable(SVGElement);
  function SVG() {
    const svgEl = BrowserAPIs.createElementNS(SVGNS, "svg");
    const svg = new SVGContainer(svgEl);
    svg.attr({ xmlns: SVGNS });
    return svg;
  }
  SVG.xlink = "http://www.w3.org/1999/xlink";
  if (Environment.isBrowser() && typeof window.SVG === "undefined") {
    window.SVG = SVG;
  }
  if (Environment.isBrowser()) {
    if (typeof window.SVG === "undefined") {
      window.SVG = SVG;
    }
    if (typeof window.Apex === "undefined") {
      window.Apex = {};
    }
  } else {
    if (typeof global !== "undefined") {
      if (typeof /** @type {any} */
      global.Apex === "undefined") {
        global.Apex = {};
      }
      if (typeof /** @type {any} */
      global.SVG === "undefined") {
        global.SVG = SVG;
      }
    }
  }
  const _InitCtxVariables = class _InitCtxVariables {
    /**
     * Register one or more optional feature modules.
     *
     * @param {Record<string, new (w: object, ctx: object) => unknown>} featureMap
     *   Plain object mapping ctx property name → constructor.
     *
     * Example (called from src/features/legend.js):
     *   InitCtxVariables.registerFeatures({ legend: Legend })
     */
    static registerFeatures(featureMap) {
      for (const [key, Ctor] of Object.entries(featureMap)) {
        _InitCtxVariables._featureRegistry.set(key, Ctor);
      }
    }
    /**
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(ctx) {
      this.ctx = ctx;
      this.w = ctx.w;
    }
    initModules() {
      this.ctx.publicMethods = [
        "updateOptions",
        "updateSeries",
        "appendData",
        "appendSeries",
        "isSeriesHidden",
        "highlightSeries",
        "toggleSeries",
        "showSeries",
        "hideSeries",
        "setLocale",
        "resetSeries",
        "zoomX",
        "toggleDataPointSelection",
        "dataURI",
        "exportToCSV",
        "addXaxisAnnotation",
        "addYaxisAnnotation",
        "addPointAnnotation",
        "clearAnnotations",
        "removeAnnotation",
        "paper",
        "destroy"
      ];
      this.ctx.eventList = [
        "click",
        "mousedown",
        "mousemove",
        "mouseleave",
        "touchstart",
        "touchmove",
        "touchleave",
        "mouseup",
        "touchend",
        "keydown",
        "keyup"
      ];
      this.ctx.animations = new Animations(this.w, this.ctx);
      this.ctx.axes = new Axes(this.w, this.ctx);
      this.ctx.core = new Core(this.ctx.el, this.w, this.ctx);
      this.ctx.config = new Config({});
      this.ctx.data = new Data(this.w, {
        resetGlobals: () => this.ctx.core.resetGlobals(),
        isMultipleY: () => this.ctx.core.isMultipleY()
      });
      this.ctx.grid = new Grid(this.w, this.ctx);
      this.ctx.graphics = new Graphics(this.w, this.ctx);
      this.ctx.coreUtils = new CoreUtils(this.w);
      this.ctx.crosshairs = new Crosshairs(this.w);
      this.ctx.events = new Events(this.w, this.ctx);
      this.ctx.fill = new Fill(this.w);
      this.ctx.localization = new Localization(this.w);
      this.ctx.options = new Options();
      this.ctx.responsive = new Responsive(this.w);
      this.ctx.series = new Series(this.w, {
        // legend may not be registered — guard with ?.
        toggleDataSeries: (...a) => {
          var _a;
          return (_a = this.ctx.legend) == null ? void 0 : _a.legendHelpers.toggleDataSeries(...a);
        },
        revertDefaultAxisMinMax: () => this.ctx.updateHelpers.revertDefaultAxisMinMax(),
        updateSeries: (...a) => this.ctx.updateHelpers._updateSeries(...a)
      });
      this.ctx.theme = new Theme(this.w);
      this.ctx.formatters = new Formatters(this.w);
      this.ctx.titleSubtitle = new TitleSubtitle(this.w);
      this.ctx.dimensions = new Dimensions(this.w, this.ctx);
      this.ctx.updateHelpers = new UpdateHelpers(this.w, this.ctx);
      const tooltipInstance = new Tooltip(this.w, this.ctx);
      this.w.globals.tooltip = tooltipInstance;
      Object.defineProperty(this.ctx, "tooltip", {
        get() {
          return this.w.globals.tooltip;
        },
        configurable: true
      });
      this._initOptionalModules();
    }
    /**
     * Instantiate optional feature modules from the registry.
     *
     * Modules that are not registered are set to null on ctx so that call sites
     * can safely use optional-chaining (ctx.tooltip?.drawTooltip(...)).
     *
     * Lazy-getter features (toolbar, zoomPanSelection, keyboardNavigation) are
     * installed as on-demand getters so they are only constructed if accessed,
     * and only if their constructor was registered.
     */
    _initOptionalModules() {
      const reg = _InitCtxVariables._featureRegistry;
      const w = this.w;
      const ctx = this.ctx;
      const ExportsCtor = reg.get("exports");
      ctx.exports = ExportsCtor ? new ExportsCtor(w, ctx) : null;
      const LegendCtor = reg.get("legend");
      ctx.legend = LegendCtor ? new LegendCtor(w, ctx) : null;
      const ToolbarCtor = reg.get("toolbar");
      Object.defineProperty(ctx, "toolbar", {
        get() {
          var _a;
          if (!this._toolbar && ToolbarCtor)
            this._toolbar = new ToolbarCtor(w, this);
          return (_a = this._toolbar) != null ? _a : null;
        },
        configurable: true
      });
      const ZoomPanCtor = reg.get("zoomPanSelection");
      Object.defineProperty(ctx, "zoomPanSelection", {
        get() {
          var _a;
          if (!this._zoomPanSelection && ZoomPanCtor)
            this._zoomPanSelection = new ZoomPanCtor(w, this);
          return (_a = this._zoomPanSelection) != null ? _a : null;
        },
        configurable: true
      });
      const KeyboardCtor = reg.get("keyboardNavigation");
      Object.defineProperty(ctx, "keyboardNavigation", {
        get() {
          var _a;
          if (!this._keyboardNavigation && KeyboardCtor)
            this._keyboardNavigation = new KeyboardCtor(w, this);
          return (_a = this._keyboardNavigation) != null ? _a : null;
        },
        configurable: true
      });
    }
  };
  /**
   * Registry of optional feature modules.
   *
   * Populated by ApexCharts.registerFeatures() (called from feature entry
   * files such as src/features/legend.js). Keys match the ctx property name
   * the module is stored under (e.g. 'legend', 'exports').
   *
   * Core modules that every chart needs are NOT in this registry — they are
   * always instantiated unconditionally in initModules().
   */
  __publicField(_InitCtxVariables, "_featureRegistry", /* @__PURE__ */ new Map());
  let InitCtxVariables = _InitCtxVariables;
  class Destroy {
    /**
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(ctx) {
      this.ctx = ctx;
      this.w = ctx.w;
    }
    /**
     * @param {{ isUpdating: boolean }} opts
     */
    clear({ isUpdating }) {
      if (this.ctx._zoomPanSelection) {
        this.ctx._zoomPanSelection.destroy();
      }
      if (this.ctx._toolbar) {
        this.ctx._toolbar.destroy();
      }
      if (this.w.globals.resizeObserver && typeof this.w.globals.resizeObserver.disconnect === "function") {
        this.w.globals.resizeObserver.disconnect();
        this.w.globals.resizeObserver = null;
      }
      PerformanceCache.invalidateAll(this.w);
      if (isUpdating) {
        this.ctx._zoomPanSelection = null;
        this.ctx._toolbar = null;
        this.ctx._keyboardNavigation = null;
      } else {
        this.ctx.animations = null;
        this.ctx.axes = null;
        this.ctx.annotations = null;
        this.ctx.core = null;
        this.ctx.data = null;
        this.ctx.grid = null;
        this.ctx.series = null;
        this.ctx.responsive = null;
        this.ctx.theme = null;
        this.ctx.formatters = null;
        this.ctx.titleSubtitle = null;
        this.ctx.legend = null;
        this.ctx.dimensions = null;
        this.ctx.options = null;
        this.ctx.crosshairs = null;
        this.ctx._zoomPanSelection = null;
        this.ctx.updateHelpers = null;
        this.ctx._toolbar = null;
        this.ctx.localization = null;
        this.ctx._keyboardNavigation = null;
        this.ctx.w.globals.tooltip = null;
      }
      this.clearDomElements({ isUpdating });
    }
    /**
     * @param {any} draw
     */
    killSVG(draw) {
      draw.each(
        /** @this {any} */
        function() {
          this.removeClass("*");
          this.off();
        },
        true
      );
      draw.clear();
    }
    /**
     * @param {{ isUpdating: boolean }} opts
     */
    clearDomElements({ isUpdating }) {
      const domEls = (
        /** @type {any} */
        this.w.dom
      );
      if (Environment.isBrowser()) {
        const elSVG = domEls.Paper.node;
        if (elSVG.parentNode && elSVG.parentNode.parentNode && !isUpdating) {
          elSVG.parentNode.parentNode.style.minHeight = "unset";
        }
        const baseEl = domEls.baseEl;
        if (baseEl) {
          this.ctx.eventList.forEach((event) => {
            baseEl.removeEventListener(event, this.ctx.events.documentEvent);
          });
        }
        if (this.ctx.el !== null) {
          while (this.ctx.el.firstChild) {
            this.ctx.el.removeChild(this.ctx.el.firstChild);
          }
        }
        this.killSVG(domEls.Paper);
        domEls.Paper.remove();
      }
      domEls.elWrap = null;
      domEls.elGraphical = null;
      domEls.elLegendWrap = null;
      domEls.elLegendForeign = null;
      domEls.baseEl = null;
      domEls.elGridRect = null;
      domEls.elGridRectMask = null;
      domEls.elGridRectBarMask = null;
      domEls.elGridRectMarkerMask = null;
      domEls.elForecastMask = null;
      domEls.elNonForecastMask = null;
      domEls.elDefs = null;
    }
  }
  const ros = /* @__PURE__ */ new WeakMap();
  function addResizeListener(el, fn) {
    if (Environment.isSSR()) return;
    let called = false;
    if (el.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
      const elRect = el.getBoundingClientRect();
      if (el.style.display === "none" || elRect.width === 0) {
        called = true;
      }
    }
    const ro = new ResizeObserver((r) => {
      if (called) {
        fn.call(el, r);
      }
      called = true;
    });
    if (el.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
      Array.from(el.children).forEach((c) => ro.observe(c));
    } else {
      ro.observe(el);
    }
    ros.set(fn, ro);
  }
  function removeResizeListener(el, fn) {
    if (Environment.isSSR()) return;
    const ro = ros.get(fn);
    if (ro) {
      ro.disconnect();
      ros.delete(fn);
    }
  }
  const apexCSS = `@keyframes opaque {
  0% {
    opacity: 0
  }

  to {
    opacity: 1
  }
}

@keyframes resizeanim {

  0%,
  to {
    opacity: 0
  }
}

.apexcharts-canvas {
  position: relative;
  direction: ltr !important;
  user-select: none
}

.apexcharts-canvas ::-webkit-scrollbar {
  -webkit-appearance: none;
  width: 6px
}

.apexcharts-canvas ::-webkit-scrollbar-thumb {
  border-radius: 4px;
  background-color: rgba(0, 0, 0, .5);
  box-shadow: 0 0 1px rgba(255, 255, 255, .5);
  -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, .5)
}

.apexcharts-inner {
  position: relative
}

.apexcharts-text tspan {
  font-family: inherit
}

rect.legend-mouseover-inactive,
.legend-mouseover-inactive rect,
.legend-mouseover-inactive path,
.legend-mouseover-inactive circle,
.legend-mouseover-inactive line,
.legend-mouseover-inactive text.apexcharts-yaxis-title-text,
.legend-mouseover-inactive text.apexcharts-yaxis-label {
  transition: .15s ease all;
  opacity: .2
}

.apexcharts-legend-text {
  padding-left: 15px;
  margin-left: -15px;
}

.apexcharts-legend-series[role="button"]:focus {
  outline: 2px solid #008FFB;
  outline-offset: 2px;
}

.apexcharts-legend-series[role="button"]:focus:not(:focus-visible) {
  outline: none;
}

.apexcharts-legend-series[role="button"]:focus-visible {
  outline: 2px solid #008FFB;
  outline-offset: 2px;
}

.apexcharts-series-collapsed {
  opacity: 0
}

.apexcharts-canvas svg:focus:not(:focus-visible) {
  outline: none;
}

/* Keyboard navigation focus indicator on SVG data elements.
   SVG elements don't support CSS outline, so we use stroke. */
.apexcharts-bar-area.apexcharts-keyboard-focused,
.apexcharts-candlestick-area.apexcharts-keyboard-focused,
.apexcharts-boxPlot-area.apexcharts-keyboard-focused,
.apexcharts-rangebar-area.apexcharts-keyboard-focused,
.apexcharts-pie-area.apexcharts-keyboard-focused,
.apexcharts-heatmap-rect.apexcharts-keyboard-focused,
.apexcharts-treemap-rect.apexcharts-keyboard-focused {
  stroke: #008FFB;
  stroke-width: 2;
  stroke-opacity: 1;
}

.apexcharts-tooltip {
  border-radius: 5px;
  box-shadow: 2px 2px 6px -4px #999;
  cursor: default;
  font-size: 14px;
  left: 62px;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  top: 20px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  white-space: nowrap;
  z-index: 12;
  transition: .15s ease all
}

.apexcharts-tooltip.apexcharts-active {
  opacity: 1;
  transition: .15s ease all
}

.apexcharts-tooltip.apexcharts-theme-light {
  border: 1px solid #e3e3e3;
  background: rgba(255, 255, 255, .96)
}

.apexcharts-tooltip.apexcharts-theme-dark {
  color: #fff;
  background: rgba(30, 30, 30, .8)
}

.apexcharts-tooltip * {
  font-family: inherit
}

.apexcharts-tooltip-title {
  padding: 6px;
  font-size: 15px;
  margin-bottom: 4px
}

.apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title {
  background: #eceff1;
  border-bottom: 1px solid #ddd
}

.apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title {
  background: rgba(0, 0, 0, .7);
  border-bottom: 1px solid #333
}

.apexcharts-tooltip-text-goals-value,
.apexcharts-tooltip-text-y-value,
.apexcharts-tooltip-text-z-value {
  display: inline-block;
  margin-left: 5px;
  font-weight: 600
}

.apexcharts-tooltip-text-goals-label:empty,
.apexcharts-tooltip-text-goals-value:empty,
.apexcharts-tooltip-text-y-label:empty,
.apexcharts-tooltip-text-y-value:empty,
.apexcharts-tooltip-text-z-value:empty,
.apexcharts-tooltip-title:empty {
  display: none
}

.apexcharts-tooltip-text-goals-label,
.apexcharts-tooltip-text-goals-value {
  padding: 6px 0 5px
}

.apexcharts-tooltip-goals-group,
.apexcharts-tooltip-text-goals-label,
.apexcharts-tooltip-text-goals-value {
  display: flex
}

.apexcharts-tooltip-text-goals-label:not(:empty),
.apexcharts-tooltip-text-goals-value:not(:empty) {
  margin-top: -6px
}

.apexcharts-tooltip-marker {
  display: inline-block;
  position: relative;
  width: 16px;
  height: 16px;
  font-size: 16px;
  line-height: 16px;
  margin-right: 4px;
  text-align: center;
  vertical-align: middle;
  color: inherit;
}

.apexcharts-tooltip-marker::before {
  content: "";
  display: inline-block;
  width: 100%;
  text-align: center;
  color: currentcolor;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  font-size: 26px;
  font-family: Arial, Helvetica, sans-serif;
  line-height: 14px;
  font-weight: 900;
}

.apexcharts-tooltip-marker[shape="circle"]::before {
  content: "\\25CF";
}

.apexcharts-tooltip-marker[shape="square"]::before,
.apexcharts-tooltip-marker[shape="rect"]::before {
  content: "\\25A0";
  transform: translate(-1px, -2px);
}

.apexcharts-tooltip-marker[shape="line"]::before {
  content: "\\2500";
}

.apexcharts-tooltip-marker[shape="diamond"]::before {
  content: "\\25C6";
  font-size: 28px;
}

.apexcharts-tooltip-marker[shape="triangle"]::before {
  content: "\\25B2";
  font-size: 22px;
}

.apexcharts-tooltip-marker[shape="cross"]::before {
  content: "\\2715";
  font-size: 18px;
}

.apexcharts-tooltip-marker[shape="plus"]::before {
  content: "\\2715";
  transform: rotate(45deg) translate(-1px, -1px);
  font-size: 18px;
}

.apexcharts-tooltip-marker[shape="star"]::before {
  content: "\\2605";
  font-size: 18px;
}

.apexcharts-tooltip-marker[shape="sparkle"]::before {
  content: "\\2726";
  font-size: 20px;
}

.apexcharts-tooltip-series-group {
  padding: 0 10px;
  display: none;
  text-align: left;
  justify-content: left;
  align-items: center
}

.apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {
  opacity: 1
}

.apexcharts-tooltip-series-group.apexcharts-active,
.apexcharts-tooltip-series-group:last-child {
  padding-bottom: 4px
}

.apexcharts-tooltip-y-group {
  padding: 6px 0 5px
}

.apexcharts-custom-tooltip,
.apexcharts-tooltip-box {
  padding: 4px 8px
}

.apexcharts-tooltip-boxPlot {
  display: flex;
  flex-direction: column-reverse
}

.apexcharts-tooltip-box>div {
  margin: 4px 0
}

.apexcharts-tooltip-box span.value {
  font-weight: 700
}

.apexcharts-tooltip-rangebar {
  padding: 5px 8px
}

.apexcharts-tooltip-rangebar .category {
  font-weight: 600;
  color: #777
}

.apexcharts-tooltip-rangebar .series-name {
  font-weight: 700;
  display: block;
  margin-bottom: 5px
}

.apexcharts-xaxistooltip,
.apexcharts-yaxistooltip {
  opacity: 0;
  pointer-events: none;
  color: #373d3f;
  font-size: 13px;
  text-align: center;
  border-radius: 2px;
  position: absolute;
  z-index: 10;
  background: #eceff1;
  border: 1px solid #90a4ae
}

.apexcharts-xaxistooltip {
  padding: 9px 10px;
  transition: .15s ease all
}

.apexcharts-xaxistooltip.apexcharts-theme-dark {
  background: rgba(0, 0, 0, .7);
  border: 1px solid rgba(0, 0, 0, .5);
  color: #fff
}

.apexcharts-xaxistooltip:after,
.apexcharts-xaxistooltip:before {
  left: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none
}

.apexcharts-xaxistooltip:after {
  border-color: transparent;
  border-width: 6px;
  margin-left: -6px
}

.apexcharts-xaxistooltip:before {
  border-color: transparent;
  border-width: 7px;
  margin-left: -7px
}

.apexcharts-xaxistooltip-bottom:after,
.apexcharts-xaxistooltip-bottom:before {
  bottom: 100%
}

.apexcharts-xaxistooltip-top:after,
.apexcharts-xaxistooltip-top:before {
  top: 100%
}

.apexcharts-xaxistooltip-bottom:after {
  border-bottom-color: #eceff1
}

.apexcharts-xaxistooltip-bottom:before {
  border-bottom-color: #90a4ae
}

.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after,
.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before {
  border-bottom-color: rgba(0, 0, 0, .5)
}

.apexcharts-xaxistooltip-top:after {
  border-top-color: #eceff1
}

.apexcharts-xaxistooltip-top:before {
  border-top-color: #90a4ae
}

.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after,
.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before {
  border-top-color: rgba(0, 0, 0, .5)
}

.apexcharts-xaxistooltip.apexcharts-active {
  opacity: 1;
  transition: .15s ease all
}

.apexcharts-yaxistooltip {
  padding: 4px 10px
}

.apexcharts-yaxistooltip.apexcharts-theme-dark {
  background: rgba(0, 0, 0, .7);
  border: 1px solid rgba(0, 0, 0, .5);
  color: #fff
}

.apexcharts-yaxistooltip:after,
.apexcharts-yaxistooltip:before {
  top: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
  pointer-events: none
}

.apexcharts-yaxistooltip:after {
  border-color: transparent;
  border-width: 6px;
  margin-top: -6px
}

.apexcharts-yaxistooltip:before {
  border-color: transparent;
  border-width: 7px;
  margin-top: -7px
}

.apexcharts-yaxistooltip-left:after,
.apexcharts-yaxistooltip-left:before {
  left: 100%
}

.apexcharts-yaxistooltip-right:after,
.apexcharts-yaxistooltip-right:before {
  right: 100%
}

.apexcharts-yaxistooltip-left:after {
  border-left-color: #eceff1
}

.apexcharts-yaxistooltip-left:before {
  border-left-color: #90a4ae
}

.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after,
.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before {
  border-left-color: rgba(0, 0, 0, .5)
}

.apexcharts-yaxistooltip-right:after {
  border-right-color: #eceff1
}

.apexcharts-yaxistooltip-right:before {
  border-right-color: #90a4ae
}

.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after,
.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before {
  border-right-color: rgba(0, 0, 0, .5)
}

.apexcharts-yaxistooltip.apexcharts-active {
  opacity: 1
}

.apexcharts-yaxistooltip-hidden {
  display: none
}

.apexcharts-xcrosshairs,
.apexcharts-ycrosshairs {
  pointer-events: none;
  opacity: 0;
  transition: .15s ease all
}

.apexcharts-xcrosshairs.apexcharts-active,
.apexcharts-ycrosshairs.apexcharts-active {
  opacity: 1;
  transition: .15s ease all
}

.apexcharts-ycrosshairs-hidden {
  opacity: 0
}

.apexcharts-selection-rect {
  cursor: move
}

.svg_select_shape {
  stroke-width: 1;
  stroke-dasharray: 10 10;
  stroke: black;
  stroke-opacity: 0.1;
  pointer-events: none;
  fill: none;
}

.svg_select_handle {
  stroke-width: 3;
  stroke: black;
  fill: none;
}

.svg_select_handle_r {
  cursor: e-resize;
}

.svg_select_handle_l {
  cursor: w-resize;
}

.apexcharts-svg.apexcharts-zoomable.hovering-zoom {
  cursor: crosshair
}

.apexcharts-svg.apexcharts-zoomable.hovering-pan {
  cursor: move
}

.apexcharts-menu-icon,
.apexcharts-pan-icon,
.apexcharts-reset-icon,
.apexcharts-selection-icon,
.apexcharts-toolbar-custom-icon,
.apexcharts-zoom-icon,
.apexcharts-zoomin-icon,
.apexcharts-zoomout-icon {
  cursor: pointer;
  width: 20px;
  height: 20px;
  line-height: 24px;
  color: #6e8192;
  text-align: center
}

.apexcharts-menu-icon svg,
.apexcharts-reset-icon svg,
.apexcharts-zoom-icon svg,
.apexcharts-zoomin-icon svg,
.apexcharts-zoomout-icon svg {
  fill: #6e8192
}

.apexcharts-selection-icon svg {
  fill: #444;
  transform: scale(.76)
}

.apexcharts-theme-dark .apexcharts-menu-icon svg,
.apexcharts-theme-dark .apexcharts-pan-icon svg,
.apexcharts-theme-dark .apexcharts-reset-icon svg,
.apexcharts-theme-dark .apexcharts-selection-icon svg,
.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg,
.apexcharts-theme-dark .apexcharts-zoom-icon svg,
.apexcharts-theme-dark .apexcharts-zoomin-icon svg,
.apexcharts-theme-dark .apexcharts-zoomout-icon svg {
  fill: #f3f4f5
}

.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg,
.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,
.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg {
  fill: #008ffb
}

.apexcharts-theme-light .apexcharts-menu-icon:hover svg,
.apexcharts-theme-light .apexcharts-reset-icon:hover svg,
.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,
.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,
.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,
.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg {
  fill: #333
}

.apexcharts-menu-icon,
.apexcharts-selection-icon {
  position: relative
}

.apexcharts-reset-icon {
  margin-left: 5px
}

.apexcharts-menu-icon,
.apexcharts-reset-icon,
.apexcharts-zoom-icon {
  transform: scale(.85)
}

.apexcharts-zoomin-icon,
.apexcharts-zoomout-icon {
  transform: scale(.7)
}

.apexcharts-zoomout-icon {
  margin-right: 3px
}

.apexcharts-pan-icon {
  transform: scale(.62);
  position: relative;
  left: 1px;
  top: 0
}

.apexcharts-pan-icon svg {
  fill: #fff;
  stroke: #6e8192;
  stroke-width: 2
}

.apexcharts-pan-icon.apexcharts-selected svg {
  stroke: #008ffb
}

.apexcharts-pan-icon:not(.apexcharts-selected):hover svg {
  stroke: #333
}

.apexcharts-toolbar {
  position: absolute;
  z-index: 11;
  max-width: 176px;
  text-align: right;
  border-radius: 3px;
  padding: 0 6px 2px;
  display: flex;
  justify-content: space-between;
  align-items: center
}

.apexcharts-menu {
  background: #fff;
  position: absolute;
  top: 100%;
  border: 1px solid #ddd;
  border-radius: 3px;
  padding: 3px;
  right: 10px;
  opacity: 0;
  min-width: 110px;
  transition: .15s ease all;
  pointer-events: none
}

.apexcharts-menu.apexcharts-menu-open {
  opacity: 1;
  pointer-events: all;
  transition: .15s ease all
}

.apexcharts-menu-item {
  padding: 6px 7px;
  font-size: 12px;
  cursor: pointer
}

.apexcharts-theme-light .apexcharts-menu-item:hover {
  background: #eee
}

.apexcharts-theme-dark .apexcharts-menu {
  background: rgba(0, 0, 0, .7);
  color: #fff
}

@media screen and (min-width:768px) {
  .apexcharts-canvas:hover .apexcharts-toolbar {
    opacity: 1
  }
}

/* Toolbar keyboard accessibility: show toolbar when any button inside it is focused */
.apexcharts-toolbar:focus-within {
  opacity: 1
}

/* Focus indicator for toolbar icon buttons */
.apexcharts-menu-icon:focus-visible,
.apexcharts-pan-icon:focus-visible,
.apexcharts-reset-icon:focus-visible,
.apexcharts-selection-icon:focus-visible,
.apexcharts-toolbar-custom-icon:focus-visible,
.apexcharts-zoom-icon:focus-visible,
.apexcharts-zoomin-icon:focus-visible,
.apexcharts-zoomout-icon:focus-visible {
  outline: 2px solid #008FFB;
  outline-offset: 2px;
  border-radius: 2px
}

/* Focus indicator for hamburger menu items */
.apexcharts-menu-item:focus-visible {
  outline: 2px solid #008FFB;
  outline-offset: -2px;
  background: #eee
}

.apexcharts-canvas .apexcharts-element-hidden,
.apexcharts-datalabel.apexcharts-element-hidden,
.apexcharts-hide .apexcharts-series-points {
  opacity: 0;
}

.apexcharts-hidden-element-shown {
  opacity: 1;
  transition: 0.25s ease all;
}

.apexcharts-datalabel,
.apexcharts-datalabel-label,
.apexcharts-datalabel-value,
.apexcharts-datalabels,
.apexcharts-pie-label {
  cursor: default;
  pointer-events: none
}

.apexcharts-pie-label-delay {
  opacity: 0;
  animation-name: opaque;
  animation-duration: .3s;
  animation-fill-mode: forwards;
  animation-timing-function: ease
}

.apexcharts-radialbar-label {
  cursor: pointer;
}

.apexcharts-annotation-rect,
.apexcharts-area-series .apexcharts-area,
.apexcharts-gridline,
.apexcharts-line,
.apexcharts-point-annotation-label,
.apexcharts-radar-series path:not(.apexcharts-marker),
.apexcharts-radar-series polygon,
.apexcharts-toolbar svg,
.apexcharts-tooltip .apexcharts-marker,
.apexcharts-xaxis-annotation-label,
.apexcharts-yaxis-annotation-label,
.apexcharts-zoom-rect,
.no-pointer-events {
  pointer-events: none
}

.apexcharts-tooltip-active .apexcharts-marker {
  transition: .15s ease all
}

.apexcharts-radar-series .apexcharts-yaxis {
  pointer-events: none;
}

.resize-triggers {
  animation: 1ms resizeanim;
  visibility: hidden;
  opacity: 0;
  height: 100%;
  width: 100%;
  overflow: hidden
}

.contract-trigger:before,
.resize-triggers,
.resize-triggers>div {
  content: " ";
  display: block;
  position: absolute;
  top: 0;
  left: 0
}

.resize-triggers>div {
  height: 100%;
  width: 100%;
  background: #eee;
  overflow: auto
}

.contract-trigger:before {
  overflow: hidden;
  width: 200%;
  height: 200%
}

.apexcharts-bar-goals-markers {
  pointer-events: none
}

.apexcharts-bar-shadows {
  pointer-events: none
}

.apexcharts-rangebar-goals-markers {
  pointer-events: none
}

.apexcharts-disable-transitions * {
  transition: none !important;
}`;
  class ApexCharts {
    /**
     * Creates a new ApexCharts instance.
     *
     * @param {HTMLElement} el - The DOM element to render the chart into.
     * @param {ApexOptions} opts - Chart configuration options.
     */
    constructor(el, opts) {
      // Module properties set dynamically by InitCtxVariables.initModules().
      // Declared as typed class fields so @ts-check resolves them throughout the
      // class body without errors. Each field typed as `any` since the modules are
      // plain objects whose specific shapes are not yet typed.
      /** @type {any} */
      __publicField(this, "core");
      /** @type {any} */
      __publicField(this, "responsive");
      /** @type {any} */
      __publicField(this, "axes");
      /** @type {any} */
      __publicField(this, "grid");
      /** @type {any} */
      __publicField(this, "graphics");
      /** @type {any} */
      __publicField(this, "coreUtils");
      /** @type {any} */
      __publicField(this, "crosshairs");
      /** @type {any} */
      __publicField(this, "events");
      /** @type {any} */
      __publicField(this, "fill");
      /** @type {any} */
      __publicField(this, "localization");
      /** @type {any} */
      __publicField(this, "options");
      /** @type {any} */
      __publicField(this, "series");
      /** @type {any} */
      __publicField(this, "theme");
      /** @type {any} */
      __publicField(this, "formatters");
      /** @type {any} */
      __publicField(this, "titleSubtitle");
      /** @type {any} */
      __publicField(this, "dimensions");
      /** @type {any} */
      __publicField(this, "updateHelpers");
      /** @type {any} */
      __publicField(this, "tooltip");
      /** @type {any} */
      __publicField(this, "data");
      /** @type {any} */
      __publicField(this, "animations");
      /** @type {any} */
      __publicField(this, "exports");
      /** @type {any} */
      __publicField(this, "legend");
      /** @type {any} */
      __publicField(this, "toolbar");
      /** @type {any} */
      __publicField(this, "zoomPanSelection");
      /** @type {any} */
      __publicField(this, "keyboardNavigation");
      /** @type {any} */
      __publicField(this, "annotations");
      /** @type {any} */
      __publicField(this, "timeScale");
      /** @type {any} */
      __publicField(this, "_keyboardNavigation");
      /** @type {any} */
      __publicField(this, "windowResizeHandler");
      /** @type {any} */
      __publicField(this, "parentResizeHandler");
      /** @type {string[]} */
      __publicField(this, "publicMethods", []);
      /** @type {string[]} */
      __publicField(this, "eventList", []);
      /** @type {any} */
      __publicField(this, "config");
      this.opts = opts;
      this.ctx = this;
      this.w = new Base(opts).init();
      this.el = el;
      this.w.globals.cuid = Utils$1.randomId();
      this.w.globals.chartID = this.w.config.chart.id ? Utils$1.escapeString(this.w.config.chart.id) : this.w.globals.cuid;
      const initCtx = new InitCtxVariables(this);
      initCtx.initModules();
      this.lastUpdateOptions = null;
      this.create = this.create.bind(this);
      if (Environment.isBrowser()) {
        this.windowResizeHandler = this._windowResizeHandler.bind(this);
        this.parentResizeHandler = this._parentResizeCallback.bind(this);
      }
    }
    /**
     * Renders the chart. Must be called once after construction.
     *
     * @returns {Promise<ApexCharts>} Resolves with the chart instance after mount.
     */
    render() {
      var _a, _b;
      if (!((_b = (_a = this.w) == null ? void 0 : _a.config) == null ? void 0 : _b.chart)) {
        return Promise.reject(
          new Error(
            "ApexCharts: chart configuration is missing or invalid. Ensure the options object includes a `chart` property."
          )
        );
      }
      return new Promise((resolve, reject) => {
        var _a2;
        if (Utils$1.elementExists(this.el)) {
          if (typeof Apex._chartInstances === "undefined") {
            Apex._chartInstances = [];
          }
          if (this.w.config.chart.id) {
            Apex._chartInstances.push({
              id: this.w.globals.chartID,
              group: this.w.config.chart.group,
              chart: this
            });
          }
          this.setLocale(this.w.config.chart.defaultLocale);
          const beforeMount = this.w.config.chart.events.beforeMount;
          if (typeof beforeMount === "function") {
            beforeMount(this, this.w);
          }
          this.events.fireEvent("beforeMount", [this, this.w]);
          if (Environment.isBrowser()) {
            window.addEventListener("resize", this.windowResizeHandler);
            addResizeListener(
              /** @type {HTMLElement} */
              this.el.parentNode,
              this.parentResizeHandler
            );
            const rootNode = (
              /** @type {any} */
              this.el.getRootNode && this.el.getRootNode()
            );
            const inShadowRoot = Utils$1.is("ShadowRoot", rootNode);
            const doc = this.el.ownerDocument;
            let css = inShadowRoot ? rootNode.getElementById("apexcharts-css") : doc.getElementById("apexcharts-css");
            if (!css) {
              css = BrowserAPIs.createElementNS(
                "http://www.w3.org/1999/xhtml",
                "style"
              );
              css.id = "apexcharts-css";
              css.textContent = apexCSS;
              const nonce = ((_a2 = this.opts.chart) == null ? void 0 : _a2.nonce) || this.w.config.chart.nonce;
              if (nonce) {
                css.setAttribute("nonce", nonce);
              }
              if (inShadowRoot) {
                rootNode.prepend(css);
              } else if (this.w.config.chart.injectStyleSheet !== false) {
                doc.head.appendChild(css);
              }
            }
          }
          const graphData = this.create(this.w.config.series, {});
          if (!graphData) return resolve(this);
          this.mount(graphData).then(() => {
            if (typeof this.w.config.chart.events.mounted === "function") {
              this.w.config.chart.events.mounted(this, this.w);
            }
            this.events.fireEvent("mounted", [this, this.w]);
            resolve(graphData);
          }).catch((e) => {
            var _a3, _b2;
            const enriched = e instanceof Error ? e : new Error(String(e));
            const err = (
              /** @type {any} */
              enriched
            );
            err.chartId = (_b2 = (_a3 = this.w) == null ? void 0 : _a3.globals) == null ? void 0 : _b2.chartID;
            err.el = this.el;
            reject(enriched);
          });
        } else {
          reject(new Error("Element not found"));
        }
      });
    }
    /**
     * @param {any[]} ser
     * @param {object} opts
     */
    create(ser, opts) {
      var _a;
      const w = this.w;
      if (!this.core) {
        const initCtx = new InitCtxVariables(this);
        initCtx.initModules();
      }
      const gl = this.w.globals;
      gl.noData = false;
      gl.animationEnded = false;
      if (!Utils$1.elementExists(this.el)) {
        gl.animationEnded = true;
        return null;
      }
      this.responsive.checkResponsiveConfig(opts);
      if (w.config.xaxis.convertedCatToNumeric) {
        const defaults = new Defaults(w.config);
        defaults.convertCatToNumericXaxis(w.config, this.ctx);
      }
      this.core.setupElements();
      if (w.config.chart.type === "treemap") {
        w.config.grid.show = false;
        w.config.yaxis[0].show = false;
      }
      if (gl.svgWidth === 0) {
        gl.animationEnded = true;
        return null;
      }
      let series = ser;
      ser.forEach((s, realIndex) => {
        if (s.hidden) {
          series = this.legend.legendHelpers.getSeriesAfterCollapsing({
            realIndex
          });
        }
      });
      const combo = CoreUtils.checkComboSeries(series, w.config.chart.type);
      gl.comboCharts = combo.comboCharts;
      gl.comboBarCount = combo.comboBarCount;
      const allSeriesAreEmpty = series.every((s) => s.data && s.data.length === 0);
      if (series.length === 0 || allSeriesAreEmpty && gl.collapsedSeries.length < 1) {
        this.series.handleNoData();
      }
      if (Environment.isBrowser()) {
        this.events.setupEventHandlers();
      }
      const parsedState = this.data.parseData(series);
      this._writeParsedSeriesData(parsedState.seriesData);
      this._writeParsedRangeData(parsedState.rangeData);
      this._writeParsedCandleData(parsedState.candleData);
      this._writeParsedLabelData(parsedState.labelData);
      this._writeParsedAxisFlags(parsedState.axisFlags);
      this.theme.init();
      const markers = new Markers(this.w, this);
      markers.setGlobalMarkerSize();
      this.formatters.setLabelFormatters();
      this.titleSubtitle.draw();
      if (!gl.noData || gl.collapsedSeries.length === w.seriesData.series.length || w.config.legend.showForSingleSeries) {
        (_a = this.legend) == null ? void 0 : _a.init();
      }
      this.series.hasAllSeriesEqualX();
      if (gl.axisCharts) {
        this.core.coreCalculations();
        if (w.config.xaxis.type !== "category") {
          this.formatters.setLabelFormatters();
        }
        if (this.ctx.toolbar) {
          this.ctx.toolbar.minX = w.globals.minX;
          this.ctx.toolbar.maxX = w.globals.maxX;
        }
      }
      this.formatters.heatmapLabelFormatters();
      const coreUtils = new CoreUtils(this.w);
      coreUtils.getLargestMarkerSize();
      const layoutState = this.dimensions.plotCoords();
      this._writeLayoutCoords(layoutState.layout);
      const xyRatios = this.core.xySettings();
      this.grid.createGridMask();
      const elGraph = this.core.plotChartType(series, xyRatios);
      const dataLabels = new DataLabels(this.w, this);
      dataLabels.bringForward();
      if (w.config.dataLabels.background.enabled) {
        dataLabels.dataLabelsBackground();
      }
      this.core.shiftGraphPosition();
      if (w.globals.dataPoints > 50) {
        w.dom.elWrap.classList.add("apexcharts-disable-transitions");
      }
      const dim = {
        plot: {
          left: w.layout.translateX,
          top: w.layout.translateY,
          width: w.layout.gridWidth,
          height: w.layout.gridHeight
        }
      };
      return {
        elGraph,
        xyRatios,
        dimensions: dim
      };
    }
    /**
     * @param {any} graphData
     */
    mount(graphData = null) {
      const me = this;
      const w = me.w;
      return new Promise((resolve, reject) => {
        var _a, _b, _c, _d, _e, _f, _g, _h, _i;
        if (me.el === null) {
          return reject(
            new Error("Not enough data to display or target element not found")
          );
        } else if (graphData === null || w.globals.allSeriesCollapsed) {
          me.series.handleNoData();
        }
        me.grid = new Grid(me.w, me);
        const elgrid = me.grid.drawGrid();
        const AnnotationsCtor = InitCtxVariables._featureRegistry.get("annotations");
        me.annotations = AnnotationsCtor ? new AnnotationsCtor(me.w, {
          theme: me.theme,
          timeScale: me.timeScale
        }) : null;
        (_a = me.annotations) == null ? void 0 : _a.drawImageAnnos();
        (_b = me.annotations) == null ? void 0 : _b.drawTextAnnos();
        if (w.config.grid.position === "back") {
          if (elgrid) {
            w.dom.elGraphical.add(elgrid.el);
          }
          if ((_c = elgrid == null ? void 0 : elgrid.elGridBorders) == null ? void 0 : _c.node) {
            w.dom.elGraphical.add(elgrid.elGridBorders);
          }
        }
        if (Array.isArray(graphData.elGraph)) {
          for (let g = 0; g < graphData.elGraph.length; g++) {
            w.dom.elGraphical.add(graphData.elGraph[g]);
          }
        } else {
          w.dom.elGraphical.add(graphData.elGraph);
        }
        if (w.config.grid.position === "front") {
          if (elgrid) {
            w.dom.elGraphical.add(elgrid.el);
          }
          if ((_d = elgrid == null ? void 0 : elgrid.elGridBorders) == null ? void 0 : _d.node) {
            w.dom.elGraphical.add(elgrid.elGridBorders);
          }
        }
        if (w.config.xaxis.crosshairs.position === "front") {
          me.crosshairs.drawXCrosshairs();
        }
        if (w.config.yaxis[0].crosshairs.position === "front") {
          me.crosshairs.drawYCrosshairs();
        }
        if (w.config.chart.type !== "treemap") {
          me.axes.drawAxis(w.config.chart.type, elgrid);
        }
        const xAxis = new XAxis(this.w, this.ctx, elgrid);
        const yaxis = new YAxis(
          this.w,
          { theme: this.theme, timeScale: this.timeScale },
          elgrid
        );
        if (elgrid !== null) {
          xAxis.xAxisLabelCorrections();
          yaxis.setYAxisTextAlignments();
          w.config.yaxis.map((yaxe, index) => {
            if (w.globals.ignoreYAxisIndexes.indexOf(index) === -1) {
              yaxis.yAxisTitleRotate(index, yaxe.opposite);
            }
          });
        }
        (_e = me.annotations) == null ? void 0 : _e.drawAxesAnnotations();
        if (!w.globals.noData) {
          if (Environment.isBrowser() && w.config.tooltip.enabled && !w.globals.noData) {
            (_f = me.w.globals.tooltip) == null ? void 0 : _f.drawTooltip(graphData.xyRatios);
          }
          if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled && w.config.chart.accessibility.keyboard.navigation.enabled) {
            (_g = me.keyboardNavigation) == null ? void 0 : _g.init();
          }
          if (Environment.isBrowser() && w.globals.axisCharts && (w.axisFlags.isXNumeric || /** @type {Record<string,any>} */
          w.config.xaxis.convertedCatToNumeric || w.axisFlags.isRangeBar)) {
            if (w.config.chart.zoom.enabled || w.config.chart.selection && w.config.chart.selection.enabled || // @ts-ignore — chart.pan is an internal toolbar config property
            w.config.chart.pan && w.config.chart.pan.enabled) {
              (_h = me.zoomPanSelection) == null ? void 0 : _h.init({
                xyRatios: graphData.xyRatios
              });
            }
          } else {
            const tools = w.config.chart.toolbar.tools;
            const toolsArr = [
              "zoom",
              "zoomin",
              "zoomout",
              "selection",
              "pan",
              "reset"
            ];
            toolsArr.forEach((t) => {
              tools[t] = false;
            });
          }
          if (w.config.chart.toolbar.show && !w.globals.allSeriesCollapsed) {
            (_i = me.toolbar) == null ? void 0 : _i.createToolbar();
          }
        }
        if (w.globals.memory.methodsToExec.length > 0) {
          w.globals.memory.methodsToExec.forEach((fn) => {
            fn.method(fn.params, false, fn.context);
          });
        }
        if (!w.globals.axisCharts && !w.globals.noData) {
          me.core.resizeNonAxisCharts();
        }
        resolve(me);
      });
    }
    /**
     * Destroys the chart instance, removes all DOM elements and event listeners.
     * After calling this, the instance should not be used again.
     */
    destroy() {
      if (Environment.isBrowser()) {
        window.removeEventListener("resize", this.windowResizeHandler);
        removeResizeListener(
          /** @type {Element} */
          this.el.parentNode,
          this.parentResizeHandler
        );
      }
      const chartID = this.w.config.chart.id;
      if (chartID) {
        Apex._chartInstances.forEach(
          (c, i) => {
            if (c.id === Utils$1.escapeString(chartID)) {
              Apex._chartInstances.splice(i, 1);
            }
          }
        );
      }
      if (this._keyboardNavigation) {
        this._keyboardNavigation.destroy();
      }
      new Destroy(this.ctx).clear({ isUpdating: false });
    }
    /**
     * Merges new options into the existing config and re-renders the chart.
     *
     * @param {ApexOptions} options - Partial config object merged with the existing config.
     * @param {boolean} [redraw=false] - When true, redraws the chart from scratch instead of animating from previous paths.
     * @param {boolean} [animate=true] - Whether to animate the update.
     * @param {boolean} [updateSyncedCharts=true] - Whether to propagate the update to charts in the same group.
     * @param {boolean} [overwriteInitialConfig=true] - When true, replaces the stored initial config used by resetSeries().
     * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
     */
    updateOptions(options2, redraw = false, animate = true, updateSyncedCharts = true, overwriteInitialConfig = true) {
      const w = this.w;
      w.interact.selection = void 0;
      if (this.lastUpdateOptions) {
        if (Utils$1.shallowEqual(this.lastUpdateOptions, options2)) {
          return Promise.resolve(this);
        }
        if (options2.series && this.lastUpdateOptions.series) {
          if (JSON.stringify(this.lastUpdateOptions.series) === JSON.stringify(options2.series)) {
            const optionsWithoutSeries = __spreadValues({}, options2);
            const lastWithoutSeries = __spreadValues({}, this.lastUpdateOptions);
            delete optionsWithoutSeries.series;
            delete lastWithoutSeries.series;
            if (Utils$1.shallowEqual(optionsWithoutSeries, lastWithoutSeries)) {
              return Promise.resolve(this);
            }
          }
        }
      }
      if (options2.series) {
        this.data.resetParsingFlags();
        this.series.resetSeries(false, true, false);
        if (options2.series.length && options2.series[0].data) {
          options2.series = options2.series.map(
            (s, i) => {
              return this.updateHelpers._extendSeries(s, i);
            }
          );
        }
        this.updateHelpers.revertDefaultAxisMinMax();
      }
      if (options2.xaxis) {
        options2 = this.updateHelpers.forceXAxisUpdate(options2);
      }
      if (options2.yaxis) {
        options2 = this.updateHelpers.forceYAxisUpdate(options2);
      }
      if (w.globals.collapsedSeriesIndices.length > 0) {
        this.series.clearPreviousPaths();
      }
      if (options2.theme) {
        options2 = this.theme.updateThemeOptions(options2);
      }
      return this.updateHelpers._updateOptions(
        options2,
        redraw,
        animate,
        updateSyncedCharts,
        overwriteInitialConfig
      );
    }
    /**
     * Replaces the chart's series data and re-renders.
     *
     * @param {ApexAxisChartSeries | ApexNonAxisChartSeries} [newSeries=[]] - The replacement series array.
     * @param {boolean} [animate=true] - Whether to animate the update.
     * @param {boolean} [overwriteInitialSeries=true] - When true, replaces the stored initial series used by resetSeries().
     * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
     */
    updateSeries(newSeries = [], animate = true, overwriteInitialSeries = true) {
      this.data.resetParsingFlags();
      this.series.resetSeries(false);
      this.updateHelpers.revertDefaultAxisMinMax();
      return this.updateHelpers._updateSeries(
        newSeries,
        animate,
        overwriteInitialSeries
      );
    }
    /**
     * Appends a new series to the existing series array and re-renders.
     *
     * @param {ApexAxisChartSeries[0] | ApexNonAxisChartSeries} newSerie - The series object to append.
     * @param {boolean} [animate=true] - Whether to animate the update.
     * @param {boolean} [overwriteInitialSeries=true] - When true, replaces the stored initial series used by resetSeries().
     * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
     */
    appendSeries(newSerie, animate = true, overwriteInitialSeries = true) {
      this.data.resetParsingFlags();
      const newSeries = this.w.config.series.slice();
      newSeries.push(
        /** @type {any} */
        newSerie
      );
      this.series.resetSeries(false);
      this.updateHelpers.revertDefaultAxisMinMax();
      return this.updateHelpers._updateSeries(
        newSeries,
        animate,
        overwriteInitialSeries
      );
    }
    /**
     * Appends data points to existing series without replacing them.
     * Each element of `newData` corresponds to the series at the same index.
     *
     * @param {Array<{ data: any[] }>} newData - Data to append, in the same shape as series[].data.
     * @param {boolean} [overwriteInitialSeries=true] - When true, updates the stored initial series used by resetSeries().
     * @returns {Promise<ApexCharts>} Resolves with the chart instance after re-render.
     */
    appendData(newData, overwriteInitialSeries = true) {
      const me = this;
      me.data.resetParsingFlags();
      me.w.globals.dataChanged = true;
      me.series.getPreviousPaths();
      const newSeries = me.w.config.series.slice();
      for (let i = 0; i < newSeries.length; i++) {
        if (newData[i] !== null && typeof newData[i] !== "undefined") {
          const srcSerie = (
            /** @type {any} */
            newData[i]
          );
          const dstSerie = (
            /** @type {any} */
            newSeries[i]
          );
          for (let j = 0; j < srcSerie.data.length; j++) {
            dstSerie.data.push(srcSerie.data[j]);
          }
        }
      }
      me.w.config.series = newSeries;
      if (overwriteInitialSeries) {
        me.w.globals.initialSeries = Utils$1.clone(me.w.config.series);
      }
      return this.update();
    }
    /**
     * @param {object} [options]
     */
    update(options2) {
      return new Promise((resolve, reject) => {
        if (this.lastUpdateOptions && JSON.stringify(this.lastUpdateOptions) === JSON.stringify(options2)) {
          return resolve(this);
        }
        this.lastUpdateOptions = Utils$1.clone(options2);
        new Destroy(this.ctx).clear({ isUpdating: true });
        const graphData = this.create(this.w.config.series, options2 != null ? options2 : {});
        if (!graphData) return resolve(this);
        this.mount(graphData).then(() => {
          if (typeof this.w.config.chart.events.updated === "function") {
            this.w.config.chart.events.updated(this, this.w);
          }
          this.events.fireEvent("updated", [this, this.w]);
          this.w.globals.isDirty = true;
          resolve(this);
        }).catch((e) => {
          reject(e);
        });
      });
    }
    /**
     * Fast update path for data-only series changes.
     *
     * Skips rebuilding grid, axes, dimensions, legend, annotations, tooltip DOM,
     * and toolbar. Only recalculates scales and replots the series paths.
     * Called automatically by _updateSeries() when the fast path is eligible.
     *
     * @param {boolean} animate - Whether to animate the update.
     * @returns {Promise<ApexCharts>} Resolves with the chart instance.
     */
    fastUpdate(animate) {
      return new Promise((resolve, reject) => {
        var _a;
        try {
          const w = this.w;
          const gl = w.globals;
          gl.shouldAnimate = animate;
          gl.dataChanged = true;
          gl.animationEnded = false;
          PerformanceCache.invalidateSelectors(w);
          const gl2 = w.globals;
          gl2.maxY = -Number.MAX_VALUE;
          gl2.minY = Number.MIN_VALUE;
          gl2.minYArr = [];
          gl2.maxYArr = [];
          gl2.maxX = -Number.MAX_VALUE;
          gl2.minX = Number.MAX_VALUE;
          gl2.initialMaxX = -Number.MAX_VALUE;
          gl2.initialMinX = Number.MAX_VALUE;
          gl2.yAxisScale = [];
          gl2.xAxisScale = null;
          gl2.xAxisTicksPositions = [];
          gl2.xRange = 0;
          gl2.yRange = [];
          gl2.zRange = 0;
          gl2.xTickAmount = 0;
          gl2.multiAxisTickAmount = 0;
          gl2.pointsArray = [];
          gl2.dataLabelsRects = [];
          gl2.lastDrawnDataLabelsIndexes = [];
          gl2.textRectsCache = /* @__PURE__ */ new Map();
          gl2.domCache = /* @__PURE__ */ new Map();
          gl2.cachedSelectors = {};
          gl2.disableZoomIn = false;
          gl2.disableZoomOut = false;
          if (gl.axisCharts) {
            this.core.coreCalculations();
            if (w.config.xaxis.type !== "category") {
              this.formatters.setLabelFormatters();
            }
          }
          const xyRatios = this.core.xySettings();
          const innerEl = w.dom.elGraphical.node;
          const toRemove = innerEl.querySelectorAll(
            ".apexcharts-series, .apexcharts-datalabels, .apexcharts-datalabels-background"
          );
          toRemove.forEach(
            (el) => {
              var _a2;
              return (_a2 = el.parentNode) == null ? void 0 : _a2.removeChild(el);
            }
          );
          const elGraph = this.core.plotChartType(w.config.series, xyRatios);
          const gridEl = innerEl.querySelector(".apexcharts-grid");
          const graphs = Array.isArray(elGraph) ? elGraph : [elGraph];
          if (gridEl && w.config.grid.position === "front") {
            graphs.forEach((g) => {
              const node = g && g.node ? g.node : g;
              if (node) innerEl.insertBefore(node, gridEl);
            });
          } else {
            graphs.forEach((g) => {
              w.dom.elGraphical.add(g);
            });
          }
          const dataLabels = new DataLabels(w, this);
          dataLabels.bringForward();
          if (w.config.dataLabels.background.enabled) {
            dataLabels.dataLabelsBackground();
          }
          if (Environment.isBrowser() && w.config.tooltip.enabled && !gl.noData) {
            (_a = w.globals.tooltip) == null ? void 0 : _a.drawTooltip(xyRatios);
          }
          if (typeof w.config.chart.events.updated === "function") {
            w.config.chart.events.updated(this, w);
          }
          this.events.fireEvent("updated", [this, w]);
          gl.isDirty = true;
          resolve(this);
        } catch (e) {
          reject(e);
        }
      });
    }
    /**
     * Returns all charts in the same `chart.group` (including this instance),
     * used to synchronise zoom/pan across grouped charts.
     *
     * @returns {ApexCharts[]}
     */
    getSyncedCharts() {
      const chartGroups = this.getGroupedCharts();
      let allCharts = (
        /** @type {ApexCharts[]} */
        [this]
      );
      if (chartGroups.length) {
        allCharts = [];
        chartGroups.forEach((ch) => {
          allCharts.push(ch);
        });
      }
      return allCharts;
    }
    /**
     * Returns all charts in the same `chart.group`, excluding this instance.
     * Used internally to apply hover/zoom effects to sibling charts.
     *
     * @returns {ApexCharts[]}
     */
    getGroupedCharts() {
      return Apex._chartInstances.filter((ch) => {
        if (ch.group) {
          return true;
        }
      }).map(
        (ch) => this.w.config.chart.group === ch.group ? ch.chart : this
      );
    }
    /**
     * Retrieves a rendered chart instance by its `chart.id` config value.
     *
     * @param {string} id - The chart ID set via `chart.id` in options.
     * @returns {ApexCharts | undefined}
     */
    static getChartByID(id) {
      const chartId = Utils$1.escapeString(id);
      if (!Apex._chartInstances) return void 0;
      const c = Apex._chartInstances.filter(
        (ch) => ch.id === chartId
      )[0];
      return c && c.chart;
    }
    /**
     * Scans the document for elements with a `data-apexcharts` attribute and
     * `data-options` JSON, then renders a chart in each one automatically.
     * Useful for non-framework HTML pages.
     */
    static initOnLoad() {
      var _a;
      const els = document.querySelectorAll("[data-apexcharts]");
      for (let i = 0; i < els.length; i++) {
        const el = (
          /** @type {HTMLElement} */
          els[i]
        );
        const options2 = JSON.parse((_a = els[i].getAttribute("data-options")) != null ? _a : "");
        const apexChart = new ApexCharts(el, options2);
        apexChart.render();
      }
    }
    /**
     * This static method allows users to call chart methods without necessarily from the
     * instance of the chart in case user has assigned chartID to the targeted chart.
     * The chartID is used for mapping the instance stored in Apex._chartInstances global variable
     *
     * This is helpful in cases when you don't have reference of the chart instance
     * easily and need to call the method from anywhere.
     * For eg, in React/Vue applications when you have many parent/child components,
     * and need easy reference to other charts for performing dynamic operations
     *
     * @param {string} chartID - The unique identifier which will be used to call methods
     * on that chart instance
     * @param {string} fn - The method name to call
     * @param {...any} opts - The parameters which are accepted in the original method will be passed here in the same order.
     */
    static exec(chartID, fn, ...opts) {
      const chart = this.getChartByID(chartID);
      if (!chart) return;
      chart.w.globals.isExecCalled = true;
      let ret = null;
      if (chart.publicMethods.indexOf(fn) !== -1) {
        ret = /** @type {any} */
        chart[fn](...opts);
      }
      return ret;
    }
    /**
     * Deep-merges `source` into `target` and returns the result.
     * Thin wrapper around the internal `Utils.extend` utility.
     *
     * @param {object} target
     * @param {object} source
     * @returns {object}
     */
    static merge(target, source) {
      return Utils$1.extend(target, source);
    }
    static getThemePalettes() {
      return getThemePalettes();
    }
    /**
     * Register additional chart types. Used by sub-entry points so that only
     * the types they include are bundled.
     *
     * @param {Record<string, new (...args: any[]) => any>} typeMap  e.g. { line: Line, area: Line }
     */
    static use(typeMap) {
      register(typeMap);
    }
    /**
     * Register optional feature modules (Exports, Legend, Toolbar,
     * ZoomPanSelection, KeyboardNavigation, Annotations).
     *
     * Call this before rendering any chart. Feature entry files (e.g.
     * `apexcharts/features/legend`) call this automatically when imported.
     * Note: Tooltip is part of core and does not need to be registered.
     *
     * @param {Record<string, new (...args: any[]) => any>} featureMap  e.g. { legend: Legend, exports: Exports }
     */
    static registerFeatures(featureMap) {
      InitCtxVariables.registerFeatures(featureMap);
    }
    /**
     * Toggles (show/hide) the series identified by name.
     * Mirrors a click on the corresponding legend item.
     *
     * @param {string} seriesName
     * @returns {object | undefined} The collapsed series object, if now hidden.
     */
    toggleSeries(seriesName) {
      return this.series.toggleSeries(seriesName);
    }
    /**
     * Highlights or un-highlights a series when the user hovers a legend item.
     * Called internally by the legend; not typically called by consumers.
     *
     * @param {MouseEvent} e
     * @param {HTMLElement} targetElement - The legend marker element being hovered.
     */
    highlightSeriesOnLegendHover(e, targetElement) {
      return this.series.toggleSeriesOnHover(e, targetElement);
    }
    /**
     * Makes a previously hidden series visible and re-renders.
     *
     * @param {string} seriesName
     */
    showSeries(seriesName) {
      this.series.showSeries(seriesName);
    }
    /**
     * Hides a visible series and re-renders.
     *
     * @param {string} seriesName
     */
    hideSeries(seriesName) {
      this.series.hideSeries(seriesName);
    }
    /**
     * Highlights (dims all other series) the series identified by name.
     *
     * @param {string} seriesName
     */
    highlightSeries(seriesName) {
      this.series.highlightSeries(seriesName);
    }
    /**
     * Returns whether the series identified by name is currently hidden.
     *
     * @param {string} seriesName
     * @returns {boolean}
     */
    isSeriesHidden(seriesName) {
      return this.series.isSeriesHidden(seriesName);
    }
    /**
     * Resets the chart to the initial series and optionally the initial zoom level.
     *
     * @param {boolean} [shouldUpdateChart=true] - When true, triggers a re-render.
     * @param {boolean} [shouldResetZoom=true] - When true, restores the initial zoom level.
     */
    resetSeries(shouldUpdateChart = true, shouldResetZoom = true) {
      this.series.resetSeries(shouldUpdateChart, shouldResetZoom);
    }
    /**
     * Subscribes to a chart event by name.
     * Supported event names mirror the `chart.events` option keys
     * (e.g. `'mounted'`, `'updated'`, `'dataPointMouseEnter'`).
     *
     * @param {string} name - Event name.
     * @param {Function} handler - Callback invoked when the event fires.
     */
    addEventListener(name2, handler) {
      this.events.addEventListener(name2, handler);
    }
    /**
     * Removes a previously registered event listener.
     *
     * @param {string} name - Event name.
     * @param {Function} handler - The exact function reference passed to addEventListener.
     */
    removeEventListener(name2, handler) {
      this.events.removeEventListener(name2, handler);
    }
    /**
     * Adds an x-axis annotation dynamically after render.
     *
     * @param {XAxisAnnotations} opts - Annotation configuration.
     * @param {boolean} [pushToMemory=true] - When true, the annotation persists across re-renders.
     * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
     */
    addXaxisAnnotation(opts, pushToMemory = true, context = void 0) {
      var _a;
      let me = (
        /** @type {ApexCharts} */
        /** @type {unknown} */
        this
      );
      if (context) {
        me = context;
      }
      (_a = me.annotations) == null ? void 0 : _a.addXaxisAnnotationExternal(opts, pushToMemory, me);
    }
    /**
     * Adds a y-axis annotation dynamically after render.
     *
     * @param {YAxisAnnotations} opts - Annotation configuration.
     * @param {boolean} [pushToMemory=true] - When true, the annotation persists across re-renders.
     * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
     */
    addYaxisAnnotation(opts, pushToMemory = true, context = void 0) {
      var _a;
      let me = (
        /** @type {ApexCharts} */
        /** @type {unknown} */
        this
      );
      if (context) {
        me = context;
      }
      (_a = me.annotations) == null ? void 0 : _a.addYaxisAnnotationExternal(opts, pushToMemory, me);
    }
    /**
     * Adds a point annotation dynamically after render.
     *
     * @param {PointAnnotations} opts - Annotation configuration.
     * @param {boolean} [pushToMemory=true] - When true, the annotation persists across re-renders.
     * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
     */
    addPointAnnotation(opts, pushToMemory = true, context = void 0) {
      var _a;
      let me = (
        /** @type {ApexCharts} */
        /** @type {unknown} */
        this
      );
      if (context) {
        me = context;
      }
      (_a = me.annotations) == null ? void 0 : _a.addPointAnnotationExternal(opts, pushToMemory, me);
    }
    /**
     * Removes all annotations from the chart.
     *
     * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
     */
    clearAnnotations(context = void 0) {
      var _a;
      let me = (
        /** @type {ApexCharts} */
        /** @type {unknown} */
        this
      );
      if (context) {
        me = context;
      }
      (_a = me.annotations) == null ? void 0 : _a.clearAnnotations(me);
    }
    /**
     * Removes a specific annotation by its `id`.
     *
     * @param {string} id - The annotation id as set in the annotation config.
     * @param {ApexCharts} [context] - Override the target chart instance (used by exec()).
     */
    removeAnnotation(id, context = void 0) {
      var _a;
      let me = (
        /** @type {ApexCharts} */
        /** @type {unknown} */
        this
      );
      if (context) {
        me = context;
      }
      (_a = me.annotations) == null ? void 0 : _a.removeAnnotation(me, id);
    }
    /**
     * Returns the inner SVG group element that contains all chart graphics.
     *
     * @returns {Element | null}
     */
    getChartArea() {
      const el = this.w.dom.baseEl.querySelector(".apexcharts-inner");
      return el;
    }
    /**
     * Returns the sum of all data points whose x value falls within [minX, maxX].
     *
     * @param {number} minX
     * @param {number} maxX
     * @returns {number[]} One total per series.
     */
    getSeriesTotalXRange(minX, maxX) {
      return this.coreUtils.getSeriesTotalsXRange(minX, maxX);
    }
    /**
     * Returns the highest y value in the specified series.
     *
     * @param {number} [seriesIndex=0]
     * @returns {number}
     */
    getHighestValueInSeries(seriesIndex = 0) {
      const range = new Range(this.w);
      return range.getMinYMaxY(seriesIndex).highestY;
    }
    /**
     * Returns the lowest y value in the specified series.
     *
     * @param {number} [seriesIndex=0]
     * @returns {number}
     */
    getLowestValueInSeries(seriesIndex = 0) {
      const range = new Range(this.w);
      return range.getMinYMaxY(seriesIndex).lowestY;
    }
    /**
     * Returns the sum of each series (the totals used for percentage calculations).
     *
     * @returns {number[]}
     */
    getSeriesTotal() {
      return this.w.globals.seriesTotals;
    }
    /**
     * Returns a curated snapshot of chart state for use in formatters, events,
     * and external integrations. Prefer this over accessing `chart.w` directly.
     *
     * The shape of this object is stable and versioned. `chart.w` is internal
     * and will be restricted in a future major version.
     */
    getState() {
      const w = this.w;
      const gl = w.globals;
      return {
        // Series data — computed/parsed form used for rendering
        series: w.seriesData.series,
        seriesNames: w.seriesData.seriesNames,
        colors: gl.colors,
        labels: w.labelData.labels,
        seriesTotals: gl.seriesTotals,
        seriesPercent: gl.seriesPercent,
        seriesXvalues: gl.seriesXvalues,
        seriesYvalues: gl.seriesYvalues,
        // Axis bounds — updated after each render
        minX: gl.minX,
        maxX: gl.maxX,
        minY: gl.minY,
        maxY: gl.maxY,
        minYArr: gl.minYArr,
        maxYArr: gl.maxYArr,
        minXDiff: gl.minXDiff,
        dataPoints: gl.dataPoints,
        // Axis scale objects — computed tick/scale results
        xAxisScale: gl.xAxisScale,
        yAxisScale: gl.yAxisScale,
        xTickAmount: gl.xTickAmount,
        // Axis type flags
        isXNumeric: w.axisFlags.isXNumeric,
        // Multi-axis series mapping
        seriesYAxisMap: gl.seriesYAxisMap,
        seriesYAxisReverseMap: gl.seriesYAxisReverseMap,
        // Chart dimensions — updated after each render/resize
        svgWidth: gl.svgWidth,
        svgHeight: gl.svgHeight,
        gridWidth: w.layout.gridWidth,
        gridHeight: w.layout.gridHeight,
        // Interactive state
        selectedDataPoints: w.interact.selectedDataPoints,
        collapsedSeriesIndices: gl.collapsedSeriesIndices,
        zoomed: w.interact.zoomed,
        // Chart-type-specific series data (null when not applicable)
        seriesX: w.seriesData.seriesX,
        seriesZ: w.seriesData.seriesZ,
        seriesCandleO: w.candleData.seriesCandleO,
        seriesCandleH: w.candleData.seriesCandleH,
        seriesCandleM: w.candleData.seriesCandleM,
        seriesCandleL: w.candleData.seriesCandleL,
        seriesCandleC: w.candleData.seriesCandleC,
        seriesRangeStart: w.rangeData.seriesRangeStart,
        seriesRangeEnd: w.rangeData.seriesRangeEnd,
        seriesGoals: w.seriesData.seriesGoals
      };
    }
    /**
     * Programmatically selects or deselects a data point.
     * Equivalent to a user click on the data point.
     *
     * @param {number} seriesIndex - Zero-based series index.
     * @param {number} [dataPointIndex] - Zero-based data point index within the series.
     * @returns {number[][] | null} Updated selectedDataPoints array, or null.
     */
    toggleDataPointSelection(seriesIndex, dataPointIndex) {
      return this.updateHelpers.toggleDataPointSelection(
        seriesIndex,
        dataPointIndex
      );
    }
    /**
     * Programmatically zooms the x-axis to the given range.
     * Requires zoom to be enabled (`chart.zoom.enabled: true`).
     *
     * @param {number} min - The minimum x value (timestamp or numeric).
     * @param {number} max - The maximum x value (timestamp or numeric).
     */
    zoomX(min, max) {
      var _a;
      (_a = this.ctx.toolbar) == null ? void 0 : _a.zoomUpdateOptions(min, max);
    }
    /**
     * Switches the active locale, updating all locale-dependent labels (toolbar tooltips, month names, etc.).
     *
     * @param {string} localeName - Must match a locale name defined in `chart.locales`.
     */
    setLocale(localeName) {
      this.localization.setCurrentLocaleValues(localeName);
    }
    /**
     * Exports the chart to a PNG or SVG data URI.
     * Requires the Exports feature: `import 'apexcharts/features/exports'`.
     *
     * @param {{ scale?: number, width?: number }} [options]
     * @returns {Promise<{ imgURI: string } | { blob: Blob }>}
     */
    dataURI(options2) {
      if (!this.ctx.exports)
        throw new Error(
          "apexcharts: Exports feature is not registered. Import apexcharts/features/exports."
        );
      return this.ctx.exports.dataURI(options2);
    }
    /**
     * Returns the chart's SVG markup as a string, optionally scaled.
     * Requires the Exports feature: `import 'apexcharts/features/exports'`.
     *
     * @param {number} [scale=1]
     * @returns {Promise<string>}
     */
    getSvgString(scale) {
      if (!this.ctx.exports)
        throw new Error(
          "apexcharts: Exports feature is not registered. Import apexcharts/features/exports."
        );
      return this.ctx.exports.getSvgString(scale);
    }
    /**
     * Triggers a CSV download of the chart's data.
     * Requires the Exports feature: `import 'apexcharts/features/exports'`.
     *
     * @param {{ series?: any, fileName?: string, columnDelimiter?: string, lineDelimiter?: string }} [options]
     */
    exportToCSV(options2 = {}) {
      if (!this.ctx.exports)
        throw new Error(
          "apexcharts: Exports feature is not registered. Import apexcharts/features/exports."
        );
      return this.ctx.exports.exportToCSV(options2);
    }
    paper() {
      return this.w.dom.Paper;
    }
    // ─── Slice write-back stubs ─────────────────────────────────────────────────
    /**
     * @param {Partial<import('./types/internal').SeriesData>} slice
     */
    _writeParsedSeriesData(slice) {
      Object.assign(this.w.seriesData, slice);
    }
    /**
     * @param {Partial<import('./types/internal').RangeData>} slice
     */
    _writeParsedRangeData(slice) {
      Object.assign(this.w.rangeData, slice);
    }
    /**
     * @param {Partial<import('./types/internal').CandleData>} slice
     */
    _writeParsedCandleData(slice) {
      Object.assign(this.w.candleData, slice);
    }
    /**
     * @param {Partial<import('./types/internal').LabelData>} slice
     */
    _writeParsedLabelData(slice) {
      Object.assign(this.w.labelData, slice);
    }
    /**
     * @param {Partial<import('./types/internal').AxisFlags>} slice
     */
    _writeParsedAxisFlags(slice) {
      Object.assign(this.w.axisFlags, slice);
    }
    /**
     * @param {Partial<import('./types/internal').LayoutCoords>} slice
     */
    _writeLayoutCoords(slice) {
      Object.assign(this.w.layout, slice);
    }
    _parentResizeCallback() {
      if (this.w.globals.animationEnded && this.w.config.chart.redrawOnParentResize) {
        this._windowResize();
      }
    }
    /**
     * Handle window resize and re-draw the whole chart.
     */
    _windowResize() {
      this.w.globals.resizeTimer = window.setTimeout(() => {
        this.w.globals.resized = true;
        this.w.globals.dataChanged = false;
        this.ctx.update();
      }, 150);
    }
    _windowResizeHandler() {
      var _a;
      clearTimeout((_a = this.w.globals.resizeTimer) != null ? _a : void 0);
      let { redrawOnWindowResize: redraw } = this.w.config.chart;
      if (typeof redraw === "function") {
        redraw = /** @type {any} */
        redraw();
      }
      redraw && this._windowResize();
    }
  }
  const apexchartsLegendCSS = ".apexcharts-flip-y {\n  transform: scaleY(-1) translateY(-100%);\n  transform-origin: top;\n  transform-box: fill-box;\n}\n.apexcharts-flip-x {\n  transform: scaleX(-1);\n  transform-origin: center;\n  transform-box: fill-box;\n}\n.apexcharts-legend {\n  display: flex;\n  overflow: auto;\n  padding: 0 10px;\n}\n.apexcharts-legend.apexcharts-legend-group-horizontal {\n  flex-direction: column;\n}\n.apexcharts-legend-group {\n  display: flex;\n}\n.apexcharts-legend-group-vertical {\n  flex-direction: column-reverse;\n}\n.apexcharts-legend.apx-legend-position-bottom, .apexcharts-legend.apx-legend-position-top {\n  flex-wrap: wrap\n}\n.apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n  flex-direction: column;\n  bottom: 0;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-left, .apexcharts-legend.apx-legend-position-top.apexcharts-align-left, .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n  justify-content: flex-start;\n  align-items: flex-start;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-center, .apexcharts-legend.apx-legend-position-top.apexcharts-align-center {\n  justify-content: center;\n  align-items: center;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-right, .apexcharts-legend.apx-legend-position-top.apexcharts-align-right {\n  justify-content: flex-end;\n  align-items: flex-end;\n}\n.apexcharts-legend-series {\n  cursor: pointer;\n  line-height: normal;\n  display: flex;\n  align-items: center;\n}\n.apexcharts-legend-text {\n  position: relative;\n  font-size: 14px;\n}\n.apexcharts-legend-text *, .apexcharts-legend-marker * {\n  pointer-events: none;\n}\n.apexcharts-legend-marker {\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  cursor: pointer;\n  margin-right: 1px;\n}\n\n.apexcharts-legend-series.apexcharts-no-click {\n  cursor: auto;\n}\n.apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {\n  display: none !important;\n}\n.apexcharts-inactive-legend {\n  opacity: 0.45;\n} ";
  class Exports {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
    }
    /**
     * @param {string} svgString
     */
    svgStringToNode(svgString) {
      const parser = new DOMParser();
      const svgDoc = parser.parseFromString(svgString, "image/svg+xml");
      return svgDoc.documentElement;
    }
    /**
     * @param {any} svg
     * @param {number} scale
     */
    scaleSvgNode(svg, scale) {
      const svgWidth = parseFloat(svg.getAttributeNS(null, "width"));
      const svgHeight = parseFloat(svg.getAttributeNS(null, "height"));
      svg.setAttributeNS(null, "width", svgWidth * scale);
      svg.setAttributeNS(null, "height", svgHeight * scale);
      svg.setAttributeNS(null, "viewBox", "0 0 " + svgWidth + " " + svgHeight);
    }
    /**
     * @param {number} [_scale]
     */
    getSvgString(_scale) {
      return new Promise((resolve) => {
        const w = this.w;
        let scale = _scale || w.config.chart.toolbar.export.scale || w.config.chart.toolbar.export.width / w.globals.svgWidth;
        if (!scale) {
          scale = 1;
        }
        const width = w.globals.svgWidth * scale;
        const height = w.globals.svgHeight * scale;
        const clonedNode = (
          /** @type {HTMLElement} */
          w.dom.elWrap.cloneNode(true)
        );
        clonedNode.style.width = width + "px";
        clonedNode.style.height = height + "px";
        const serializedNode = new XMLSerializer().serializeToString(clonedNode);
        const shouldIncludeLegendStyles = w.config.legend.show && w.dom.elLegendWrap && w.dom.elLegendWrap.children.length > 0;
        let exportStyles = `
        .apexcharts-tooltip, .apexcharts-toolbar, .apexcharts-xaxistooltip, .apexcharts-yaxistooltip, .apexcharts-xcrosshairs, .apexcharts-ycrosshairs, .apexcharts-zoom-rect, .apexcharts-selection-rect {
          display: none;
        }
      `;
        if (shouldIncludeLegendStyles) {
          exportStyles += apexchartsLegendCSS;
        }
        let svgString = `
        <svg xmlns="http://www.w3.org/2000/svg"
          version="1.1"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          class="apexcharts-svg"
          xmlns:data="ApexChartsNS"
          transform="translate(0, 0)"
          width="${w.globals.svgWidth}px" height="${w.globals.svgHeight}px">
          <foreignObject width="100%" height="100%">
            <div xmlns="http://www.w3.org/1999/xhtml" style="width:${width}px; height:${height}px;">
            <style type="text/css">
              ${exportStyles}
            </style>
              ${serializedNode}
            </div>
          </foreignObject>
        </svg>
      `;
        const svgNode = this.svgStringToNode(svgString);
        if (scale !== 1) {
          this.scaleSvgNode(svgNode, scale);
        }
        this.convertImagesToBase64(svgNode).then(() => {
          svgString = new XMLSerializer().serializeToString(svgNode);
          resolve(svgString.replace(/&nbsp;/g, "&#160;"));
        });
      });
    }
    /**
     * @param {any} svgNode
     */
    convertImagesToBase64(svgNode) {
      const images = svgNode.getElementsByTagName("image");
      const promises = Array.from(images).map((img) => {
        const href = img.getAttributeNS("http://www.w3.org/1999/xlink", "href");
        if (href && !href.startsWith("data:")) {
          return this.getBase64FromUrl(href).then((base64) => {
            img.setAttributeNS("http://www.w3.org/1999/xlink", "href", base64);
          }).catch((error) => {
            console.error("Error converting image to base64:", error);
          });
        }
        return Promise.resolve();
      });
      return Promise.all(promises);
    }
    /**
     * @param {string} url
     */
    getBase64FromUrl(url) {
      if (Environment.isSSR()) return Promise.resolve(url);
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.crossOrigin = "Anonymous";
        img.onload = () => {
          const canvas = document.createElement("canvas");
          canvas.width = img.width;
          canvas.height = img.height;
          const ctx = canvas.getContext("2d");
          if (ctx) ctx.drawImage(img, 0, 0);
          resolve(canvas.toDataURL());
        };
        img.onerror = reject;
        img.src = url;
      });
    }
    svgUrl() {
      return new Promise((resolve) => {
        this.getSvgString().then((svgData) => {
          const svgBlob = new Blob([svgData], {
            type: "image/svg+xml;charset=utf-8"
          });
          resolve(URL.createObjectURL(svgBlob));
        });
      });
    }
    /**
     * @param {Record<string, any> | undefined} options
     */
    dataURI(options2) {
      if (Environment.isSSR()) return Promise.resolve({ imgURI: "" });
      return new Promise((resolve) => {
        const w = this.w;
        const scale = options2 ? options2.scale || options2.width / w.globals.svgWidth : 1;
        const canvas = document.createElement("canvas");
        canvas.width = w.globals.svgWidth * scale;
        canvas.height = parseInt(w.dom.elWrap.style.height, 10) * scale;
        const canvasBg = w.config.chart.background === "transparent" || !w.config.chart.background ? "#fff" : w.config.chart.background;
        const ctx = canvas.getContext("2d");
        if (!ctx) return;
        ctx.fillStyle = canvasBg;
        ctx.fillRect(0, 0, canvas.width * scale, canvas.height * scale);
        this.getSvgString(scale).then((svgData) => {
          const svgUrl = "data:image/svg+xml," + encodeURIComponent(svgData);
          const img = new Image();
          img.crossOrigin = "anonymous";
          img.onload = () => {
            ctx.drawImage(img, 0, 0);
            const edgeCanvas = canvas;
            if (edgeCanvas.msToBlob) {
              const blob = edgeCanvas.msToBlob();
              resolve({ blob });
            } else {
              const imgURI = canvas.toDataURL("image/png");
              resolve({ imgURI });
            }
          };
          img.src = svgUrl;
        });
      });
    }
    exportToSVG() {
      this.svgUrl().then((url) => {
        this.triggerDownload(
          url,
          this.w.config.chart.toolbar.export.svg.filename,
          ".svg"
        );
      });
    }
    exportToPng() {
      const scale = this.w.config.chart.toolbar.export.scale;
      const width = this.w.config.chart.toolbar.export.width;
      const option = scale ? { scale } : width ? { width } : void 0;
      this.dataURI(option).then(({ imgURI, blob }) => {
        if (blob) {
          navigator.msSaveOrOpenBlob(blob, this.w.globals.chartID + ".png");
        } else {
          this.triggerDownload(
            imgURI,
            this.w.config.chart.toolbar.export.png.filename,
            ".png"
          );
        }
      });
    }
    /** @param {{ series?: any, fileName?: any, columnDelimiter?: string, lineDelimiter?: string }} opts */
    exportToCSV({
      series,
      fileName,
      columnDelimiter = ",",
      lineDelimiter = "\n"
    }) {
      const w = this.w;
      if (!series) series = w.config.series;
      let columns = [];
      const rows = [];
      let result = "";
      const universalBOM = "\uFEFF";
      const gSeries = w.seriesData.series.map((s, i) => {
        return w.globals.collapsedSeriesIndices.indexOf(i) === -1 ? s : [];
      });
      const getFormattedCategory = (cat) => {
        if (typeof w.config.chart.toolbar.export.csv.categoryFormatter === "function") {
          return w.config.chart.toolbar.export.csv.categoryFormatter(cat);
        }
        if (w.config.xaxis.type === "datetime" && String(cat).length >= 10) {
          return new Date(cat).toDateString();
        }
        return Utils$1.isNumber(cat) ? cat : cat.split(columnDelimiter).join("");
      };
      const getFormattedValue = (value) => {
        return typeof w.config.chart.toolbar.export.csv.valueFormatter === "function" ? w.config.chart.toolbar.export.csv.valueFormatter(value) : value;
      };
      const seriesMaxDataLength = Math.max(
        ...series.map((s) => {
          return s.data ? s.data.length : 0;
        })
      );
      const dataFormat = new Data(this.w);
      const axesUtils = new AxesUtils(this.w, {
        theme: this.ctx.theme,
        timeScale: this.ctx.timeScale
      });
      const getCat = (i) => {
        let cat = "";
        if (!w.globals.axisCharts) {
          cat = w.config.labels[i];
        } else {
          if (w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) {
            if (w.globals.isBarHorizontal) {
              const lbFormatter = w.formatters.yLabelFormatters[0];
              const sr = new Series(this.ctx.w);
              const activeSeries = sr.getActiveConfigSeriesIndex();
              cat = lbFormatter(w.labelData.labels[i], {
                seriesIndex: activeSeries,
                dataPointIndex: i,
                w
              });
            } else {
              cat = axesUtils.getLabel(
                w.labelData.labels,
                w.labelData.timescaleLabels,
                0,
                i
              ).text;
            }
          }
          if (w.config.xaxis.type === "datetime") {
            if (w.config.xaxis.categories.length) {
              cat = w.config.xaxis.categories[i];
            } else if (w.config.labels.length) {
              cat = w.config.labels[i];
            }
          }
        }
        if (cat === null) return "nullvalue";
        if (Array.isArray(cat)) {
          cat = cat.join(" ");
        }
        return Utils$1.isNumber(cat) ? cat : cat.split(columnDelimiter).join("");
      };
      const getEmptyDataForCsvColumn = () => {
        return [...Array(seriesMaxDataLength)].map(() => "");
      };
      const handleAxisRowsColumns = (s, sI) => {
        var _a;
        if (columns.length && sI === 0) {
          rows.push(columns.join(columnDelimiter));
        }
        if (s.data) {
          s.data = s.data.length && s.data || getEmptyDataForCsvColumn();
          for (let i = 0; i < s.data.length; i++) {
            columns = [];
            let cat = getCat(i);
            if (cat === "nullvalue") continue;
            if (!cat) {
              if (dataFormat.isFormatXY()) {
                cat = series[sI].data[i].x;
              } else if (dataFormat.isFormat2DArray()) {
                cat = series[sI].data[i] ? series[sI].data[i][0] : "";
              }
            }
            if (sI === 0) {
              columns.push(getFormattedCategory(cat));
              for (let ci = 0; ci < w.seriesData.series.length; ci++) {
                const value = dataFormat.isFormatXY() ? (_a = series[ci].data[i]) == null ? void 0 : _a.y : gSeries[ci][i];
                columns.push(getFormattedValue(value));
              }
            }
            if (w.config.chart.type === "candlestick" || s.type && s.type === "candlestick") {
              columns.pop();
              columns.push(w.candleData.seriesCandleO[sI][i]);
              columns.push(w.candleData.seriesCandleH[sI][i]);
              columns.push(w.candleData.seriesCandleL[sI][i]);
              columns.push(w.candleData.seriesCandleC[sI][i]);
            }
            if (w.config.chart.type === "boxPlot" || s.type && s.type === "boxPlot") {
              columns.pop();
              columns.push(w.candleData.seriesCandleO[sI][i]);
              columns.push(w.candleData.seriesCandleH[sI][i]);
              columns.push(w.candleData.seriesCandleM[sI][i]);
              columns.push(w.candleData.seriesCandleL[sI][i]);
              columns.push(w.candleData.seriesCandleC[sI][i]);
            }
            if (w.config.chart.type === "rangeBar") {
              columns.pop();
              columns.push(w.rangeData.seriesRangeStart[sI][i]);
              columns.push(w.rangeData.seriesRangeEnd[sI][i]);
            }
            if (columns.length) {
              rows.push(columns.join(columnDelimiter));
            }
          }
        }
      };
      const handleUnequalXValues = () => {
        const categories = /* @__PURE__ */ new Set();
        const data = {};
        series.forEach((s, sI) => {
          s == null ? void 0 : s.data.forEach((dataItem) => {
            let cat, value;
            if (dataFormat.isFormatXY()) {
              cat = dataItem.x;
              value = dataItem.y;
            } else if (dataFormat.isFormat2DArray()) {
              cat = dataItem[0];
              value = dataItem[1];
            } else {
              return;
            }
            if (!/** @type {Record<string,any>} */
            data[cat]) {
              data[cat] = Array(
                series.length
              ).fill("");
            }
            data[cat][sI] = getFormattedValue(value);
            categories.add(cat);
          });
        });
        if (columns.length) {
          rows.push(columns.join(columnDelimiter));
        }
        Array.from(categories).sort().forEach((cat) => {
          rows.push([
            getFormattedCategory(cat),
            /** @type {Record<string,any>} */
            data[cat].join(columnDelimiter)
          ]);
        });
      };
      columns.push(w.config.chart.toolbar.export.csv.headerCategory);
      if (w.config.chart.type === "boxPlot") {
        columns.push("minimum");
        columns.push("q1");
        columns.push("median");
        columns.push("q3");
        columns.push("maximum");
      } else if (w.config.chart.type === "candlestick") {
        columns.push("open");
        columns.push("high");
        columns.push("low");
        columns.push("close");
      } else if (w.config.chart.type === "rangeBar") {
        columns.push("minimum");
        columns.push("maximum");
      } else {
        series.map((s, sI) => {
          const sname = (s.name ? s.name : `series-${sI}`) + "";
          if (w.globals.axisCharts) {
            columns.push(
              sname.split(columnDelimiter).join("") ? sname.split(columnDelimiter).join("") : `series-${sI}`
            );
          }
        });
      }
      if (!w.globals.axisCharts) {
        columns.push(w.config.chart.toolbar.export.csv.headerValue);
        rows.push(columns.join(columnDelimiter));
      }
      if (!w.globals.allSeriesHasEqualX && w.globals.axisCharts && !w.config.xaxis.categories.length && !w.config.labels.length) {
        handleUnequalXValues();
      } else {
        series.map((s, sI) => {
          if (w.globals.axisCharts) {
            handleAxisRowsColumns(s, sI);
          } else {
            columns = [];
            columns.push(getFormattedCategory(w.labelData.labels[sI]));
            columns.push(getFormattedValue(gSeries[sI]));
            rows.push(columns.join(columnDelimiter));
          }
        });
      }
      result += rows.join(lineDelimiter);
      this.triggerDownload(
        "data:text/csv; charset=utf-8," + encodeURIComponent(universalBOM + result),
        fileName ? fileName : w.config.chart.toolbar.export.csv.filename,
        ".csv"
      );
    }
    /**
     * @param {string} href
     * @param {string} filename
     * @param {string} ext
     */
    triggerDownload(href, filename, ext) {
      if (Environment.isSSR()) return;
      const downloadLink = document.createElement("a");
      downloadLink.href = href;
      downloadLink.download = (filename ? filename : this.w.globals.chartID) + ext;
      document.body.appendChild(downloadLink);
      downloadLink.click();
      document.body.removeChild(downloadLink);
    }
  }
  ApexCharts.registerFeatures({ exports: Exports });
  let Helpers$3 = class Helpers {
    /**
     * @param {import('./Legend').default} lgCtx
     */
    constructor(lgCtx) {
      this.w = lgCtx.w;
      this.lgCtx = lgCtx;
    }
    getLegendStyles() {
      if (Environment.isSSR()) return null;
      const stylesheet = document.createElement("style");
      stylesheet.setAttribute("type", "text/css");
      const nonce = this.w.config.chart.nonce;
      if (nonce) {
        stylesheet.setAttribute("nonce", nonce);
      }
      const rule = document.createTextNode(apexchartsLegendCSS);
      stylesheet.appendChild(rule);
      return stylesheet;
    }
    getLegendDimensions() {
      const w = this.w;
      const currLegendsWrap = w.dom.baseEl.querySelector(".apexcharts-legend");
      if (!currLegendsWrap) {
        return { clwh: 0, clww: 0 };
      }
      const { width: currLegendsWrapWidth, height: currLegendsWrapHeight } = currLegendsWrap.getBoundingClientRect();
      return {
        clwh: currLegendsWrapHeight,
        clww: currLegendsWrapWidth
      };
    }
    appendToForeignObject() {
      var _a;
      const legendStyles = this.getLegendStyles();
      if (this.w.config.chart.injectStyleSheet !== false && legendStyles) {
        (_a = this.w.dom.elLegendForeign) == null ? void 0 : _a.appendChild(legendStyles);
      }
    }
    /**
     * @param {number} seriesCnt
     * @param {boolean} isHidden
     */
    toggleDataSeries(seriesCnt, isHidden) {
      var _a, _b;
      const w = this.w;
      if (w.globals.axisCharts || w.config.chart.type === "radialBar") {
        w.globals.resized = true;
        let seriesEl = null;
        let realIndex = null;
        w.globals.risingSeries = [];
        if (w.globals.axisCharts) {
          seriesEl = w.dom.baseEl.querySelector(
            `.apexcharts-series[data\\:realIndex='${seriesCnt}']`
          );
          if (!seriesEl) return;
          realIndex = parseInt((_a = seriesEl.getAttribute("data:realIndex")) != null ? _a : "", 10);
        } else {
          seriesEl = w.dom.baseEl.querySelector(
            `.apexcharts-series[rel='${seriesCnt + 1}']`
          );
          if (!seriesEl) return;
          realIndex = parseInt((_b = seriesEl.getAttribute("rel")) != null ? _b : "", 10) - 1;
        }
        if (isHidden) {
          const seriesToMakeVisible = [
            {
              cs: w.globals.collapsedSeries,
              csi: w.globals.collapsedSeriesIndices
            },
            {
              cs: w.globals.ancillaryCollapsedSeries,
              csi: w.globals.ancillaryCollapsedSeriesIndices
            }
          ];
          seriesToMakeVisible.forEach((r) => {
            const cs = (
              /** @type {any} */
              r.cs
            );
            const csi = (
              /** @type {any} */
              r.csi
            );
            this.riseCollapsedSeries(
              cs,
              csi,
              /** @type {number} */
              realIndex
            );
          });
        } else {
          this.hideSeries({ seriesEl, realIndex });
        }
        if (w.config.chart.accessibility.enabled) {
          const legendItem = w.dom.baseEl.querySelector(
            `.apexcharts-legend-series[rel="${seriesCnt + 1}"]`
          );
          if (legendItem) {
            const isCollapsed = w.globals.collapsedSeriesIndices.includes(realIndex) || w.globals.ancillaryCollapsedSeriesIndices.includes(realIndex);
            legendItem.setAttribute(
              "aria-pressed",
              isCollapsed ? "true" : "false"
            );
            const legendTextEl = legendItem.querySelector(
              ".apexcharts-legend-text"
            );
            const seriesName = legendTextEl ? legendTextEl.textContent : w.seriesData.seriesNames[seriesCnt];
            const statusText = isCollapsed ? "hidden" : "visible";
            legendItem.setAttribute(
              "aria-label",
              `${seriesName}, ${statusText}. Press Enter or Space to toggle.`
            );
          }
        }
      } else {
        const seriesEl = w.dom.Paper.findOne(
          ` .apexcharts-series[rel='${seriesCnt + 1}'] path`
        );
        const type = w.config.chart.type;
        if (type === "pie" || type === "polarArea" || type === "donut") {
          const dataLabels = w.config.plotOptions.pie.donut.labels;
          const graphics = new Graphics(this.w);
          graphics.pathMouseDown(seriesEl, null);
          this.lgCtx.printDataLabelsInner(seriesEl.node, dataLabels);
        }
        if (w.config.chart.accessibility.enabled) {
          const legendItem = w.dom.baseEl.querySelector(
            `.apexcharts-legend-series[rel="${seriesCnt + 1}"]`
          );
          if (legendItem) {
            const isCollapsed = w.globals.collapsedSeriesIndices.includes(seriesCnt);
            legendItem.setAttribute(
              "aria-pressed",
              isCollapsed ? "true" : "false"
            );
            const legendTextEl = legendItem.querySelector(
              ".apexcharts-legend-text"
            );
            const seriesName = legendTextEl ? legendTextEl.textContent : w.seriesData.seriesNames[seriesCnt];
            const statusText = isCollapsed ? "hidden" : "visible";
            legendItem.setAttribute(
              "aria-label",
              `${seriesName}, ${statusText}. Press Enter or Space to toggle.`
            );
          }
        }
      }
    }
    /** @param {{realIndex: any}} opts */
    getSeriesAfterCollapsing({ realIndex }) {
      var _a;
      const w = this.w;
      const gl = w.globals;
      const series = Utils$1.clone(w.config.series);
      if (gl.axisCharts) {
        const yaxis = w.config.yaxis[gl.seriesYAxisReverseMap[realIndex]];
        const collapseData = {
          index: realIndex,
          data: series[realIndex].data.slice(),
          type: series[realIndex].type || w.config.chart.type
        };
        if (yaxis && yaxis.show && yaxis.showAlways) {
          if (gl.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) {
            gl.ancillaryCollapsedSeries.push(collapseData);
            gl.ancillaryCollapsedSeriesIndices.push(realIndex);
          }
        } else {
          if (gl.collapsedSeriesIndices.indexOf(realIndex) < 0) {
            gl.collapsedSeries.push(collapseData);
            gl.collapsedSeriesIndices.push(realIndex);
            const removeIndexOfRising = gl.risingSeries.indexOf(realIndex);
            gl.risingSeries.splice(removeIndexOfRising, 1);
          }
        }
      } else {
        gl.collapsedSeries.push({
          index: realIndex,
          data: series[realIndex],
          type: (
            /** @type {any} */
            (_a = w.config.series[realIndex].type) != null ? _a : "line"
          )
        });
        gl.collapsedSeriesIndices.push(realIndex);
      }
      gl.allSeriesCollapsed = gl.collapsedSeries.length + gl.ancillaryCollapsedSeries.length === w.config.series.length;
      return this._getSeriesBasedOnCollapsedState(series);
    }
    /** @param {{seriesEl: any, realIndex: any}} opts */
    hideSeries({ seriesEl, realIndex }) {
      const w = this.w;
      const series = this.getSeriesAfterCollapsing({
        realIndex
      });
      const seriesChildren = seriesEl.childNodes;
      for (let sc = 0; sc < seriesChildren.length; sc++) {
        if (seriesChildren[sc].classList.contains("apexcharts-series-markers-wrap")) {
          if (seriesChildren[sc].classList.contains("apexcharts-hide")) {
            seriesChildren[sc].classList.remove("apexcharts-hide");
          } else {
            seriesChildren[sc].classList.add("apexcharts-hide");
          }
        }
      }
      this.lgCtx.updateSeries(
        series,
        w.config.chart.animations.dynamicAnimation.enabled
      );
    }
    /**
     * @param {any[]} collapsedSeries
     * @param {number[]} seriesIndices
     * @param {number} realIndex
     */
    riseCollapsedSeries(collapsedSeries, seriesIndices, realIndex) {
      const w = this.w;
      let series = Utils$1.clone(w.config.series);
      if (collapsedSeries.length > 0) {
        for (let c = 0; c < collapsedSeries.length; c++) {
          if (collapsedSeries[c].index === realIndex) {
            if (w.globals.axisCharts) {
              series[realIndex].data = collapsedSeries[c].data.slice();
            } else {
              series[realIndex] = collapsedSeries[c].data;
            }
            if (typeof series[realIndex] !== "number") {
              series[realIndex].hidden = false;
            }
            collapsedSeries.splice(c, 1);
            seriesIndices.splice(c, 1);
            w.globals.risingSeries.push(realIndex);
            c--;
          }
        }
        series = this._getSeriesBasedOnCollapsedState(series);
        this.lgCtx.updateSeries(
          series,
          w.config.chart.animations.dynamicAnimation.enabled
        );
      }
    }
    /**
     * @param {any[]} series
     */
    _getSeriesBasedOnCollapsedState(series) {
      const w = this.w;
      let collapsed = 0;
      if (w.globals.axisCharts) {
        series.forEach((s, sI) => {
          if (!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(sI) < 0)) {
            series[sI].data = [];
            collapsed++;
          }
        });
      } else {
        series.forEach((s, sI) => {
          if (!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0)) {
            series[sI] = 0;
            collapsed++;
          }
        });
      }
      w.globals.allSeriesCollapsed = collapsed === series.length;
      return series;
    }
  };
  class Legend {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.printDataLabelsInner = (...a) => {
        var _a;
        return (_a = ctx.pie) == null ? void 0 : _a.printDataLabelsInner(...a);
      };
      this.updateSeries = (...a) => ctx.updateHelpers._updateSeries(...a);
      this.onLegendClick = this.onLegendClick.bind(this);
      this.onLegendHovered = this.onLegendHovered.bind(this);
      this.isBarsDistributed = this.w.config.chart.type === "bar" && this.w.config.plotOptions.bar.distributed && this.w.config.series.length === 1;
      this.legendHelpers = new Helpers$3(this);
    }
    init() {
      const w = this.w;
      const gl = w.globals;
      const cnf = w.config;
      const showLegendAlways = cnf.legend.showForSingleSeries && this.w.seriesData.series.length === 1 || this.isBarsDistributed || this.w.seriesData.series.length > 1;
      this.legendHelpers.appendToForeignObject();
      if ((showLegendAlways || !gl.axisCharts) && cnf.legend.show) {
        const elLegendWrap = (
          /** @type {HTMLElement} */
          w.dom.elLegendWrap
        );
        while (elLegendWrap.firstChild) {
          elLegendWrap.removeChild(elLegendWrap.firstChild);
        }
        this.drawLegends();
        if (cnf.legend.position === "bottom" || cnf.legend.position === "top") {
          this.legendAlignHorizontal();
        } else if (cnf.legend.position === "right" || cnf.legend.position === "left") {
          this.legendAlignVertical();
        }
      }
    }
    createLegendMarker({ i, fillcolor }) {
      const w = this.w;
      const elMarker = BrowserAPIs.createElement("span");
      elMarker.classList.add("apexcharts-legend-marker");
      const mShape = w.config.legend.markers.shape || w.config.markers.shape;
      let shape = mShape;
      if (Array.isArray(mShape)) {
        shape = mShape[i];
      }
      const mSize = Array.isArray(w.config.legend.markers.size) ? parseFloat(w.config.legend.markers.size[i]) : parseFloat(w.config.legend.markers.size);
      const mOffsetX = Array.isArray(w.config.legend.markers.offsetX) ? parseFloat(w.config.legend.markers.offsetX[i]) : parseFloat(w.config.legend.markers.offsetX);
      const mOffsetY = Array.isArray(w.config.legend.markers.offsetY) ? parseFloat(w.config.legend.markers.offsetY[i]) : parseFloat(w.config.legend.markers.offsetY);
      const mBorderWidth = Array.isArray(w.config.legend.markers.strokeWidth) ? parseFloat(w.config.legend.markers.strokeWidth[i]) : parseFloat(w.config.legend.markers.strokeWidth);
      const mStyle = elMarker.style;
      mStyle.height = (mSize + mBorderWidth) * 2 + "px";
      mStyle.width = (mSize + mBorderWidth) * 2 + "px";
      mStyle.left = mOffsetX + "px";
      mStyle.top = mOffsetY + "px";
      if (w.config.legend.markers.customHTML) {
        mStyle.background = "transparent";
        mStyle.color = fillcolor[i];
        if (Array.isArray(w.config.legend.markers.customHTML)) {
          if (w.config.legend.markers.customHTML[i]) {
            elMarker.innerHTML = w.config.legend.markers.customHTML[i]();
          }
        } else {
          elMarker.innerHTML = w.config.legend.markers.customHTML();
        }
      } else {
        const markers = new Markers(this.ctx.w, this.ctx);
        const markerConfig = markers.getMarkerConfig({
          cssClass: `apexcharts-legend-marker apexcharts-marker apexcharts-marker-${shape}`,
          seriesIndex: i,
          strokeWidth: mBorderWidth,
          size: mSize
        });
        const SVGLib = Environment.isBrowser() ? (
          /** @type {any} */
          window.SVG
        ) : (
          /** @type {any} */
          global.SVG
        );
        const SVGMarker = SVGLib().addTo(elMarker).size("100%", "100%");
        const marker = new Graphics(this.w).drawMarker(0, 0, __spreadProps(__spreadValues({}, markerConfig), {
          pointFillColor: Array.isArray(fillcolor) ? fillcolor[i] : markerConfig.pointFillColor,
          shape
        }));
        const shapesEls = w.dom.Paper.find(
          ".apexcharts-legend-marker.apexcharts-marker"
        );
        shapesEls.forEach((shapeEl) => {
          if (shapeEl.node.classList.contains("apexcharts-marker-triangle")) {
            shapeEl.node.style.transform = "translate(50%, 45%)";
          } else {
            shapeEl.node.style.transform = "translate(50%, 50%)";
          }
        });
        SVGMarker.add(marker);
      }
      return elMarker;
    }
    drawLegends() {
      var _a;
      const me = this;
      const w = this.w;
      const elLegendWrap = (
        /** @type {HTMLElement} */
        w.dom.elLegendWrap
      );
      const fontFamily = w.config.legend.fontFamily;
      let legendNames = w.seriesData.seriesNames;
      let fillcolor = w.config.legend.markers.fillColors ? w.config.legend.markers.fillColors.slice() : w.globals.colors.slice();
      if (w.config.chart.type === "heatmap") {
        const ranges = w.config.plotOptions.heatmap.colorScale.ranges;
        legendNames = ranges.map((colorScale) => {
          return colorScale.name ? colorScale.name : colorScale.from + " - " + colorScale.to;
        });
        fillcolor = ranges.map((color) => color.color);
      } else if (this.isBarsDistributed) {
        legendNames = w.labelData.labels.slice();
      }
      if (w.config.legend.customLegendItems.length) {
        legendNames = w.config.legend.customLegendItems;
      }
      const legendFormatter = w.formatters.legendFormatter;
      const isLegendInversed = w.config.legend.inverseOrder;
      const legendGroups = [];
      if (w.labelData.seriesGroups.length > 1 && w.config.legend.clusterGroupedSeries) {
        w.labelData.seriesGroups.forEach((_, gi) => {
          legendGroups[gi] = BrowserAPIs.createElement("div");
          legendGroups[gi].classList.add(
            "apexcharts-legend-group",
            `apexcharts-legend-group-${gi}`
          );
          if (w.config.legend.clusterGroupedSeriesOrientation === "horizontal") {
            elLegendWrap.classList.add("apexcharts-legend-group-horizontal");
          } else {
            legendGroups[gi].classList.add("apexcharts-legend-group-vertical");
          }
        });
      }
      for (let i = isLegendInversed ? legendNames.length - 1 : 0; isLegendInversed ? i >= 0 : i <= legendNames.length - 1; isLegendInversed ? i-- : i++) {
        const text = legendFormatter(legendNames[i], { seriesIndex: i, w });
        let collapsedSeries = false;
        let ancillaryCollapsedSeries = false;
        if (w.globals.collapsedSeries.length > 0) {
          for (let c = 0; c < w.globals.collapsedSeries.length; c++) {
            if (w.globals.collapsedSeries[c].index === i) {
              collapsedSeries = true;
            }
          }
        }
        if (w.globals.ancillaryCollapsedSeriesIndices.length > 0) {
          for (let c = 0; c < w.globals.ancillaryCollapsedSeriesIndices.length; c++) {
            if (w.globals.ancillaryCollapsedSeriesIndices[c] === i) {
              ancillaryCollapsedSeries = true;
            }
          }
        }
        const elMarker = this.createLegendMarker({ i, fillcolor });
        Graphics.setAttrs(elMarker, {
          rel: i + 1,
          "data:collapsed": collapsedSeries || ancillaryCollapsedSeries
        });
        if (collapsedSeries || ancillaryCollapsedSeries) {
          elMarker.classList.add("apexcharts-inactive-legend");
        }
        const elLegend = BrowserAPIs.createElement("div");
        if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
          elLegend.setAttribute("role", "button");
          elLegend.setAttribute("tabindex", "0");
          const seriesName = Array.isArray(text) ? text.join(" ") : text;
          const isCollapsed = collapsedSeries || ancillaryCollapsedSeries;
          const statusText = isCollapsed ? "hidden" : "visible";
          elLegend.setAttribute(
            "aria-label",
            `${seriesName}, ${statusText}. Press Enter or Space to toggle.`
          );
          elLegend.setAttribute("aria-pressed", isCollapsed ? "true" : "false");
        }
        const elLegendText = BrowserAPIs.createElement("span");
        elLegendText.classList.add("apexcharts-legend-text");
        elLegendText.innerHTML = Array.isArray(text) ? text.join(" ") : text;
        let textColor = w.config.legend.labels.useSeriesColors ? w.globals.colors[i] : Array.isArray(w.config.legend.labels.colors) ? (_a = w.config.legend.labels.colors) == null ? void 0 : _a[i] : w.config.legend.labels.colors;
        if (!textColor) {
          textColor = w.config.chart.foreColor;
        }
        elLegendText.style.color = textColor;
        elLegendText.style.fontSize = w.config.legend.fontSize;
        elLegendText.style.fontWeight = w.config.legend.fontWeight;
        elLegendText.style.fontFamily = fontFamily || w.config.chart.fontFamily;
        Graphics.setAttrs(elLegendText, {
          rel: i + 1,
          i,
          "data:default-text": encodeURIComponent(text),
          "data:collapsed": collapsedSeries || ancillaryCollapsedSeries
        });
        elLegend.appendChild(elMarker);
        elLegend.appendChild(elLegendText);
        const coreUtils = new CoreUtils(this.w);
        if (!w.config.legend.showForZeroSeries) {
          const total = coreUtils.getSeriesTotalByIndex(i);
          if (total === 0 && coreUtils.seriesHaveSameValues(i) && !coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) {
            elLegend.classList.add("apexcharts-hidden-zero-series");
          }
        }
        if (!w.config.legend.showForNullSeries) {
          if (coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) {
            elLegend.classList.add("apexcharts-hidden-null-series");
          }
        }
        if (legendGroups.length) {
          w.labelData.seriesGroups.forEach((group, gi) => {
            var _a2, _b;
            if (group.includes(
              /** @type {Record<string,any>} */
              (_b = (_a2 = w.config.series[i]) == null ? void 0 : _a2.name) != null ? _b : ""
            )) {
              elLegendWrap.appendChild(legendGroups[gi]);
              legendGroups[gi].appendChild(elLegend);
            }
          });
        } else {
          elLegendWrap.appendChild(elLegend);
        }
        elLegendWrap.classList.add(
          `apexcharts-align-${w.config.legend.horizontalAlign}`
        );
        elLegendWrap.classList.add(
          "apx-legend-position-" + w.config.legend.position
        );
        elLegend.classList.add("apexcharts-legend-series");
        elLegend.style.margin = `${w.config.legend.itemMargin.vertical}px ${w.config.legend.itemMargin.horizontal}px`;
        elLegendWrap.style.width = w.config.legend.width ? w.config.legend.width + "px" : "";
        elLegendWrap.style.height = w.config.legend.height ? w.config.legend.height + "px" : "";
        Graphics.setAttrs(elLegend, {
          rel: i + 1,
          seriesName: Utils$1.escapeString(legendNames[i]),
          "data:collapsed": collapsedSeries || ancillaryCollapsedSeries
        });
        if (collapsedSeries || ancillaryCollapsedSeries) {
          elLegend.classList.add("apexcharts-inactive-legend");
        }
        if (!w.config.legend.onItemClick.toggleDataSeries) {
          elLegend.classList.add("apexcharts-no-click");
        }
      }
      w.dom.elWrap.addEventListener("click", me.onLegendClick, true);
      if (w.config.legend.onItemHover.highlightDataSeries && w.config.legend.customLegendItems.length === 0) {
        w.dom.elWrap.addEventListener("mousemove", me.onLegendHovered, true);
        w.dom.elWrap.addEventListener("mouseout", me.onLegendHovered, true);
      }
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) {
        w.dom.elWrap.addEventListener(
          "keydown",
          me.onLegendKeyDown.bind(me),
          true
        );
      }
    }
    /**
     * @param {number} offsetX
     * @param {number} offsetY
     */
    setLegendWrapXY(offsetX, offsetY) {
      const w = this.w;
      const elLegendWrap = (
        /** @type {HTMLElement} */
        w.dom.elLegendWrap
      );
      const legendHeight = elLegendWrap.clientHeight;
      let x = 0;
      let y = 0;
      if (w.config.legend.position === "bottom") {
        y = w.globals.svgHeight - Math.min(legendHeight, w.globals.svgHeight / 2) - 5;
      } else if (w.config.legend.position === "top") {
        const dim = new Dimensions(this.w, this.ctx);
        const titleH = dim.dimHelpers.getTitleSubtitleCoords("title").height;
        const subtitleH = dim.dimHelpers.getTitleSubtitleCoords("subtitle").height;
        y = (titleH > 0 ? titleH - 10 : 0) + (subtitleH > 0 ? subtitleH - 10 : 0);
      }
      elLegendWrap.style.position = "absolute";
      x = x + offsetX + w.config.legend.offsetX;
      y = y + offsetY + w.config.legend.offsetY;
      elLegendWrap.style.left = x + "px";
      elLegendWrap.style.top = y + "px";
      if (w.config.legend.position === "right") {
        elLegendWrap.style.left = "auto";
        elLegendWrap.style.right = 25 + w.config.legend.offsetX + "px";
      }
      const fixedHeigthWidth = (
        /** @type {const} */
        ["width", "height"]
      );
      fixedHeigthWidth.forEach((hw) => {
        if (elLegendWrap && elLegendWrap.style[hw]) {
          elLegendWrap.style[hw] = parseInt(String(w.config.legend[hw]), 10) + "px";
        }
      });
    }
    legendAlignHorizontal() {
      const w = this.w;
      const elLegendWrap = (
        /** @type {HTMLElement} */
        w.dom.elLegendWrap
      );
      elLegendWrap.style.right = "0";
      const dimensions = new Dimensions(this.w, this.ctx);
      const titleRect = dimensions.dimHelpers.getTitleSubtitleCoords("title");
      const subtitleRect = dimensions.dimHelpers.getTitleSubtitleCoords("subtitle");
      const offsetX = 20;
      let offsetY = 0;
      if (w.config.legend.position === "top") {
        offsetY = titleRect.height + subtitleRect.height + w.config.title.margin + w.config.subtitle.margin - 10;
      }
      this.setLegendWrapXY(offsetX, offsetY);
    }
    legendAlignVertical() {
      const w = this.w;
      const lRect = this.legendHelpers.getLegendDimensions();
      const offsetY = 20;
      let offsetX = 0;
      if (w.config.legend.position === "left") {
        offsetX = 20;
      }
      if (w.config.legend.position === "right") {
        offsetX = w.globals.svgWidth - lRect.clww - 10;
      }
      this.setLegendWrapXY(offsetX, offsetY);
    }
    /**
     * @param {MouseEvent} e
     */
    onLegendHovered(e) {
      var _a;
      const w = this.w;
      const target = (
        /** @type {Element} */
        e.target
      );
      const hoverOverLegend = target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker");
      if (w.config.chart.type !== "heatmap" && !this.isBarsDistributed) {
        if (!target.classList.contains("apexcharts-inactive-legend") && hoverOverLegend) {
          const series = new Series(this.ctx.w);
          series.toggleSeriesOnHover(e, target);
        }
      } else {
        if (hoverOverLegend) {
          const seriesCnt = parseInt((_a = target.getAttribute("rel")) != null ? _a : "0", 10) - 1;
          this.ctx.events.fireEvent("legendHover", [this.ctx, seriesCnt, this.w]);
          const series = new Series(this.ctx.w);
          series.highlightRangeInSeries(e, target);
        }
      }
    }
    /**
     * @param {KeyboardEvent} e
     */
    onLegendKeyDown(e) {
      const me = this;
      const w = this.w;
      const target = (
        /** @type {Element} */
        e.target
      );
      const isLegendItem = target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker");
      if (!isLegendItem) return;
      if (e.key === "Enter" || e.key === " ") {
        e.preventDefault();
        const rel = target.getAttribute("rel");
        me.onLegendClick(e);
        if (rel !== null && w.config.legend.onItemClick.toggleDataSeries) {
          requestAnimationFrame(() => {
            const restored = w.dom.baseEl.querySelector(
              `.apexcharts-legend-series[rel="${rel}"]`
            );
            if (restored) restored.focus();
          });
        }
      }
    }
    /**
     * @param {Event} e
     */
    onLegendClick(e) {
      var _a;
      const w = this.w;
      const target = (
        /** @type {Element} */
        e.target
      );
      if (w.config.legend.customLegendItems.length) return;
      if (target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker")) {
        const seriesCnt = parseInt((_a = target.getAttribute("rel")) != null ? _a : "0", 10) - 1;
        const isHidden = target.getAttribute("data:collapsed") === "true";
        const legendClick = this.w.config.chart.events.legendClick;
        if (typeof legendClick === "function") {
          legendClick(this.ctx, seriesCnt, this.w);
        }
        this.ctx.events.fireEvent("legendClick", [this.ctx, seriesCnt, this.w]);
        const markerClick = this.w.config.legend.markers.onClick;
        if (typeof markerClick === "function" && target.classList.contains("apexcharts-legend-marker")) {
          markerClick(this.ctx, seriesCnt, this.w);
          this.ctx.events.fireEvent("legendMarkerClick", [
            this.ctx,
            seriesCnt,
            this.w
          ]);
        }
        const clickAllowed = w.config.chart.type !== "treemap" && w.config.chart.type !== "heatmap" && !this.isBarsDistributed;
        if (clickAllowed && w.config.legend.onItemClick.toggleDataSeries) {
          this.legendHelpers.toggleDataSeries(seriesCnt, isHidden);
        }
      }
    }
  }
  ApexCharts.registerFeatures({ legend: Legend });
  const icoPan = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n    <defs>\n        <path d="M0 0h24v24H0z" id="a"/>\n    </defs>\n    <clipPath id="b">\n        <use overflow="visible" xlink:href="#a"/>\n    </clipPath>\n    <path clip-path="url(#b)" d="M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/>\n</svg>';
  const icoZoom = '<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n    <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>\n    <path d="M0 0h24v24H0V0z" fill="none"/>\n    <path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/>\n</svg>';
  const icoReset = '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n    <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>\n    <path d="M0 0h24v24H0z" fill="none"/>\n</svg>';
  const icoZoomIn = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n';
  const icoZoomOut = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n';
  const icoSelect = '<svg fill="#6E8192" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n    <path d="M0 0h24v24H0z" fill="none"/>\n    <path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2z"/>\n</svg>';
  const icoMenu = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>';
  class Toolbar {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.ev = this.w.config.chart.events;
      this.selectedClass = "apexcharts-selected";
      this.localeValues = this.w.globals.locale.toolbar;
      this.minX = w.globals.minX;
      this.maxX = w.globals.maxX;
      this.elZoom = null;
      this.elZoomIn = null;
      this.elZoomOut = null;
      this.elPan = null;
      this.elSelection = null;
      this.elZoomReset = null;
      this.elMenuIcon = null;
      this.elMenu = null;
      this.elMenuItems = [];
      this.t = null;
    }
    createToolbar() {
      const w = this.w;
      const createDiv = () => {
        return BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div");
      };
      const elToolbarWrap = createDiv();
      elToolbarWrap.setAttribute("class", "apexcharts-toolbar");
      elToolbarWrap.style.top = w.config.chart.toolbar.offsetY + "px";
      elToolbarWrap.style.right = -w.config.chart.toolbar.offsetX + 3 + "px";
      w.dom.elWrap.appendChild(elToolbarWrap);
      this.elZoom = createDiv();
      this.elZoomIn = createDiv();
      this.elZoomOut = createDiv();
      this.elPan = createDiv();
      this.elSelection = createDiv();
      this.elZoomReset = createDiv();
      this.elMenuIcon = createDiv();
      this.elMenu = createDiv();
      this.elCustomIcons = [];
      this.t = w.config.chart.toolbar.tools;
      if (Array.isArray(this.t.customIcons)) {
        for (let i = 0; i < this.t.customIcons.length; i++) {
          this.elCustomIcons.push(createDiv());
        }
      }
      const toolbarControls = [];
      const appendZoomControl = (type, el, ico) => {
        const tool = type.toLowerCase();
        if (this.t[tool] && w.config.chart.zoom.enabled) {
          toolbarControls.push({
            el,
            icon: typeof this.t[tool] === "string" ? this.t[tool] : ico,
            title: (
              /** @type {any} */
              this.localeValues[type]
            ),
            class: `apexcharts-${tool}-icon`
          });
        }
      };
      appendZoomControl("zoomIn", this.elZoomIn, icoZoomIn);
      appendZoomControl("zoomOut", this.elZoomOut, icoZoomOut);
      const zoomSelectionCtrls = (z) => {
        if (this.t[z] && w.config.chart[z].enabled) {
          toolbarControls.push({
            el: z === "zoom" ? this.elZoom : this.elSelection,
            icon: typeof this.t[z] === "string" ? this.t[z] : z === "zoom" ? icoZoom : icoSelect,
            title: (
              /** @type {any} */
              this.localeValues[z === "zoom" ? "selectionZoom" : "selection"]
            ),
            class: `apexcharts-${z}-icon`
          });
        }
      };
      zoomSelectionCtrls("zoom");
      zoomSelectionCtrls("selection");
      if (this.t.pan && w.config.chart.zoom.enabled) {
        toolbarControls.push({
          el: this.elPan,
          icon: typeof this.t.pan === "string" ? this.t.pan : icoPan,
          title: this.localeValues.pan,
          class: "apexcharts-pan-icon"
        });
      }
      appendZoomControl("reset", this.elZoomReset, icoReset);
      if (this.t.download) {
        toolbarControls.push({
          el: this.elMenuIcon,
          icon: typeof this.t.download === "string" ? this.t.download : icoMenu,
          title: this.localeValues.menu,
          class: "apexcharts-menu-icon"
        });
      }
      for (let i = 0; i < this.elCustomIcons.length; i++) {
        toolbarControls.push({
          el: this.elCustomIcons[i],
          icon: this.t.customIcons[i].icon,
          title: this.t.customIcons[i].title,
          index: this.t.customIcons[i].index,
          class: "apexcharts-toolbar-custom-icon " + this.t.customIcons[i].class
        });
      }
      toolbarControls.forEach((t, index) => {
        if (t.index) {
          Utils$1.moveIndexInArray(toolbarControls, index, t.index);
        }
      });
      for (let i = 0; i < toolbarControls.length; i++) {
        Graphics.setAttrs(toolbarControls[i].el, {
          class: toolbarControls[i].class,
          title: toolbarControls[i].title,
          tabindex: "0",
          role: "button",
          "aria-label": toolbarControls[i].title
        });
        toolbarControls[i].el.innerHTML = toolbarControls[i].icon;
        elToolbarWrap.appendChild(toolbarControls[i].el);
      }
      if (this.elZoom.parentNode) {
        this.elZoom.setAttribute("aria-pressed", String(!!w.interact.zoomEnabled));
      }
      if (this.elSelection.parentNode) {
        this.elSelection.setAttribute(
          "aria-pressed",
          String(!!w.interact.selectionEnabled)
        );
      }
      if (this.elPan.parentNode) {
        this.elPan.setAttribute("aria-pressed", String(!!w.interact.panEnabled));
      }
      if (this.elMenuIcon.parentNode) {
        this.elMenuIcon.setAttribute("aria-haspopup", "true");
        this.elMenuIcon.setAttribute("aria-expanded", "false");
      }
      this._createHamburgerMenu(elToolbarWrap);
      if (w.interact.zoomEnabled) {
        this.elZoom.classList.add(this.selectedClass);
      } else if (w.interact.panEnabled) {
        this.elPan.classList.add(this.selectedClass);
      } else if (w.interact.selectionEnabled) {
        this.elSelection.classList.add(this.selectedClass);
      }
      this.addToolbarEventListeners();
    }
    /**
     * @param {Element} parent
     */
    _createHamburgerMenu(parent) {
      this.elMenuItems = [];
      parent.appendChild(
        /** @type {Node} */
        this.elMenu
      );
      Graphics.setAttrs(this.elMenu, {
        class: "apexcharts-menu",
        role: "menu"
      });
      const menuItems = [
        {
          name: "exportSVG",
          title: this.localeValues.exportToSVG
        },
        {
          name: "exportPNG",
          title: this.localeValues.exportToPNG
        },
        {
          name: "exportCSV",
          title: this.localeValues.exportToCSV
        }
      ];
      for (let i = 0; i < menuItems.length; i++) {
        this.elMenuItems.push(
          BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div")
        );
        this.elMenuItems[i].innerHTML = menuItems[i].title;
        Graphics.setAttrs(this.elMenuItems[i], {
          class: `apexcharts-menu-item ${menuItems[i].name}`,
          title: menuItems[i].title,
          role: "menuitem",
          tabindex: "-1"
        });
        this.elMenu.appendChild(this.elMenuItems[i]);
      }
    }
    addToolbarEventListeners() {
      var _a, _b, _c, _d, _e, _f, _g, _h;
      (_a = this.elZoomReset) == null ? void 0 : _a.addEventListener("click", this.handleZoomReset.bind(this));
      (_b = this.elSelection) == null ? void 0 : _b.addEventListener(
        "click",
        this.toggleZoomSelection.bind(this, "selection")
      );
      (_c = this.elZoom) == null ? void 0 : _c.addEventListener(
        "click",
        this.toggleZoomSelection.bind(this, "zoom")
      );
      (_d = this.elZoomIn) == null ? void 0 : _d.addEventListener("click", this.handleZoomIn.bind(this));
      (_e = this.elZoomOut) == null ? void 0 : _e.addEventListener("click", this.handleZoomOut.bind(this));
      (_f = this.elPan) == null ? void 0 : _f.addEventListener("click", this.togglePanning.bind(this));
      (_g = this.elMenuIcon) == null ? void 0 : _g.addEventListener("click", this.toggleMenu.bind(this));
      this.elMenuItems.forEach((m) => {
        if (m.classList.contains("exportSVG")) {
          m.addEventListener("click", this.handleDownload.bind(this, "svg"));
        } else if (m.classList.contains("exportPNG")) {
          m.addEventListener("click", this.handleDownload.bind(this, "png"));
        } else if (m.classList.contains("exportCSV")) {
          m.addEventListener("click", this.handleDownload.bind(this, "csv"));
        }
      });
      for (let i = 0; i < this.t.customIcons.length; i++) {
        this.elCustomIcons[i].addEventListener(
          "click",
          this.t.customIcons[i].click.bind(this, this.ctx, this.ctx.w)
        );
      }
      const toolbarButtons = [
        this.elZoomReset,
        this.elSelection,
        this.elZoom,
        this.elZoomIn,
        this.elZoomOut,
        this.elPan,
        this.elMenuIcon,
        ...this.elCustomIcons
      ];
      toolbarButtons.forEach((btn) => {
        btn.addEventListener("keydown", (e) => {
          if (e.key === "Enter" || e.key === " ") {
            e.preventDefault();
            const btnClass = btn.className;
            btn.click();
            requestAnimationFrame(() => {
              const baseEl = this.w.dom.baseEl;
              if (!baseEl) return;
              const apexClass = btnClass.split(" ").find((c) => c.startsWith("apexcharts-"));
              if (!apexClass) return;
              const restored = baseEl.querySelector(`.${apexClass}`);
              if (restored) restored.focus();
            });
          }
        });
      });
      (_h = this.elMenuIcon) == null ? void 0 : _h.addEventListener(
        "keydown",
        (e) => {
          var _a2;
          if (e.key === "ArrowDown" || e.key === "ArrowUp") {
            e.preventDefault();
            if (!((_a2 = this.elMenu) == null ? void 0 : _a2.classList.contains("apexcharts-menu-open"))) {
              this.toggleMenu();
            }
            window.setTimeout(() => {
              const idx = e.key === "ArrowDown" ? 0 : this.elMenuItems.length - 1;
              if (this.elMenuItems[idx])
                this.elMenuItems[idx].focus();
            }, 20);
          }
        }
      );
      this.elMenuItems.forEach((m, idx) => {
        m.addEventListener("keydown", (e) => {
          var _a2;
          if (e.key === "ArrowDown") {
            e.preventDefault();
            const next = this.elMenuItems[idx + 1] || this.elMenuItems[0];
            next.focus();
          } else if (e.key === "ArrowUp") {
            e.preventDefault();
            const prev = this.elMenuItems[idx - 1] || this.elMenuItems[this.elMenuItems.length - 1];
            prev.focus();
          } else if (e.key === "Escape" || e.key === "Tab") {
            this._closeMenu();
            (_a2 = this.elMenuIcon) == null ? void 0 : _a2.focus();
            if (e.key === "Tab") ;
            else {
              e.preventDefault();
            }
          } else if (e.key === "Enter" || e.key === " ") {
            e.preventDefault();
            m.click();
          }
        });
      });
    }
    /**
     * @param {string} type
     */
    toggleZoomSelection(type) {
      const charts = this.ctx.getSyncedCharts();
      charts.forEach((ch) => {
        ch.ctx.toolbar.toggleOtherControls();
        const el = type === "selection" ? ch.ctx.toolbar.elSelection : ch.ctx.toolbar.elZoom;
        const enabledType = type === "selection" ? "selectionEnabled" : "zoomEnabled";
        ch.w.globals[enabledType] = !ch.w.globals[enabledType];
        if (!el.classList.contains(ch.ctx.toolbar.selectedClass)) {
          el.classList.add(ch.ctx.toolbar.selectedClass);
        } else {
          el.classList.remove(ch.ctx.toolbar.selectedClass);
        }
        el.setAttribute("aria-pressed", String(ch.w.globals[enabledType]));
      });
    }
    getToolbarIconsReference() {
      const w = this.w;
      if (!this.elZoom) {
        this.elZoom = w.dom.baseEl.querySelector(".apexcharts-zoom-icon");
      }
      if (!this.elPan) {
        this.elPan = w.dom.baseEl.querySelector(".apexcharts-pan-icon");
      }
      if (!this.elSelection) {
        this.elSelection = w.dom.baseEl.querySelector(
          ".apexcharts-selection-icon"
        );
      }
    }
    /**
     * @param {string} type
     */
    enableZoomPanFromToolbar(type) {
      this.toggleOtherControls();
      type === "pan" ? this.w.interact.panEnabled = true : this.w.interact.zoomEnabled = true;
      const el = type === "pan" ? this.elPan : this.elZoom;
      const el2 = type === "pan" ? this.elZoom : this.elPan;
      if (el) {
        el.classList.add(this.selectedClass);
      }
      if (el2) {
        el2.classList.remove(this.selectedClass);
      }
    }
    togglePanning() {
      const charts = this.ctx.getSyncedCharts();
      charts.forEach((ch) => {
        ch.ctx.toolbar.toggleOtherControls();
        ch.w.interact.panEnabled = !ch.w.interact.panEnabled;
        if (!ch.ctx.toolbar.elPan.classList.contains(ch.ctx.toolbar.selectedClass)) {
          ch.ctx.toolbar.elPan.classList.add(ch.ctx.toolbar.selectedClass);
        } else {
          ch.ctx.toolbar.elPan.classList.remove(ch.ctx.toolbar.selectedClass);
        }
        ch.ctx.toolbar.elPan.setAttribute(
          "aria-pressed",
          String(ch.w.interact.panEnabled)
        );
      });
    }
    toggleOtherControls() {
      const w = this.w;
      w.interact.panEnabled = false;
      w.interact.zoomEnabled = false;
      w.interact.selectionEnabled = false;
      this.getToolbarIconsReference();
      const toggleEls = [this.elPan, this.elSelection, this.elZoom];
      toggleEls.forEach((el) => {
        if (el) {
          el.classList.remove(this.selectedClass);
        }
      });
    }
    handleZoomIn() {
      const w = this.w;
      if (w.axisFlags.isRangeBar) {
        this.minX = w.globals.minY;
        this.maxX = w.globals.maxY;
      }
      const centerX = (this.minX + this.maxX) / 2;
      const newMinX = (this.minX + centerX) / 2;
      const newMaxX = (this.maxX + centerX) / 2;
      const newMinXMaxX = this._getNewMinXMaxX(newMinX, newMaxX);
      if (!w.interact.disableZoomIn) {
        this.zoomUpdateOptions(newMinXMaxX.minX, newMinXMaxX.maxX);
      }
    }
    handleZoomOut() {
      const w = this.w;
      if (w.axisFlags.isRangeBar) {
        this.minX = w.globals.minY;
        this.maxX = w.globals.maxY;
      }
      if (w.config.xaxis.type === "datetime" && new Date(this.minX).getUTCFullYear() < 1e3) {
        return;
      }
      const centerX = (this.minX + this.maxX) / 2;
      const newMinX = this.minX - (centerX - this.minX);
      const newMaxX = this.maxX - (centerX - this.maxX);
      const newMinXMaxX = this._getNewMinXMaxX(newMinX, newMaxX);
      if (!w.interact.disableZoomOut) {
        this.zoomUpdateOptions(newMinXMaxX.minX, newMinXMaxX.maxX);
      }
    }
    /**
     * @param {number} newMinX
     * @param {number} newMaxX
     */
    _getNewMinXMaxX(newMinX, newMaxX) {
      const shouldFloor = this.w.config.xaxis.convertedCatToNumeric;
      return {
        minX: shouldFloor ? Math.floor(newMinX) : newMinX,
        maxX: shouldFloor ? Math.floor(newMaxX) : newMaxX
      };
    }
    /**
     * @param {number} newMinX
     * @param {number} newMaxX
     */
    zoomUpdateOptions(newMinX, newMaxX) {
      const w = this.w;
      if (newMinX === void 0 && newMaxX === void 0) {
        this.handleZoomReset();
        return;
      }
      if (w.config.xaxis.convertedCatToNumeric) {
        if (newMinX < 1) {
          newMinX = 1;
          newMaxX = w.globals.dataPoints;
        }
        if (newMaxX - newMinX < 2) {
          return;
        }
      }
      let xaxis = {
        min: newMinX,
        max: newMaxX
      };
      const beforeZoomRange = this.getBeforeZoomRange(
        xaxis,
        /** @type {any} */
        void 0
      );
      if (beforeZoomRange) {
        xaxis = beforeZoomRange.xaxis;
      }
      const options2 = {
        xaxis
      };
      if (!w.globals.initialConfig) return;
      const yaxis = Utils$1.clone(w.globals.initialConfig.yaxis);
      if (!w.config.chart.group) {
        options2.yaxis = yaxis;
      }
      this.w.interact.zoomed = true;
      this.ctx.updateHelpers._updateOptions(
        options2,
        false,
        this.w.config.chart.animations.dynamicAnimation.enabled
      );
      this.zoomCallback(xaxis, yaxis);
    }
    /**
     * @param {Record<string, any>} xaxis
     * @param {Record<string, any>} yaxis
     */
    zoomCallback(xaxis, yaxis) {
      if (typeof this.ev.zoomed === "function") {
        this.ev.zoomed(this.ctx, { xaxis, yaxis });
        this.ctx.events.fireEvent("zoomed", { xaxis, yaxis });
      }
    }
    /**
     * @param {Record<string, any>} xaxis
     * @param {Record<string, any>} yaxis
     */
    getBeforeZoomRange(xaxis, yaxis) {
      let newRange = null;
      if (typeof this.ev.beforeZoom === "function") {
        newRange = this.ev.beforeZoom(this, { xaxis, yaxis });
      }
      return newRange;
    }
    toggleMenu() {
      window.setTimeout(() => {
        var _a, _b, _c;
        if ((_a = this.elMenu) == null ? void 0 : _a.classList.contains("apexcharts-menu-open")) {
          this._closeMenu();
        } else {
          (_b = this.elMenu) == null ? void 0 : _b.classList.add("apexcharts-menu-open");
          (_c = this.elMenuIcon) == null ? void 0 : _c.setAttribute("aria-expanded", "true");
        }
      }, 0);
    }
    _closeMenu() {
      var _a, _b;
      (_a = this.elMenu) == null ? void 0 : _a.classList.remove("apexcharts-menu-open");
      (_b = this.elMenuIcon) == null ? void 0 : _b.setAttribute("aria-expanded", "false");
    }
    /**
     * @param {string} type
     */
    handleDownload(type) {
      const w = this.w;
      const exprt = new Exports(this.w, this.ctx);
      switch (type) {
        case "svg":
          exprt.exportToSVG();
          break;
        case "png":
          exprt.exportToPng();
          break;
        case "csv":
          exprt.exportToCSV({
            series: w.config.series,
            columnDelimiter: w.config.chart.toolbar.export.csv.columnDelimiter
          });
          break;
      }
    }
    handleZoomReset() {
      const charts = this.ctx.getSyncedCharts();
      charts.forEach((ch) => {
        const w = ch.w;
        if (!w.interact.zoomed) return;
        w.globals.lastXAxis.min = w.globals.initialConfig.xaxis.min;
        w.globals.lastXAxis.max = w.globals.initialConfig.xaxis.max;
        ch.updateHelpers.revertDefaultAxisMinMax();
        if (typeof w.config.chart.events.beforeResetZoom === "function") {
          const resetZoomRange = w.config.chart.events.beforeResetZoom(ch, w);
          if (resetZoomRange) {
            ch.updateHelpers.revertDefaultAxisMinMax(resetZoomRange);
          }
        }
        if (typeof w.config.chart.events.zoomed === "function") {
          ch.ctx.toolbar.zoomCallback({
            min: w.config.xaxis.min,
            max: w.config.xaxis.max
          });
        }
        const series = ch.ctx.series.emptyCollapsedSeries(
          Utils$1.clone(w.globals.initialSeries)
        );
        ch.updateHelpers._updateSeries(
          series,
          w.config.chart.animations.dynamicAnimation.enabled
        );
        w.interact.zoomed = false;
      });
    }
    destroy() {
      this.elZoom = null;
      this.elZoomIn = null;
      this.elZoomOut = null;
      this.elPan = null;
      this.elSelection = null;
      this.elZoomReset = null;
      this.elMenuIcon = null;
    }
  }
  class ZoomPanSelection extends Toolbar {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      super(w, ctx);
      this.w = w;
      this.ctx = ctx;
      this.dragged = false;
      this.graphics = new Graphics(this.w);
      this.eventList = [
        "mousedown",
        "mouseleave",
        "mousemove",
        "touchstart",
        "touchmove",
        "mouseup",
        "touchend",
        "wheel"
      ];
      this.clientX = 0;
      this.clientY = 0;
      this.startX = 0;
      this.endX = 0;
      this.dragX = 0;
      this.startY = 0;
      this.endY = 0;
      this.dragY = 0;
      this.moveDirection = "none";
      this.debounceTimer = null;
      this.debounceDelay = 100;
      this.wheelDelay = 400;
    }
    /** @param {{xyRatios: any}} opts */
    init({ xyRatios }) {
      const w = this.w;
      const me = this;
      this.xyRatios = xyRatios;
      this.zoomRect = this.graphics.drawRect(0, 0, 0, 0);
      this.selectionRect = this.graphics.drawRect(0, 0, 0, 0);
      this.gridRect = w.dom.baseEl.querySelector(".apexcharts-grid");
      this.constraints = new Box(0, 0, w.layout.gridWidth, w.layout.gridHeight);
      this.zoomRect.node.classList.add("apexcharts-zoom-rect");
      this.selectionRect.node.classList.add("apexcharts-selection-rect");
      w.dom.Paper.add(this.zoomRect);
      w.dom.Paper.add(this.selectionRect);
      if (w.config.chart.selection.type === "x") {
        this.slDraggableRect = this.selectionRect.draggable({
          minX: 0,
          minY: 0,
          maxX: w.layout.gridWidth,
          maxY: w.layout.gridHeight
        }).on("dragmove.namespace", this.selectionDragging.bind(this, "dragging"));
      } else if (w.config.chart.selection.type === "y") {
        this.slDraggableRect = this.selectionRect.draggable({
          minX: 0,
          maxX: w.layout.gridWidth
        }).on("dragmove.namespace", this.selectionDragging.bind(this, "dragging"));
      } else {
        this.slDraggableRect = this.selectionRect.draggable().on("dragmove.namespace", this.selectionDragging.bind(this, "dragging"));
      }
      this.preselectedSelection();
      this.hoverArea = /** @type {Element} */
      w.dom.baseEl.querySelector(`${w.globals.chartClass} .apexcharts-svg`);
      if (!this.hoverArea) return;
      this.hoverArea.classList.add("apexcharts-zoomable");
      this.eventList.forEach((event) => {
        var _a;
        (_a = this.hoverArea) == null ? void 0 : _a.addEventListener(
          event,
          me.svgMouseEvents.bind(me, xyRatios),
          {
            capture: false,
            passive: true
          }
        );
      });
      if (w.config.chart.zoom.enabled && w.config.chart.zoom.allowMouseWheelZoom) {
        this.hoverArea.addEventListener("wheel", me.mouseWheelEvent.bind(me), {
          capture: false,
          passive: false
        });
      }
    }
    // remove the event listeners which were previously added on hover area
    destroy() {
      if (this.slDraggableRect) {
        this.slDraggableRect.draggable(false);
        this.slDraggableRect.off();
        this.selectionRect.off();
      }
      this.selectionRect = null;
      this.zoomRect = null;
      this.gridRect = null;
    }
    /**
     * @param {import('../types/internal').XYRatios} xyRatios
     * @param {any} e
     */
    svgMouseEvents(xyRatios, e) {
      var _a;
      const w = this.w;
      const toolbar = this.ctx.toolbar;
      const zoomtype = w.interact.zoomEnabled ? w.config.chart.zoom.type : w.config.chart.selection.type;
      const autoSelected = w.config.chart.toolbar.autoSelected;
      if (e.shiftKey) {
        this.shiftWasPressed = true;
        toolbar.enableZoomPanFromToolbar(autoSelected === "pan" ? "zoom" : "pan");
      } else {
        if (this.shiftWasPressed) {
          toolbar.enableZoomPanFromToolbar(autoSelected);
          this.shiftWasPressed = false;
        }
      }
      if (!e.target) return;
      const tc = e.target.classList;
      let pc;
      if (e.target.parentNode && e.target.parentNode !== null) {
        pc = e.target.parentNode.classList;
      }
      const falsePositives = tc.contains("apexcharts-legend-marker") || tc.contains("apexcharts-legend-text") || pc && pc.contains("apexcharts-toolbar");
      if (falsePositives) return;
      this.clientX = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientX : e.type === "touchend" ? e.changedTouches[0].clientX : e.clientX;
      this.clientY = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientY : e.type === "touchend" ? e.changedTouches[0].clientY : e.clientY;
      if (e.type === "mousedown" && e.which === 1 || e.type === "touchstart") {
        const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
        if (!gridRectDim) return;
        this.startX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
        this.startY = this.clientY - gridRectDim.top;
        this.dragged = false;
        this.w.interact.mousedown = true;
      }
      if (e.type === "mousemove" && e.which === 1 || e.type === "touchmove") {
        this.dragged = true;
        if (w.interact.panEnabled) {
          w.interact.selection = null;
          if (this.w.interact.mousedown) {
            this.panDragging({
              context: this,
              zoomtype,
              xyRatios
            });
          }
        } else {
          if (this.w.interact.mousedown && w.interact.zoomEnabled || this.w.interact.mousedown && w.interact.selectionEnabled) {
            this.selection = this.selectionDrawing({
              context: this,
              zoomtype
            });
          }
        }
      }
      if (e.type === "mouseup" || e.type === "touchend" || e.type === "mouseleave") {
        this.handleMouseUp({ zoomtype });
      }
      this.makeSelectionRectDraggable();
    }
    /** @param {{ zoomtype?: any, isResized?: any }} opts */
    handleMouseUp({ zoomtype, isResized }) {
      var _a;
      const w = this.w;
      const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
      if (gridRectDim && (this.w.interact.mousedown || isResized)) {
        this.endX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
        this.endY = this.clientY - gridRectDim.top;
        this.dragX = Math.abs(this.endX - this.startX);
        this.dragY = Math.abs(this.endY - this.startY);
        if (w.interact.zoomEnabled || w.interact.selectionEnabled) {
          this.selectionDrawn({
            context: this,
            zoomtype
          });
        }
      }
      if (w.interact.zoomEnabled) {
        this.hideSelectionRect(this.selectionRect);
      }
      this.dragged = false;
      this.w.interact.mousedown = false;
    }
    /**
     * @param {Event} e
     */
    mouseWheelEvent(e) {
      const w = this.w;
      e.preventDefault();
      const now = Date.now();
      if (now - w.interact.lastWheelExecution > this.wheelDelay) {
        this.executeMouseWheelZoom(e);
        w.interact.lastWheelExecution = now;
      }
      if (this.debounceTimer) clearTimeout(this.debounceTimer);
      this.debounceTimer = setTimeout(() => {
        if (now - w.interact.lastWheelExecution > this.wheelDelay) {
          this.executeMouseWheelZoom(e);
          w.interact.lastWheelExecution = now;
        }
      }, this.debounceDelay);
    }
    /**
     * @param {any} e
     */
    executeMouseWheelZoom(e) {
      var _a;
      const w = this.w;
      this.minX = w.axisFlags.isRangeBar ? w.globals.minY : w.globals.minX;
      this.maxX = w.axisFlags.isRangeBar ? w.globals.maxY : w.globals.maxX;
      const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
      if (!gridRectDim) return;
      const mouseX = (e.clientX - gridRectDim.left) / gridRectDim.width;
      const currentMinX = this.minX;
      const currentMaxX = this.maxX;
      const totalX = currentMaxX - currentMinX;
      const zoomFactorIn = 0.5;
      const zoomFactorOut = 1.5;
      let zoomRange;
      let newMinX, newMaxX;
      if (e.deltaY < 0) {
        zoomRange = zoomFactorIn * totalX;
        const midPoint = currentMinX + mouseX * totalX;
        newMinX = midPoint - zoomRange / 2;
        newMaxX = midPoint + zoomRange / 2;
      } else {
        zoomRange = zoomFactorOut * totalX;
        newMinX = currentMinX - zoomRange / 2;
        newMaxX = currentMaxX + zoomRange / 2;
      }
      if (!w.axisFlags.isRangeBar) {
        newMinX = Math.max(newMinX, w.globals.initialMinX);
        newMaxX = Math.min(newMaxX, w.globals.initialMaxX);
        const minRange = (w.globals.initialMaxX - w.globals.initialMinX) * 0.01;
        if (newMaxX - newMinX < minRange) {
          const midPoint = (newMinX + newMaxX) / 2;
          newMinX = midPoint - minRange / 2;
          newMaxX = midPoint + minRange / 2;
        }
      }
      const newMinXMaxX = this._getNewMinXMaxX(newMinX, newMaxX);
      if (!isNaN(newMinXMaxX.minX) && !isNaN(newMinXMaxX.maxX)) {
        this.zoomUpdateOptions(newMinXMaxX.minX, newMinXMaxX.maxX);
      }
    }
    makeSelectionRectDraggable() {
      const w = this.w;
      if (!this.selectionRect) return;
      const rectDim = this.selectionRect.node.getBoundingClientRect();
      if (rectDim.width > 0 && rectDim.height > 0) {
        this.selectionRect.select(false).resize(false);
        this.selectionRect.select({
          createRot: () => {
          },
          updateRot: () => {
          },
          createHandle: (group, p, index, pointArr, handleName) => {
            if (handleName === "l" || handleName === "r")
              return group.circle(8).css({ "stroke-width": 1, stroke: "#333", fill: "#fff" });
            return group.circle(0);
          },
          updateHandle: (group, p) => {
            return group.center(p[0], p[1]);
          }
        }).resize().on("resize", () => {
          const zoomtype = w.interact.zoomEnabled ? w.config.chart.zoom.type : w.config.chart.selection.type;
          this.handleMouseUp({ zoomtype, isResized: true });
        });
      }
    }
    preselectedSelection() {
      const w = this.w;
      const xyRatios = this.xyRatios;
      if (!w.interact.zoomEnabled) {
        if (typeof w.interact.selection !== "undefined" && w.interact.selection !== null) {
          this.drawSelectionRect(__spreadProps(__spreadValues({}, w.interact.selection), {
            translateX: w.layout.translateX,
            translateY: w.layout.translateY
          }));
        } else {
          if (w.config.chart.selection.xaxis.min !== void 0 && w.config.chart.selection.xaxis.max !== void 0) {
            let x = (w.config.chart.selection.xaxis.min - w.globals.minX) / xyRatios.xRatio;
            let width = w.layout.gridWidth - (w.globals.maxX - w.config.chart.selection.xaxis.max) / xyRatios.xRatio - x;
            if (w.axisFlags.isRangeBar) {
              x = (w.config.chart.selection.xaxis.min - w.globals.yAxisScale[0].niceMin) / xyRatios.invertedYRatio;
              width = (w.config.chart.selection.xaxis.max - w.config.chart.selection.xaxis.min) / xyRatios.invertedYRatio;
            }
            const selectionRect = {
              x,
              y: 0,
              width,
              height: w.layout.gridHeight,
              translateX: w.layout.translateX,
              translateY: w.layout.translateY,
              selectionEnabled: true
            };
            this.drawSelectionRect(selectionRect);
            this.makeSelectionRectDraggable();
            if (typeof w.config.chart.events.selection === "function") {
              w.config.chart.events.selection(this.ctx, {
                xaxis: {
                  min: w.config.chart.selection.xaxis.min,
                  max: w.config.chart.selection.xaxis.max
                },
                yaxis: {}
              });
            }
          }
        }
      }
    }
    /** @param {{x: any, y: any, width: any, height: any, translateX: any, translateY: any}} opts */
    drawSelectionRect({ x, y, width, height, translateX = 0, translateY = 0 }) {
      const w = this.w;
      const zoomRect = this.zoomRect;
      const selectionRect = this.selectionRect;
      if (this.dragged || w.interact.selection !== null) {
        const scalingAttrs = {
          transform: "translate(" + translateX + ", " + translateY + ")"
        };
        if (w.interact.zoomEnabled && this.dragged) {
          if (width < 0) width = 1;
          zoomRect.attr({
            x,
            y,
            width,
            height,
            fill: w.config.chart.zoom.zoomedArea.fill.color,
            "fill-opacity": w.config.chart.zoom.zoomedArea.fill.opacity,
            stroke: w.config.chart.zoom.zoomedArea.stroke.color,
            "stroke-width": w.config.chart.zoom.zoomedArea.stroke.width,
            "stroke-opacity": w.config.chart.zoom.zoomedArea.stroke.opacity
          });
          Graphics.setAttrs(zoomRect.node, scalingAttrs);
        }
        if (w.interact.selectionEnabled) {
          selectionRect.attr({
            x,
            y,
            width: width > 0 ? width : 0,
            height: height > 0 ? height : 0,
            fill: w.config.chart.selection.fill.color,
            "fill-opacity": w.config.chart.selection.fill.opacity,
            stroke: w.config.chart.selection.stroke.color,
            "stroke-width": w.config.chart.selection.stroke.width,
            "stroke-dasharray": w.config.chart.selection.stroke.dashArray,
            "stroke-opacity": w.config.chart.selection.stroke.opacity
          });
          Graphics.setAttrs(selectionRect.node, scalingAttrs);
        }
      }
    }
    /**
     * @param {any} rect
     */
    hideSelectionRect(rect) {
      if (rect) {
        rect.attr({
          x: 0,
          y: 0,
          width: 0,
          height: 0
        });
      }
    }
    selectionDrawing({ context, zoomtype }) {
      var _a;
      const w = this.w;
      const me = context;
      const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
      if (!gridRectDim) return;
      const startX = me.startX - 1;
      const startY = me.startY;
      let inversedX = false;
      let inversedY = false;
      const left = me.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
      const top = me.clientY - gridRectDim.top;
      let selectionWidth = left - startX;
      let selectionHeight = top - startY;
      let selectionRect = {
        translateX: w.layout.translateX,
        translateY: w.layout.translateY
      };
      if (Math.abs(selectionWidth + startX) > w.layout.gridWidth) {
        selectionWidth = w.layout.gridWidth - startX;
      } else if (left < 0) {
        selectionWidth = startX;
      }
      if (startX > left) {
        inversedX = true;
        selectionWidth = Math.abs(selectionWidth);
      }
      if (startY > top) {
        inversedY = true;
        selectionHeight = Math.abs(selectionHeight);
      }
      if (zoomtype === "x") {
        selectionRect = {
          x: inversedX ? startX - selectionWidth : startX,
          y: 0,
          width: selectionWidth,
          height: w.layout.gridHeight
        };
      } else if (zoomtype === "y") {
        selectionRect = {
          x: 0,
          y: inversedY ? startY - selectionHeight : startY,
          width: w.layout.gridWidth,
          height: selectionHeight
        };
      } else {
        selectionRect = {
          x: inversedX ? startX - selectionWidth : startX,
          y: inversedY ? startY - selectionHeight : startY,
          width: selectionWidth,
          height: selectionHeight
        };
      }
      selectionRect = __spreadProps(__spreadValues({}, selectionRect), {
        translateX: w.layout.translateX,
        translateY: w.layout.translateY
      });
      me.drawSelectionRect(selectionRect);
      me.selectionDragging("resizing");
      return selectionRect;
    }
    /**
     * @param {string} type
     * @param {CustomEvent} e
     */
    selectionDragging(type, e) {
      var _a;
      const w = this.w;
      if (!e) return;
      e.preventDefault();
      const { handler, box } = e.detail;
      const constraints = (
        /** @type {any} */
        this.constraints
      );
      let { x, y } = box;
      if (x < constraints.x) {
        x = constraints.x;
      }
      if (y < constraints.y) {
        y = constraints.y;
      }
      if (box.x2 > constraints.x2) {
        x = constraints.x2 - box.w;
      }
      if (box.y2 > constraints.y2) {
        y = constraints.y2 - box.h;
      }
      handler.move(x, y);
      const xyRatios = this.xyRatios;
      const selRect = this.selectionRect;
      let timerInterval = 0;
      if (type === "resizing") {
        timerInterval = 30;
      }
      const getSelAttr = (attr) => {
        return parseFloat(selRect.node.getAttribute(attr));
      };
      const draggedProps = {
        x: getSelAttr("x"),
        y: getSelAttr("y"),
        width: getSelAttr("width"),
        height: getSelAttr("height")
      };
      w.interact.selection = draggedProps;
      if (typeof w.config.chart.events.selection === "function" && w.interact.selectionEnabled) {
        clearTimeout((_a = this.w.globals.selectionResizeTimer) != null ? _a : void 0);
        this.w.globals.selectionResizeTimer = window.setTimeout(() => {
          var _a2;
          const gridRectDim = (_a2 = this.gridRect) == null ? void 0 : _a2.getBoundingClientRect();
          if (!gridRectDim) return;
          const selectionRect = selRect.node.getBoundingClientRect();
          let minX, maxX, minY, maxY;
          if (!w.axisFlags.isRangeBar) {
            if (!w.globals.xAxisScale) return;
            minX = w.globals.xAxisScale.niceMin + (selectionRect.left - gridRectDim.left) * xyRatios.xRatio;
            maxX = w.globals.xAxisScale.niceMin + (selectionRect.right - gridRectDim.left) * xyRatios.xRatio;
            minY = w.globals.yAxisScale[0].niceMin + (gridRectDim.bottom - selectionRect.bottom) * xyRatios.yRatio[0];
            maxY = w.globals.yAxisScale[0].niceMax - (selectionRect.top - gridRectDim.top) * xyRatios.yRatio[0];
          } else {
            minX = w.globals.yAxisScale[0].niceMin + (selectionRect.left - gridRectDim.left) * xyRatios.invertedYRatio;
            maxX = w.globals.yAxisScale[0].niceMin + (selectionRect.right - gridRectDim.left) * xyRatios.invertedYRatio;
            minY = 0;
            maxY = 1;
          }
          const xyAxis = {
            xaxis: {
              min: minX,
              max: maxX
            },
            yaxis: {
              min: minY,
              max: maxY
            }
          };
          w.config.chart.events.selection(this.ctx, xyAxis);
          if (w.config.chart.brush.enabled && w.config.chart.events.brushScrolled !== void 0) {
            w.config.chart.events.brushScrolled(this.ctx, xyAxis);
          }
        }, timerInterval);
      }
    }
    /** @param {{context: any, zoomtype: any}} opts */
    selectionDrawn({ context, zoomtype }) {
      var _a, _b;
      const w = this.w;
      const me = context;
      const xyRatios = this.xyRatios;
      const toolbar = this.ctx.toolbar;
      const selRect = w.interact.zoomEnabled ? me.zoomRect.node.getBoundingClientRect() : me.selectionRect.node.getBoundingClientRect();
      const gridRectDim = me.gridRect.getBoundingClientRect();
      const localStartX = selRect.left - gridRectDim.left - w.globals.barPadForNumericAxis;
      const localEndX = selRect.right - gridRectDim.left - w.globals.barPadForNumericAxis;
      const localStartY = selRect.top - gridRectDim.top;
      const localEndY = selRect.bottom - gridRectDim.top;
      let xLowestValue, xHighestValue;
      if (!w.axisFlags.isRangeBar) {
        const niceMin = (_b = (_a = w.globals.xAxisScale) == null ? void 0 : _a.niceMin) != null ? _b : 0;
        xLowestValue = niceMin + localStartX * xyRatios.xRatio;
        xHighestValue = niceMin + localEndX * xyRatios.xRatio;
      } else {
        xLowestValue = w.globals.yAxisScale[0].niceMin + localStartX * xyRatios.invertedYRatio;
        xHighestValue = w.globals.yAxisScale[0].niceMin + localEndX * xyRatios.invertedYRatio;
      }
      const yHighestValue = [];
      const yLowestValue = [];
      w.config.yaxis.forEach((yaxe, index) => {
        const seriesIndex = w.globals.seriesYAxisMap[index][0];
        const highestVal = w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * localStartY;
        const lowestVal = w.globals.yAxisScale[index].niceMax - xyRatios.yRatio[seriesIndex] * localEndY;
        yHighestValue.push(highestVal);
        yLowestValue.push(lowestVal);
      });
      if (me.dragged && (me.dragX > 10 || me.dragY > 10) && xLowestValue !== xHighestValue) {
        if (w.interact.zoomEnabled) {
          if (!w.globals.initialConfig) return;
          let yaxis = Utils$1.clone(w.globals.initialConfig.yaxis);
          let xaxis = Utils$1.clone(w.globals.initialConfig.xaxis);
          w.interact.zoomed = true;
          if (w.config.xaxis.convertedCatToNumeric) {
            xLowestValue = Math.floor(xLowestValue);
            xHighestValue = Math.floor(xHighestValue);
            if (xLowestValue < 1) {
              xLowestValue = 1;
              xHighestValue = w.globals.dataPoints;
            }
            if (xHighestValue - xLowestValue < 2) {
              xHighestValue = xLowestValue + 1;
            }
          }
          if (zoomtype === "xy" || zoomtype === "x") {
            xaxis = {
              min: xLowestValue,
              max: xHighestValue
            };
          }
          if (zoomtype === "xy" || zoomtype === "y") {
            yaxis.forEach((yaxe, index) => {
              yaxis[index].min = yLowestValue[index];
              yaxis[index].max = yHighestValue[index];
            });
          }
          if (toolbar) {
            const beforeZoomRange = toolbar.getBeforeZoomRange(xaxis, yaxis);
            if (beforeZoomRange) {
              xaxis = beforeZoomRange.xaxis ? beforeZoomRange.xaxis : xaxis;
              yaxis = beforeZoomRange.yaxis ? beforeZoomRange.yaxis : yaxis;
            }
          }
          const options2 = {
            xaxis
          };
          if (!w.config.chart.group) {
            options2.yaxis = yaxis;
          }
          me.ctx.updateHelpers._updateOptions(
            options2,
            false,
            me.w.config.chart.animations.dynamicAnimation.enabled
          );
          if (typeof w.config.chart.events.zoomed === "function") {
            toolbar.zoomCallback(xaxis, yaxis);
          }
        } else if (w.interact.selectionEnabled) {
          let yaxis = null;
          let xaxis = null;
          xaxis = {
            min: xLowestValue,
            max: xHighestValue
          };
          if (zoomtype === "xy" || zoomtype === "y") {
            const yaxisCopy = (
              /** @type {ApexYAxis[]} */
              Utils$1.clone(w.config.yaxis)
            );
            yaxis = yaxisCopy;
            yaxisCopy.forEach((yaxe, index) => {
              yaxisCopy[index].min = yLowestValue[index];
              yaxisCopy[index].max = yHighestValue[index];
            });
          }
          w.interact.selection = me.selection;
          if (typeof w.config.chart.events.selection === "function") {
            w.config.chart.events.selection(me.ctx, {
              xaxis,
              yaxis
            });
          }
        }
      }
    }
    /** @param {{ context?: any, zoomtype?: any, xyRatios?: any }} opts */
    panDragging({ context }) {
      var _a;
      const w = this.w;
      const me = context;
      if (typeof w.interact.lastClientPosition.x !== "undefined") {
        const deltaX = w.interact.lastClientPosition.x - me.clientX;
        const deltaY = ((_a = w.interact.lastClientPosition.y) != null ? _a : 0) - me.clientY;
        if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX > 0) {
          this.moveDirection = "left";
        } else if (Math.abs(deltaX) > Math.abs(deltaY) && deltaX < 0) {
          this.moveDirection = "right";
        } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY > 0) {
          this.moveDirection = "up";
        } else if (Math.abs(deltaY) > Math.abs(deltaX) && deltaY < 0) {
          this.moveDirection = "down";
        }
      }
      w.interact.lastClientPosition = {
        x: me.clientX,
        y: me.clientY
      };
      const xLowestValue = w.axisFlags.isRangeBar ? w.globals.minY : w.globals.minX;
      const xHighestValue = w.axisFlags.isRangeBar ? w.globals.maxY : w.globals.maxX;
      me.panScrolled(xLowestValue, xHighestValue);
    }
    // delayedPanScrolled() {
    //   const w = this.w
    //   let newMinX = w.globals.minX
    //   let newMaxX = w.globals.maxX
    //   const centerX = (w.globals.maxX - w.globals.minX) / 2
    //   if (this.moveDirection === 'left') {
    //     newMinX = w.globals.minX + centerX
    //     newMaxX = w.globals.maxX + centerX
    //   } else if (this.moveDirection === 'right') {
    //     newMinX = w.globals.minX - centerX
    //     newMaxX = w.globals.maxX - centerX
    //   }
    //   newMinX = Math.floor(newMinX)
    //   newMaxX = Math.floor(newMaxX)
    //   this.updateScrolledChart(
    //     { xaxis: { min: newMinX, max: newMaxX } },
    //     newMinX,
    //     newMaxX
    //   )
    // }
    /**
     * @param {number} xLowestValue
     * @param {number} xHighestValue
     */
    panScrolled(xLowestValue, xHighestValue) {
      const w = this.w;
      const xyRatios = this.xyRatios;
      if (!w.globals.initialConfig) return;
      const yaxis = Utils$1.clone(w.globals.initialConfig.yaxis);
      let xRatio = xyRatios.xRatio;
      let minX = w.globals.minX;
      let maxX = w.globals.maxX;
      if (w.axisFlags.isRangeBar) {
        xRatio = xyRatios.invertedYRatio;
        minX = w.globals.minY;
        maxX = w.globals.maxY;
      }
      if (this.moveDirection === "left") {
        xLowestValue = minX + w.layout.gridWidth / 15 * xRatio;
        xHighestValue = maxX + w.layout.gridWidth / 15 * xRatio;
      } else if (this.moveDirection === "right") {
        xLowestValue = minX - w.layout.gridWidth / 15 * xRatio;
        xHighestValue = maxX - w.layout.gridWidth / 15 * xRatio;
      }
      if (!w.axisFlags.isRangeBar) {
        if (xLowestValue < w.globals.initialMinX || xHighestValue > w.globals.initialMaxX) {
          xLowestValue = minX;
          xHighestValue = maxX;
        }
      }
      const xaxis = {
        min: xLowestValue,
        max: xHighestValue
      };
      const options2 = {
        xaxis
      };
      if (!w.config.chart.group) {
        options2.yaxis = yaxis;
      }
      this.updateScrolledChart(options2, xLowestValue, xHighestValue);
    }
    /**
     * @param {object} options
     * @param {number} xLowestValue
     * @param {number} xHighestValue
     */
    updateScrolledChart(options2, xLowestValue, xHighestValue) {
      const w = this.w;
      this.ctx.updateHelpers._updateOptions(options2, false, false);
      if (typeof w.config.chart.events.scrolled === "function") {
        const args = {
          xaxis: {
            min: xLowestValue,
            max: xHighestValue
          }
        };
        w.config.chart.events.scrolled(this.ctx, args);
        this.ctx.events.fireEvent("scrolled", args);
      }
    }
  }
  ApexCharts.registerFeatures({
    toolbar: Toolbar,
    zoomPanSelection: ZoomPanSelection
  });
  let Helpers$2 = class Helpers {
    /**
     * @param {import('./Annotations').default} annoCtx
     */
    constructor(annoCtx) {
      this.w = annoCtx.w;
      this.annoCtx = annoCtx;
    }
    /**
     * @param {Record<string, any>} anno
     * @param {number | null} [annoIndex]
     */
    setOrientations(anno, annoIndex = null) {
      var _a, _b;
      const w = this.w;
      if (anno.label.orientation === "vertical") {
        const i = annoIndex !== null ? annoIndex : 0;
        const xAnno = w.dom.baseEl.querySelector(
          `.apexcharts-xaxis-annotations .apexcharts-xaxis-annotation-label[rel='${i}']`
        );
        if (xAnno !== null) {
          const xAnnoCoord = (
            /** @type {SVGGraphicsElement} */
            xAnno.getBBox()
          );
          xAnno.setAttribute(
            "x",
            String(
              parseFloat((_a = xAnno.getAttribute("x")) != null ? _a : "0") - xAnnoCoord.height + 4
            )
          );
          const yOffset = anno.label.position === "top" ? xAnnoCoord.width : -xAnnoCoord.width;
          xAnno.setAttribute(
            "y",
            String(parseFloat((_b = xAnno.getAttribute("y")) != null ? _b : "0") + yOffset)
          );
          const { x, y } = this.annoCtx.graphics.rotateAroundCenter(xAnno);
          xAnno.setAttribute("transform", `rotate(-90 ${x} ${y})`);
        }
      }
    }
    /**
     * @param {any} annoEl
     * @param {Record<string, any>} anno
     */
    addBackgroundToAnno(annoEl, anno) {
      const w = this.w;
      if (!annoEl || !anno.label.text || !String(anno.label.text).trim()) {
        return null;
      }
      const gridEl = w.dom.baseEl.querySelector(".apexcharts-grid");
      if (!gridEl) return null;
      const elGridRect = gridEl.getBoundingClientRect();
      const gridBBox = (
        /** @type {SVGGraphicsElement} */
        gridEl.getBBox()
      );
      const zoom = elGridRect.width / gridBBox.width || 1;
      const coords = annoEl.getBoundingClientRect();
      let {
        left: pleft,
        right: pright,
        top: ptop,
        bottom: pbottom
      } = anno.label.style.padding;
      if (anno.label.orientation === "vertical") {
        [ptop, pbottom, pleft, pright] = [pleft, pright, ptop, pbottom];
      }
      const x1 = (coords.left - elGridRect.left) / zoom - pleft;
      const y1 = (coords.top - elGridRect.top) / zoom - ptop;
      const elRect = this.annoCtx.graphics.drawRect(
        x1 - w.globals.barPadForNumericAxis,
        y1,
        coords.width / zoom + pleft + pright,
        coords.height / zoom + ptop + pbottom,
        anno.label.borderRadius,
        anno.label.style.background,
        1,
        anno.label.borderWidth,
        anno.label.borderColor,
        0
      );
      if (anno.id) {
        elRect.node.classList.add(anno.id);
      }
      return elRect;
    }
    annotationsBackground() {
      const w = this.w;
      const add = (anno, i, type) => {
        const annoLabel = w.dom.baseEl.querySelector(
          `.apexcharts-${type}-annotations .apexcharts-${type}-annotation-label[rel='${i}']`
        );
        if (annoLabel) {
          const parent = annoLabel.parentNode;
          const elRect = this.addBackgroundToAnno(annoLabel, anno);
          if (elRect) {
            parent == null ? void 0 : parent.insertBefore(elRect.node, annoLabel);
            if (anno.label.mouseEnter) {
              elRect.node.addEventListener(
                "mouseenter",
                anno.label.mouseEnter.bind(this, anno)
              );
            }
            if (anno.label.mouseLeave) {
              elRect.node.addEventListener(
                "mouseleave",
                anno.label.mouseLeave.bind(this, anno)
              );
            }
            if (anno.label.click) {
              elRect.node.addEventListener(
                "click",
                anno.label.click.bind(this, anno)
              );
            }
          }
        }
      };
      w.config.annotations.xaxis.forEach(
        (anno, i) => add(anno, i, "xaxis")
      );
      w.config.annotations.yaxis.forEach(
        (anno, i) => add(anno, i, "yaxis")
      );
      w.config.annotations.points.forEach(
        (anno, i) => add(anno, i, "point")
      );
    }
    /**
     * @param {string} type
     * @param {Record<string, any>} anno
     */
    getY1Y2(type, anno) {
      var _a, _b;
      const w = this.w;
      const y = type === "y1" ? anno.y : anno.y2;
      let yP;
      let clipped = false;
      if (this.annoCtx.invertAxis) {
        const labels = w.config.xaxis.convertedCatToNumeric ? w.labelData.categoryLabels : w.labelData.labels;
        const catIndex = labels.indexOf(y);
        const xLabel = w.dom.baseEl.querySelector(
          `.apexcharts-yaxis-texts-g text:nth-child(${catIndex + 1})`
        );
        yP = xLabel ? parseFloat((_a = xLabel.getAttribute("y")) != null ? _a : "0") : (w.layout.gridHeight / labels.length - 1) * (catIndex + 1) - w.globals.barHeight;
        if (anno.seriesIndex !== void 0 && w.globals.barHeight) {
          yP -= w.globals.barHeight / 2 * (w.seriesData.series.length - 1) - w.globals.barHeight * anno.seriesIndex;
        }
      } else {
        const seriesIndex = w.globals.seriesYAxisMap[anno.yAxisIndex][0];
        const yPos = w.config.yaxis[anno.yAxisIndex].logarithmic ? new CoreUtils(this.w).getLogVal(
          w.config.yaxis[anno.yAxisIndex].logBase,
          y,
          seriesIndex
        ) / /** @type {any} */
        w.globals.yLogRatio[seriesIndex] : (y - w.globals.minYArr[seriesIndex]) / (w.globals.yRange[seriesIndex] / w.layout.gridHeight);
        yP = w.layout.gridHeight - Math.min(Math.max(yPos, 0), w.layout.gridHeight);
        clipped = yPos > w.layout.gridHeight || yPos < 0;
        if (anno.marker && (anno.y === void 0 || anno.y === null)) {
          yP = 0;
        }
        if ((_b = w.config.yaxis[anno.yAxisIndex]) == null ? void 0 : _b.reversed) {
          yP = yPos;
        }
      }
      if (typeof y === "string" && y.includes("px")) {
        yP = parseFloat(y);
      }
      return { yP, clipped };
    }
    /**
     * @param {string} type
     * @param {Record<string, any>} anno
     */
    getX1X2(type, anno) {
      const w = this.w;
      const x = type === "x1" ? anno.x : anno.x2;
      const min = this.annoCtx.invertAxis ? w.globals.minY : w.globals.minX;
      const max = this.annoCtx.invertAxis ? w.globals.maxY : w.globals.maxX;
      const range = this.annoCtx.invertAxis ? w.globals.yRange[0] : w.globals.xRange;
      let clipped = false;
      let xP = this.annoCtx.inversedReversedAxis ? (max - x) / (range / w.layout.gridWidth) : (x - min) / (range / w.layout.gridWidth);
      if ((w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) && !this.annoCtx.invertAxis && !w.axisFlags.dataFormatXNumeric) {
        if (!w.config.chart.sparkline.enabled) {
          xP = this.getStringX(x);
        }
      }
      if (typeof x === "string" && x.includes("px")) {
        xP = parseFloat(x);
      }
      if ((x === void 0 || x === null) && anno.marker) {
        xP = w.layout.gridWidth;
      }
      if (anno.seriesIndex !== void 0 && w.globals.barWidth && !this.annoCtx.invertAxis) {
        xP -= w.globals.barWidth / 2 * (w.seriesData.series.length - 1) - w.globals.barWidth * anno.seriesIndex;
      }
      if (typeof xP !== "number") {
        xP = 0;
        clipped = true;
      }
      if (parseFloat(xP.toFixed(10)) > parseFloat(w.layout.gridWidth.toFixed(10))) {
        xP = w.layout.gridWidth;
        clipped = true;
      } else if (xP < 0) {
        xP = 0;
        clipped = true;
      }
      return { x: xP, clipped };
    }
    /**
     * @param {number} x
     */
    getStringX(x) {
      var _a;
      const w = this.w;
      let rX = x;
      if (w.config.xaxis.convertedCatToNumeric && w.labelData.categoryLabels.length) {
        const strX = String(x);
        x = w.labelData.categoryLabels.findIndex(
          (l) => String(l) === strX
        ) + 1;
      }
      const catIndex = w.labelData.labels.map(
        (item) => Array.isArray(item) ? item.join(" ") : item
      ).indexOf(x);
      const xLabel = w.dom.baseEl.querySelector(
        `.apexcharts-xaxis-texts-g text:nth-child(${catIndex + 1})`
      );
      if (xLabel) {
        rX = parseFloat((_a = xLabel.getAttribute("x")) != null ? _a : "0");
      }
      return rX;
    }
  };
  class XAnnotations {
    /**
     * @param {import('./Annotations').default} annoCtx
     */
    constructor(annoCtx) {
      this.w = annoCtx.w;
      this.annoCtx = annoCtx;
      this.invertAxis = this.annoCtx.invertAxis;
      this.helpers = new Helpers$2(this.annoCtx);
    }
    /**
     * @param {XAxisAnnotations} anno
     * @param {Element} parent
     * @param {number} index
     */
    addXaxisAnnotation(anno, parent, index) {
      const w = this.w;
      const result = this.helpers.getX1X2("x1", anno);
      let x1 = result.x;
      const clipX1 = result.clipped;
      let clipX2 = true;
      let x2;
      const text = anno.label.text;
      const strokeDashArray = anno.strokeDashArray;
      if (!Utils$1.isNumber(x1)) return;
      if (anno.x2 === null || typeof anno.x2 === "undefined") {
        if (!clipX1) {
          const line = this.annoCtx.graphics.drawLine(
            x1 + anno.offsetX,
            // x1
            0 + anno.offsetY,
            // y1
            x1 + anno.offsetX,
            // x2
            w.layout.gridHeight + anno.offsetY,
            // y2
            anno.borderColor,
            // lineColor
            strokeDashArray,
            //dashArray
            anno.borderWidth
          );
          parent.appendChild(line.node);
          if (anno.id) {
            line.node.classList.add(anno.id);
          }
        }
      } else {
        const result2 = this.helpers.getX1X2("x2", anno);
        x2 = result2.x;
        clipX2 = result2.clipped;
        if (x2 < x1) {
          const temp = x1;
          x1 = x2;
          x2 = temp;
        }
        const rect = this.annoCtx.graphics.drawRect(
          x1 + anno.offsetX,
          // x1
          0 + anno.offsetY,
          // y1
          x2 - x1,
          // x2
          w.layout.gridHeight + anno.offsetY,
          // y2
          0,
          // radius
          anno.fillColor,
          // color
          anno.opacity,
          // opacity,
          1,
          // strokeWidth
          anno.borderColor,
          // strokeColor
          strokeDashArray
          // stokeDashArray
        );
        rect.node.classList.add("apexcharts-annotation-rect");
        rect.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
        parent.appendChild(rect.node);
        if (anno.id) {
          rect.node.classList.add(anno.id);
        }
      }
      if (!(clipX1 && clipX2)) {
        const textRects = this.annoCtx.graphics.getTextRects(
          text,
          anno.label.style.fontSize
        );
        const textY = anno.label.position === "top" ? 4 : anno.label.position === "center" ? w.layout.gridHeight / 2 + (anno.label.orientation === "vertical" ? textRects.width / 2 : 0) : w.layout.gridHeight;
        const elText = this.annoCtx.graphics.drawText({
          x: x1 + anno.label.offsetX,
          y: textY + anno.label.offsetY - (anno.label.orientation === "vertical" ? anno.label.position === "top" ? textRects.width / 2 - 12 : -textRects.width / 2 : 0),
          text,
          textAnchor: anno.label.textAnchor,
          fontSize: anno.label.style.fontSize,
          fontFamily: anno.label.style.fontFamily,
          fontWeight: anno.label.style.fontWeight,
          foreColor: anno.label.style.color,
          cssClass: `apexcharts-xaxis-annotation-label ${anno.label.style.cssClass} ${anno.id ? anno.id : ""}`
        });
        elText.attr({
          rel: index
        });
        parent.appendChild(elText.node);
        this.annoCtx.helpers.setOrientations(anno, index);
      }
    }
    drawXAxisAnnotations() {
      const w = this.w;
      const elg = this.annoCtx.graphics.group({
        class: "apexcharts-xaxis-annotations"
      });
      w.config.annotations.xaxis.map(
        (anno, index) => {
          this.addXaxisAnnotation(anno, elg.node, index);
        }
      );
      return elg;
    }
  }
  class YAnnotations {
    /**
     * @param {import('./Annotations').default} annoCtx
     */
    constructor(annoCtx) {
      this.w = annoCtx.w;
      this.annoCtx = annoCtx;
      this.helpers = new Helpers$2(this.annoCtx);
      this.axesUtils = new AxesUtils(this.annoCtx.w, {
        theme: this.annoCtx.theme,
        timeScale: this.annoCtx.timeScale
      });
    }
    /**
     * @param {YAxisAnnotations} anno
     * @param {Element} parent
     * @param {number} index
     */
    addYaxisAnnotation(anno, parent, index) {
      const w = this.w;
      const strokeDashArray = anno.strokeDashArray;
      let result = this.helpers.getY1Y2("y1", anno);
      let y1 = result.yP;
      const clipY1 = result.clipped;
      let y2;
      let clipY2 = true;
      let drawn = false;
      const text = anno.label.text;
      if (anno.y2 === null || typeof anno.y2 === "undefined") {
        if (!clipY1) {
          drawn = true;
          const line = this.annoCtx.graphics.drawLine(
            0 + anno.offsetX,
            // x1
            y1 + anno.offsetY,
            // y1
            this._getYAxisAnnotationWidth(anno),
            // x2
            y1 + anno.offsetY,
            // y2
            anno.borderColor,
            // lineColor
            strokeDashArray,
            // dashArray
            anno.borderWidth
          );
          parent.appendChild(line.node);
          if (anno.id) {
            line.node.classList.add(anno.id);
          }
        }
      } else {
        result = this.helpers.getY1Y2("y2", anno);
        y2 = result.yP;
        clipY2 = result.clipped;
        if (y2 > y1) {
          const temp = y1;
          y1 = y2;
          y2 = temp;
        }
        if (!(clipY1 && clipY2)) {
          drawn = true;
          const rect = this.annoCtx.graphics.drawRect(
            0 + anno.offsetX,
            // x1
            y2 + anno.offsetY,
            // y1
            this._getYAxisAnnotationWidth(anno),
            // x2
            y1 - y2,
            // y2
            0,
            // radius
            anno.fillColor,
            // color
            anno.opacity,
            // opacity,
            1,
            // strokeWidth
            anno.borderColor,
            // strokeColor
            strokeDashArray
            // stokeDashArray
          );
          rect.node.classList.add("apexcharts-annotation-rect");
          rect.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
          parent.appendChild(rect.node);
          if (anno.id) {
            rect.node.classList.add(anno.id);
          }
        }
      }
      if (drawn) {
        const textX = anno.label.position === "right" ? w.layout.gridWidth : anno.label.position === "center" ? w.layout.gridWidth / 2 : 0;
        const elText = this.annoCtx.graphics.drawText({
          x: textX + anno.label.offsetX,
          y: (y2 != null ? y2 : y1) + anno.label.offsetY - 3,
          text,
          textAnchor: anno.label.textAnchor,
          fontSize: anno.label.style.fontSize,
          fontFamily: anno.label.style.fontFamily,
          fontWeight: anno.label.style.fontWeight,
          foreColor: anno.label.style.color,
          cssClass: `apexcharts-yaxis-annotation-label ${anno.label.style.cssClass} ${anno.id ? anno.id : ""}`
        });
        elText.attr({
          rel: index
        });
        parent.appendChild(elText.node);
      }
    }
    /**
     * @param {YAxisAnnotations} anno
     */
    _getYAxisAnnotationWidth(anno) {
      const w = this.w;
      let width = w.layout.gridWidth;
      if (anno.width.indexOf("%") > -1) {
        width = w.layout.gridWidth * parseInt(anno.width, 10) / 100;
      } else {
        width = parseInt(anno.width, 10);
      }
      return width + anno.offsetX;
    }
    drawYAxisAnnotations() {
      const w = this.w;
      const elg = this.annoCtx.graphics.group({
        class: "apexcharts-yaxis-annotations"
      });
      w.config.annotations.yaxis.forEach(
        (anno, index) => {
          anno.yAxisIndex = this.axesUtils.translateYAxisIndex(anno.yAxisIndex);
          if (!(this.axesUtils.isYAxisHidden(anno.yAxisIndex) && this.axesUtils.yAxisAllSeriesCollapsed(anno.yAxisIndex))) {
            this.addYaxisAnnotation(anno, elg.node, index);
          }
        }
      );
      return elg;
    }
  }
  class PointAnnotations {
    /**
     * @param {import('./Annotations').default} annoCtx
     */
    constructor(annoCtx) {
      this.w = annoCtx.w;
      this.annoCtx = annoCtx;
      this.helpers = new Helpers$2(this.annoCtx);
    }
    /**
     * @param {Record<string, any>} anno
     * @param {Element} parent
     * @param {number} index
     */
    addPointAnnotation(anno, parent, index) {
      const w = this.w;
      if (w.globals.collapsedSeriesIndices.indexOf(anno.seriesIndex) > -1) {
        return;
      }
      const resultX = this.helpers.getX1X2("x1", anno);
      const x = resultX.x;
      const clipX = resultX.clipped;
      const resultY = this.helpers.getY1Y2("y1", anno);
      const y = resultY.yP;
      const clipY = resultY.clipped;
      if (!Utils$1.isNumber(x)) return;
      if (!(clipY || clipX)) {
        const optsPoints = {
          pSize: anno.marker.size,
          pointStrokeWidth: anno.marker.strokeWidth,
          pointFillColor: anno.marker.fillColor,
          pointStrokeColor: anno.marker.strokeColor,
          shape: anno.marker.shape,
          pRadius: anno.marker.radius,
          class: `apexcharts-point-annotation-marker ${anno.marker.cssClass} ${anno.id ? anno.id : ""}`
        };
        let point = this.annoCtx.graphics.drawMarker(
          x + anno.marker.offsetX,
          y + anno.marker.offsetY,
          optsPoints
        );
        parent.appendChild(point.node);
        const text = anno.label.text ? anno.label.text : "";
        const elText = this.annoCtx.graphics.drawText({
          x: x + anno.label.offsetX,
          y: y + anno.label.offsetY - anno.marker.size - parseFloat(anno.label.style.fontSize) / 1.6,
          text,
          textAnchor: anno.label.textAnchor,
          fontSize: anno.label.style.fontSize,
          fontFamily: anno.label.style.fontFamily,
          fontWeight: anno.label.style.fontWeight,
          foreColor: anno.label.style.color,
          cssClass: `apexcharts-point-annotation-label ${anno.label.style.cssClass} ${anno.id ? anno.id : ""}`
        });
        elText.attr({
          rel: index
        });
        parent.appendChild(elText.node);
        if (anno.customSVG.SVG) {
          const g = this.annoCtx.graphics.group({
            class: "apexcharts-point-annotations-custom-svg " + anno.customSVG.cssClass
          });
          g.attr({
            transform: `translate(${x + anno.customSVG.offsetX}, ${y + anno.customSVG.offsetY})`
          });
          g.node.innerHTML = anno.customSVG.SVG;
          parent.appendChild(g.node);
        }
        if (anno.image.path) {
          const imgWidth = anno.image.width ? anno.image.width : 20;
          const imgHeight = anno.image.height ? anno.image.height : 20;
          point = this.annoCtx.addImage({
            x: x + anno.image.offsetX - imgWidth / 2,
            y: y + anno.image.offsetY - imgHeight / 2,
            width: imgWidth,
            height: imgHeight,
            path: anno.image.path,
            appendTo: ".apexcharts-point-annotations"
          });
        }
        if (anno.mouseEnter) {
          point.node.addEventListener(
            "mouseenter",
            anno.mouseEnter.bind(this, anno)
          );
        }
        if (anno.mouseLeave) {
          point.node.addEventListener(
            "mouseleave",
            anno.mouseLeave.bind(this, anno)
          );
        }
        if (anno.click) {
          point.node.addEventListener("click", anno.click.bind(this, anno));
        }
      }
    }
    drawPointAnnotations() {
      const w = this.w;
      const elg = this.annoCtx.graphics.group({
        class: "apexcharts-point-annotations"
      });
      w.config.annotations.points.map(
        (anno, index) => {
          this.addPointAnnotation(anno, elg.node, index);
        }
      );
      return elg;
    }
  }
  class Annotations {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     */
    constructor(w, { theme = null, timeScale = null } = {}) {
      this.w = w;
      this.theme = theme;
      this.timeScale = timeScale;
      this.invertAxis = void 0;
      this.inversedReversedAxis = void 0;
      this.graphics = new Graphics(this.w);
      if (this.w.globals.isBarHorizontal) {
        this.invertAxis = true;
      }
      this.helpers = new Helpers$2(this);
      this.xAxisAnnotations = new XAnnotations(this);
      this.yAxisAnnotations = new YAnnotations(this);
      this.pointsAnnotations = new PointAnnotations(this);
      if (this.w.globals.isBarHorizontal && this.w.config.yaxis[0].reversed) {
        this.inversedReversedAxis = true;
      }
      this.xDivision = this.w.layout.gridWidth / this.w.globals.dataPoints;
    }
    drawAxesAnnotations() {
      const w = this.w;
      if (w.globals.axisCharts && w.globals.dataPoints) {
        const yAnnotations = this.yAxisAnnotations.drawYAxisAnnotations();
        const xAnnotations = this.xAxisAnnotations.drawXAxisAnnotations();
        const pointAnnotations = this.pointsAnnotations.drawPointAnnotations();
        const initialAnim = w.config.chart.animations.enabled;
        const annoArray = [yAnnotations, xAnnotations, pointAnnotations];
        const annoElArray = [
          xAnnotations.node,
          yAnnotations.node,
          pointAnnotations.node
        ];
        for (let i = 0; i < 3; i++) {
          w.dom.elGraphical.add(annoArray[i]);
          if (initialAnim && !w.globals.resized && !w.globals.dataChanged) {
            if (w.config.chart.type !== "scatter" && w.config.chart.type !== "bubble" && w.globals.dataPoints > 1) {
              annoElArray[i].classList.add("apexcharts-element-hidden");
            }
          }
          w.globals.delayedElements.push({ el: annoElArray[i], index: 0 });
        }
        this.helpers.annotationsBackground();
      }
    }
    drawImageAnnos() {
      const w = this.w;
      w.config.annotations.images.map((s) => {
        this.addImage(s);
      });
    }
    drawTextAnnos() {
      const w = this.w;
      w.config.annotations.texts.map((t) => {
        this.addText(t);
      });
    }
    /**
     * @param {Record<string, any>} anno
     * @param {Element} parent
     * @param {number} index
     */
    addXaxisAnnotation(anno, parent, index) {
      this.xAxisAnnotations.addXaxisAnnotation(anno, parent, index);
    }
    /**
     * @param {Record<string, any>} anno
     * @param {Element} parent
     * @param {number} index
     */
    addYaxisAnnotation(anno, parent, index) {
      this.yAxisAnnotations.addYaxisAnnotation(anno, parent, index);
    }
    /**
     * @param {Record<string, any>} anno
     * @param {Element} parent
     * @param {number} index
     */
    addPointAnnotation(anno, parent, index) {
      this.pointsAnnotations.addPointAnnotation(anno, parent, index);
    }
    /**
     * @param {Record<string, any>} params
     */
    addText(params) {
      const {
        x,
        y,
        text,
        textAnchor,
        foreColor,
        fontSize,
        fontFamily,
        fontWeight,
        cssClass,
        backgroundColor,
        borderWidth,
        strokeDashArray,
        borderRadius,
        borderColor,
        appendTo = ".apexcharts-svg",
        paddingLeft = 4,
        paddingRight = 4,
        paddingBottom = 2,
        paddingTop = 2
      } = params;
      const w = this.w;
      const elText = this.graphics.drawText({
        x,
        y,
        text,
        textAnchor: textAnchor || "start",
        fontSize: fontSize || "12px",
        fontWeight: fontWeight || "regular",
        fontFamily: fontFamily || w.config.chart.fontFamily,
        foreColor: foreColor || w.config.chart.foreColor,
        cssClass: "apexcharts-text " + cssClass ? cssClass : ""
      });
      const parent = w.dom.baseEl.querySelector(appendTo);
      if (parent) {
        parent.appendChild(elText.node);
      }
      const textRect = elText.bbox();
      if (text) {
        const elRect = this.graphics.drawRect(
          textRect.x - paddingLeft,
          textRect.y - paddingTop,
          textRect.width + paddingLeft + paddingRight,
          textRect.height + paddingBottom + paddingTop,
          borderRadius,
          backgroundColor ? backgroundColor : "transparent",
          1,
          borderWidth,
          borderColor,
          strokeDashArray
        );
        parent.insertBefore(elRect.node, elText.node);
      }
    }
    /**
     * @param {Record<string, any>} params
     */
    addImage(params) {
      const w = this.w;
      const {
        path,
        x = 0,
        y = 0,
        width = 20,
        height = 20,
        appendTo = ".apexcharts-svg"
      } = params;
      const img = w.dom.Paper.image(path);
      img.size(width, height).move(x, y);
      const parent = w.dom.baseEl.querySelector(appendTo);
      if (parent) {
        parent.appendChild(img.node);
      }
      return img;
    }
    // The addXaxisAnnotation method requires a parent class, and user calling this method externally on the chart instance may not specify parent, hence a different method
    /**
     * @param {Record<string, any>} params
     * @param {boolean} pushToMemory
     * @param {any} context
     */
    addXaxisAnnotationExternal(params, pushToMemory, context) {
      this.addAnnotationExternal({
        params,
        pushToMemory,
        context,
        type: "xaxis",
        contextMethod: context.addXaxisAnnotation
      });
      return context;
    }
    /**
     * @param {Record<string, any>} params
     * @param {boolean} pushToMemory
     * @param {any} context
     */
    addYaxisAnnotationExternal(params, pushToMemory, context) {
      this.addAnnotationExternal({
        params,
        pushToMemory,
        context,
        type: "yaxis",
        contextMethod: context.addYaxisAnnotation
      });
      return context;
    }
    /**
     * @param {Record<string, any>} params
     * @param {boolean} pushToMemory
     * @param {any} context
     */
    addPointAnnotationExternal(params, pushToMemory, context) {
      if (typeof this.invertAxis === "undefined") {
        this.invertAxis = context.w.globals.isBarHorizontal;
      }
      this.addAnnotationExternal({
        params,
        pushToMemory,
        context,
        type: "point",
        contextMethod: context.addPointAnnotation
      });
      return context;
    }
    /** @param {{params: any, pushToMemory: any, context: any, type: any, contextMethod: any}} opts */
    addAnnotationExternal({
      params,
      pushToMemory,
      context,
      type,
      contextMethod
    }) {
      const me = context;
      const w = me.w;
      const parent = w.dom.baseEl.querySelector(`.apexcharts-${type}-annotations`);
      const index = parent.childNodes.length + 1;
      const options2 = new Options();
      const axesAnno = Object.assign(
        {},
        type === "xaxis" ? options2.xAxisAnnotation : type === "yaxis" ? options2.yAxisAnnotation : options2.pointAnnotation
      );
      const anno = Utils$1.extend(axesAnno, params);
      switch (type) {
        case "xaxis":
          this.addXaxisAnnotation(anno, parent, index);
          break;
        case "yaxis":
          this.addYaxisAnnotation(anno, parent, index);
          break;
        case "point":
          this.addPointAnnotation(anno, parent, index);
          break;
      }
      const axesAnnoLabel = w.dom.baseEl.querySelector(
        `.apexcharts-${type}-annotations .apexcharts-${type}-annotation-label[rel='${index}']`
      );
      const elRect = this.helpers.addBackgroundToAnno(axesAnnoLabel, anno);
      if (elRect) {
        parent.insertBefore(elRect.node, axesAnnoLabel);
      }
      if (pushToMemory) {
        w.globals.memory.methodsToExec.push({
          context: me,
          id: anno.id ? anno.id : Utils$1.randomId(),
          method: contextMethod,
          label: "addAnnotation",
          params
        });
      }
      return context;
    }
    /**
     * @param {import('../../types/internal').ChartContext} ctx
     */
    clearAnnotations(ctx) {
      const w = ctx.w;
      const annos = w.dom.baseEl.querySelectorAll(
        ".apexcharts-yaxis-annotations, .apexcharts-xaxis-annotations, .apexcharts-point-annotations"
      );
      for (let i = w.globals.memory.methodsToExec.length - 1; i >= 0; i--) {
        if (w.globals.memory.methodsToExec[i].label === "addText" || w.globals.memory.methodsToExec[i].label === "addAnnotation") {
          w.globals.memory.methodsToExec.splice(i, 1);
        }
      }
      Array.prototype.forEach.call(annos, (a) => {
        while (a.firstChild) {
          a.removeChild(a.firstChild);
        }
      });
    }
    /**
     * @param {import('../../types/internal').ChartContext} ctx
     * @param {string} id
     */
    removeAnnotation(ctx, id) {
      const w = ctx.w;
      const annos = w.dom.baseEl.querySelectorAll(`.${id}`);
      if (annos) {
        w.globals.memory.methodsToExec.map((m, i) => {
          if (m.id === id) {
            w.globals.memory.methodsToExec.splice(i, 1);
          }
        });
        Object.keys(w.config.annotations).forEach((key) => {
          const annotationArray = w.config.annotations[key];
          if (Array.isArray(annotationArray)) {
            w.config.annotations[key] = annotationArray.filter((m) => m.id !== id);
          }
        });
        Array.prototype.forEach.call(annos, (a) => {
          a.parentElement.removeChild(a);
        });
      }
    }
  }
  ApexCharts.registerFeatures({ annotations: Annotations });
  class KeyboardNavigation {
    /**
     * @param {import('../../types/internal').ChartStateW} w
     * @param {import('../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.w = w;
      this.ctx = ctx;
      this.seriesIndex = 0;
      this.dataPointIndex = 0;
      this.active = false;
      this._focusedEl = null;
      this._hoveredBarEl = null;
      this._enlargedScatterMarker = null;
      this._onKeyDown = this._onKeyDown.bind(this);
      this._onFocus = this._onFocus.bind(this);
      this._onBlur = this._onBlur.bind(this);
      this._onLegendClick = this._onLegendClick.bind(this);
    }
    // ─── Public API ───────────────────────────────────────────────────────────
    /**
     * Called after the chart and tooltip have been fully rendered.
     * Attaches event listeners and makes the SVG keyboard-focusable.
     */
    init() {
      const w = this.w;
      const svgEl = w.dom.Paper.node;
      if (!svgEl) return;
      svgEl.setAttribute("tabindex", "0");
      svgEl.addEventListener("focus", this._onFocus);
      svgEl.addEventListener("blur", this._onBlur);
      svgEl.addEventListener("keydown", this._onKeyDown, { passive: false });
      this.ctx.events.addEventListener("legendClick", this._onLegendClick);
    }
    /**
     * Removes all event listeners. Called from chart.destroy().
     */
    destroy() {
      const w = this.w;
      const svgEl = w.dom.Paper && w.dom.Paper.node;
      if (!svgEl) return;
      svgEl.removeEventListener("focus", this._onFocus);
      svgEl.removeEventListener("blur", this._onBlur);
      svgEl.removeEventListener("keydown", this._onKeyDown);
      this.ctx.events.removeEventListener("legendClick", this._onLegendClick);
    }
    /**
     * Called from Events.js keydown handler. Navigation keys are already handled
     * by the direct SVG listener (which can call preventDefault). This entry
     * point is intentionally a no-op — Events.js still fires the public keyDown
     * callback and fireEvent('keydown') independently.
     * @param {Event} _e
     */
    handleKey(_e) {
    }
    // ─── Focus / blur ─────────────────────────────────────────────────────────
    _onFocus() {
      if (!this._isNavEnabled()) return;
      this.active = true;
      this._clampCursor();
      this._snapToVisibleRange();
      this._showCurrentPoint();
    }
    _onBlur() {
      this.active = false;
      this._hideFocus();
    }
    // Called when the user clicks a legend item (collapse/expand a series).
    // Hide the keyboard-nav tooltip — the chart is about to re-render and the
    // current position may no longer be valid.
    _onLegendClick() {
      if (!this.active) return;
      this.active = false;
      this._hideFocus();
    }
    // ─── Key handler ──────────────────────────────────────────────────────────
    /**
     * @param {KeyboardEvent} e
     */
    _onKeyDown(e) {
      if (!this._isNavEnabled() || !this.active) return;
      switch (e.key) {
        case "ArrowRight":
          e.preventDefault();
          this._move(0, 1);
          break;
        case "ArrowLeft":
          e.preventDefault();
          this._move(0, -1);
          break;
        case "ArrowUp":
          e.preventDefault();
          this._move(-1, 0);
          break;
        case "ArrowDown":
          e.preventDefault();
          this._move(1, 0);
          break;
        case "Home":
          e.preventDefault();
          this.dataPointIndex = 0;
          this._skipNullForward();
          this._showCurrentPoint();
          break;
        case "End":
          e.preventDefault();
          this.dataPointIndex = this._getDataPointCount(this.seriesIndex) - 1;
          this._skipNullBackward();
          this._showCurrentPoint();
          break;
        case "Enter":
        case " ":
          e.preventDefault();
          this._fireClick();
          break;
        case "Escape":
          e.preventDefault();
          this.active = false;
          this._hideFocus();
          break;
      }
    }
    // ─── Navigation ───────────────────────────────────────────────────────────
    /**
     * @param {number} dSeries
     * @param {number} dPoint
     */
    _move(dSeries, dPoint) {
      const w = this.w;
      const wrapAround = w.config.chart.accessibility.keyboard.navigation.wrapAround;
      if (dSeries !== 0) {
        const ttCtx = this.w.globals.tooltip;
        if (ttCtx && ttCtx.tConfig && ttCtx.tConfig.shared) {
          const j = this.dataPointIndex;
          const isActuallyShared = ttCtx.tooltipUtil && ttCtx.tooltipUtil.isXoverlap(j) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
          if (isActuallyShared) return;
        }
        const total = this._getSeriesCount();
        let si = this.seriesIndex + dSeries;
        let attempts = 0;
        while (attempts < total) {
          if (si < 0) si = wrapAround ? total - 1 : 0;
          if (si >= total) si = wrapAround ? 0 : total - 1;
          if (!w.globals.collapsedSeriesIndices.includes(si)) break;
          si += dSeries;
          attempts++;
        }
        this.seriesIndex = si;
        const dpCount = this._getDataPointCount(si);
        if (this.dataPointIndex >= dpCount) {
          this.dataPointIndex = dpCount - 1;
        }
      }
      if (dPoint !== 0) {
        const dpCount = this._getDataPointCount(this.seriesIndex);
        let di = this.dataPointIndex + dPoint;
        if (di < 0) di = wrapAround ? dpCount - 1 : 0;
        if (di >= dpCount) di = wrapAround ? 0 : dpCount - 1;
        this.dataPointIndex = di;
        if (dPoint > 0) {
          this._skipNullForward();
        } else {
          this._skipNullBackward();
        }
        if (!this._isDataPointVisible(this.seriesIndex, this.dataPointIndex)) {
          this._snapToVisibleRangeInDirection(dPoint);
        }
      }
      this._showCurrentPoint();
    }
    /** Advance dataPointIndex forward past any nulls */
    _skipNullForward() {
      const w = this.w;
      const si = this.seriesIndex;
      const dpCount = this._getDataPointCount(si);
      let di = this.dataPointIndex;
      let attempts = 0;
      if (!Array.isArray(w.seriesData.series[si])) return;
      while (attempts < dpCount && w.seriesData.series[si][di] === null) {
        di = (di + 1) % dpCount;
        attempts++;
      }
      this.dataPointIndex = di;
    }
    /** Retreat dataPointIndex backward past any nulls */
    _skipNullBackward() {
      const w = this.w;
      const si = this.seriesIndex;
      const dpCount = this._getDataPointCount(si);
      let di = this.dataPointIndex;
      let attempts = 0;
      if (!Array.isArray(w.seriesData.series[si])) return;
      while (attempts < dpCount && w.seriesData.series[si][di] === null) {
        di = (di - 1 + dpCount) % dpCount;
        attempts++;
      }
      this.dataPointIndex = di;
    }
    // ─── Display ──────────────────────────────────────────────────────────────
    _showCurrentPoint() {
      const { seriesIndex: i, dataPointIndex: j } = this;
      const w = this.w;
      const ttCtx = w.globals.tooltip;
      if (!ttCtx || !ttCtx.ttItems) return;
      w.interact.capturedSeriesIndex = i;
      w.interact.capturedDataPointIndex = j;
      this._applyFocusClass(i, j);
      this._showTooltip(
        i,
        j,
        /** @type {any} */
        ttCtx
      );
    }
    _hideFocus() {
      const w = this.w;
      const ttCtx = (
        /** @type {any} */
        w.globals.tooltip
      );
      this._removeFocusClass();
      this._leaveHoveredBar();
      if (!ttCtx) return;
      if (ttCtx.marker) {
        ttCtx.marker.resetPointsSize();
      }
      this._enlargedScatterMarker = null;
      const tooltipEl = ttCtx.getElTooltip();
      if (tooltipEl) {
        tooltipEl.classList.remove("apexcharts-active");
        if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
          tooltipEl.setAttribute("aria-hidden", "true");
        }
      }
      w.dom.baseEl.classList.remove("apexcharts-tooltip-active");
      const xcrosshairs = ttCtx.getElXCrosshairs();
      if (xcrosshairs) xcrosshairs.classList.remove("apexcharts-active");
    }
    // ─── Tooltip display per chart type ───────────────────────────────────────
    /**
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     */
    _showTooltip(i, j, ttCtx) {
      const w = this.w;
      const type = w.config.chart.type;
      const tooltipEl = ttCtx.getElTooltip();
      if (!tooltipEl) return;
      const cachedDims = ttCtx.getCachedDimensions();
      ttCtx.tooltipRect = {
        x: 0,
        y: 0,
        ttWidth: cachedDims.ttWidth || 0,
        ttHeight: cachedDims.ttHeight || 0
      };
      this._setSyntheticEvent(i, j, ttCtx);
      w.dom.baseEl.classList.add("apexcharts-tooltip-active");
      tooltipEl.classList.add("apexcharts-active");
      if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
        tooltipEl.removeAttribute("aria-hidden");
      }
      if (type === "pie" || type === "donut" || type === "polarArea") {
        this._showTooltipNonAxis(i, j, ttCtx, tooltipEl);
      } else if (type === "radialBar") {
        this._showTooltipRadialBar(i, j, ttCtx, tooltipEl);
      } else if (type === "heatmap" || type === "treemap") {
        this._showTooltipHeatTree(i, j, ttCtx, tooltipEl, type);
      } else if (type === "bar" || type === "candlestick" || type === "boxPlot" || type === "rangeBar") {
        this._showTooltipBar(i, j, ttCtx);
      } else {
        this._showTooltipAxisLine(i, j, ttCtx);
      }
    }
    /**
     * Set ttCtx.e to a synthetic mouse-event-like object whose clientX/Y point
     * to the centre of the current data-point element.  This ensures that any
     * positioning helper that reads ttCtx.e (followCursor path in moveTooltip,
     * moveStickyTooltipOverBars, moveDynamicPointsOnHover, etc.) gets valid
     * coordinates rather than crashing on undefined.
     *
     * For chart types that don't have a concrete SVG element per data point
     * (pie, radialBar) we fall back to the SVG centre.
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     */
    _setSyntheticEvent(i, j, ttCtx) {
      const w = this.w;
      const type = w.config.chart.type;
      let clientX = 0;
      let clientY = 0;
      const el = this._getFocusableElement(i, j);
      if (el) {
        const rect = el.getBoundingClientRect();
        clientX = rect.left + rect.width / 2;
        clientY = rect.top + rect.height / 2;
      } else if (w.globals.pointsArray && w.globals.pointsArray[i] && w.globals.pointsArray[i][j]) {
        const pt = w.globals.pointsArray[i][j];
        const elGrid = ttCtx.getElGrid && ttCtx.getElGrid();
        if (elGrid) {
          const gridRect = elGrid.getBoundingClientRect();
          clientX = gridRect.left + (pt[0] || 0);
          clientY = gridRect.top + (pt[1] || 0);
        }
      } else {
        const svgEl = w.dom.Paper && w.dom.Paper.node;
        if (svgEl) {
          const svgRect = svgEl.getBoundingClientRect();
          clientX = svgRect.left + svgRect.width / 2;
          clientY = svgRect.top + svgRect.height / 2;
        }
      }
      if (type === "line" || type === "area" || type === "rangeArea" || type === "scatter" || type === "bubble" || type === "radar") {
        if (w.globals.pointsArray && w.globals.pointsArray[i] && w.globals.pointsArray[i][j]) {
          const pt = w.globals.pointsArray[i][j];
          const elGrid = ttCtx.getElGrid && ttCtx.getElGrid();
          if (elGrid) {
            const gridRect = elGrid.getBoundingClientRect();
            clientX = gridRect.left + (pt[0] || 0);
            clientY = gridRect.top + (pt[1] || 0);
          }
        }
      }
      ttCtx.e = { type: "mousemove", clientX, clientY };
    }
    /**
     * bar / column / candlestick / boxPlot / rangeBar
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     */
    _showTooltipBar(i, j, ttCtx) {
      var _a, _b, _c, _d;
      const w = this.w;
      const shared = ttCtx.tConfig.shared && (ttCtx.tooltipUtil.isXoverlap(j) || w.globals.isBarHorizontal) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
      const rangeData = (
        /** @type {any} */
        (_d = (_c = (_b = (_a = w.rangeData.seriesRange) == null ? void 0 : _a[i]) == null ? void 0 : _b[j]) == null ? void 0 : _c.y) == null ? void 0 : _d[0]
      );
      ttCtx.tooltipLabels.drawSeriesTexts(__spreadProps(__spreadValues(__spreadValues({
        ttItems: ttCtx.ttItems,
        i,
        j
      }, (rangeData == null ? void 0 : rangeData.y1) !== void 0 && { y1: rangeData.y1 }), (rangeData == null ? void 0 : rangeData.y2) !== void 0 && { y2: rangeData.y2 }), {
        shared
      }));
      const parent = `.apexcharts-series[data\\:realIndex='${i}']`;
      const elPath = w.dom.Paper.findOne(
        `${parent} path[j='${j}'], ${parent} circle[j='${j}'], ${parent} rect[j='${j}']`
      );
      if (elPath) {
        this._leaveHoveredBar();
        const graphics = new Graphics(this.w, this.ctx);
        graphics.pathMouseEnter(elPath, null);
        this._hoveredBarEl = elPath;
      }
      if (w.globals.isBarHorizontal) {
        const barDomEl = elPath && elPath.node;
        if (barDomEl) {
          const wrapRect = w.dom.elWrap.getBoundingClientRect();
          const barRect = barDomEl.getBoundingClientRect();
          const barCx = barRect.left - wrapRect.left;
          const barCy = barRect.top - wrapRect.top;
          const bh = barRect.height;
          const bw = barRect.width;
          const ttWidth = ttCtx.tooltipRect.ttWidth || 0;
          const ttHeight = ttCtx.tooltipRect.ttHeight || 0;
          const y = barCy + bh / 2 - ttHeight / 2;
          let x = barCx + bw;
          const baselineX = ttCtx.xyRatios && ttCtx.xyRatios.baseLineInvertedY != null ? ttCtx.xyRatios.baseLineInvertedY : wrapRect.width / 2;
          if (barCx < baselineX) {
            x = barCx - ttWidth;
          }
          const tooltipEl = ttCtx.getElTooltip();
          if (tooltipEl) {
            tooltipEl.style.left = x + "px";
            tooltipEl.style.top = y + "px";
          }
        }
      } else {
        ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, i);
      }
    }
    /**
     * line / area / scatter / bubble / radar / rangeArea
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     */
    _showTooltipAxisLine(i, j, ttCtx) {
      const w = this.w;
      const type = w.config.chart.type;
      const sharedConfigured = ttCtx.tConfig.shared;
      const shared = sharedConfigured && ttCtx.tooltipUtil.isXoverlap(j) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: ttCtx.ttItems,
        i,
        j,
        shared
      });
      const isScatterLike = type === "scatter" || type === "bubble";
      const hasVisibleMarkers = w.globals.markers.largestSize > 0;
      if (isScatterLike) {
        this._showScatterBubblePoint(i, j, ttCtx);
      } else if (hasVisibleMarkers) {
        if (shared) {
          ttCtx.marker.enlargePoints(j);
        } else {
          ttCtx.tooltipPosition.moveDynamicPointOnHover(j, i);
        }
      } else if (shared) {
        ttCtx.tooltipPosition.moveDynamicPointsOnHover(j);
      } else {
        ttCtx.tooltipPosition.moveDynamicPointOnHover(j, i);
      }
    }
    /**
     * Scatter / bubble: find the specific marker element for (seriesIndex i,
     * dataPointIndex j), resize only that element, and position the tooltip at
     * its coordinates — mirroring what Position.moveMarkers does for mouse hover.
     *
     * Unlike enlargePoints(j) which queries ALL series for rel===j (causing
     * multiple bubbles to enlarge and tooltip to land on the wrong one), this
     * method queries by both series index AND data-point index for precision.
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     */
    _showScatterBubblePoint(i, j, ttCtx) {
      const baseEl = this.w.dom.baseEl;
      if (this._enlargedScatterMarker) {
        ttCtx.marker.oldPointSize(this._enlargedScatterMarker);
        this._enlargedScatterMarker = null;
      }
      const seriesEl = baseEl.querySelector(
        `.apexcharts-series[data\\:realIndex='${i}']`
      );
      if (!seriesEl) return;
      const markerEl = seriesEl.querySelector(`.apexcharts-marker[rel='${j}']`);
      if (!markerEl) return;
      ttCtx.marker.enlargeCurrentPoint(j, markerEl);
      this._enlargedScatterMarker = markerEl;
    }
    /**
     * pie / donut / polarArea
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     * @param {HTMLElement} tooltipEl
     */
    _showTooltipNonAxis(i, j, ttCtx, tooltipEl) {
      var _a, _b;
      const w = this.w;
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: ttCtx.ttItems,
        i: j,
        shared: false
      });
      const tooltipBound = tooltipEl.getBoundingClientRect();
      const ttWidth = tooltipBound.width || ttCtx.tooltipRect.ttWidth || 0;
      const ttHeight = tooltipBound.height || ttCtx.tooltipRect.ttHeight || 0;
      const sliceEl = w.dom.baseEl.querySelector(`.apexcharts-pie-area[j='${j}']`);
      if (sliceEl) {
        const cx = parseFloat((_a = sliceEl.getAttribute("data:cx")) != null ? _a : "");
        const cy = parseFloat((_b = sliceEl.getAttribute("data:cy")) != null ? _b : "");
        if (!isNaN(cx) && !isNaN(cy)) {
          const svgBound = w.dom.Paper.node.getBoundingClientRect();
          const wrapBound = w.dom.elWrap.getBoundingClientRect();
          const offsetX = svgBound.left - wrapBound.left;
          const offsetY = svgBound.top - wrapBound.top;
          tooltipEl.style.left = offsetX + cx - ttWidth / 2 + "px";
          tooltipEl.style.top = offsetY + cy - ttHeight - 10 + "px";
        }
      }
    }
    /**
     * radialBar — one ring per series, single value each
     * @param {number} i
     * @param {any} _j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     * @param {HTMLElement} tooltipEl
     */
    _showTooltipRadialBar(i, _j, ttCtx, tooltipEl) {
      var _a;
      const w = this.w;
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: ttCtx.ttItems,
        i,
        shared: false
      });
      const { ttWidth = 0, ttHeight = 0 } = ttCtx.getCachedDimensions();
      const arcEl = w.dom.baseEl.querySelector(
        `.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`
      );
      if (arcEl) {
        const angle = parseFloat((_a = arcEl.getAttribute("data:angle")) != null ? _a : "") || 0;
        const initialAngle = w.config.plotOptions.radialBar.startAngle || 0;
        const midAngle = initialAngle + angle / 2;
        const centerX = w.layout.gridWidth / 2;
        const centerY = w.layout.gridHeight / 2;
        const radialSize = w.globals.radialSize || Math.min(w.layout.gridWidth, w.layout.gridHeight) / 2;
        const seriesCount = w.seriesData.series.length;
        const trackSize = radialSize / Math.max(seriesCount, 1);
        const outerRadius = radialSize - i * trackSize;
        const innerRadius = outerRadius - trackSize;
        const ringRadius = (outerRadius + innerRadius) / 2;
        const centroid = Utils$1.polarToCartesian(
          centerX,
          centerY,
          ringRadius,
          midAngle
        );
        const x = centroid.x + (w.layout.translateX || 0);
        const y = centroid.y + (w.layout.translateY || 0);
        tooltipEl.style.left = x - ttWidth / 2 + "px";
        tooltipEl.style.top = y - ttHeight - 10 + "px";
      }
    }
    /**
     * heatmap / treemap — position tooltip using element bounding rect
     * @param {number} i
     * @param {number} j
     * @param {import('../tooltip/Tooltip').default} ttCtx
     * @param {HTMLElement} tooltipEl
     * @param {string} type
     */
    _showTooltipHeatTree(i, j, ttCtx, tooltipEl, type) {
      var _a, _b;
      const w = this.w;
      ttCtx.tooltipLabels.drawSeriesTexts({
        ttItems: ttCtx.ttItems,
        i,
        j,
        shared: false
      });
      const tooltipRect = tooltipEl.getBoundingClientRect();
      const ttWidth = tooltipRect.width || ttCtx.tooltipRect.ttWidth || 0;
      const ttHeight = tooltipRect.height || ttCtx.tooltipRect.ttHeight || 0;
      const rectClass = type === "heatmap" ? "apexcharts-heatmap-rect" : "apexcharts-treemap-rect";
      const cell = w.dom.baseEl.querySelector(`.${rectClass}[i='${i}'][j='${j}']`);
      if (cell) {
        const wrapRect = w.dom.elWrap.getBoundingClientRect();
        const cellRect = cell.getBoundingClientRect();
        const cellCx = cellRect.left - wrapRect.left;
        const cellCy = cellRect.top - wrapRect.top;
        const cellWidth = cellRect.width;
        const cellHeight = cellRect.height;
        const cx = parseFloat((_a = cell.getAttribute("cx")) != null ? _a : "");
        const cellWidthAttr = parseFloat((_b = cell.getAttribute("width")) != null ? _b : "");
        ttCtx.tooltipPosition.moveXCrosshairs(cx + cellWidthAttr / 2);
        let x = cellCx + cellWidth + ttWidth / 2;
        const y = cellCy + cellHeight / 2 - ttHeight / 2;
        if (cellCx + cellWidth > w.layout.gridWidth / 2) {
          x = cellCx - ttWidth / 2;
        }
        tooltipEl.style.left = x + "px";
        tooltipEl.style.top = y + "px";
      }
    }
    // ─── Focus class management ───────────────────────────────────────────────
    /**
     * @param {number} i
     * @param {number} j
     */
    _applyFocusClass(i, j) {
      this._removeFocusClass();
      const el = this._getFocusableElement(i, j);
      if (el) {
        el.classList.add("apexcharts-keyboard-focused");
        this._focusedEl = el;
      }
    }
    _removeFocusClass() {
      if (this._focusedEl) {
        this._focusedEl.classList.remove("apexcharts-keyboard-focused");
        this._focusedEl = null;
      }
    }
    _leaveHoveredBar() {
      if (this._hoveredBarEl) {
        const graphics = new Graphics(this.w, this.ctx);
        graphics.pathMouseLeave(this._hoveredBarEl, null);
        this._hoveredBarEl = null;
      }
    }
    /**
     * @param {number} i
     * @param {number} j
     */
    _getFocusableElement(i, j) {
      const w = this.w;
      const type = w.config.chart.type;
      const baseEl = w.dom.baseEl;
      if (type === "pie" || type === "donut" || type === "polarArea") {
        return baseEl.querySelector(`.apexcharts-pie-area[j='${j}']`);
      }
      if (type === "heatmap") {
        return baseEl.querySelector(
          `.apexcharts-heatmap-rect[i='${i}'][j='${j}']`
        );
      }
      if (type === "treemap") {
        return baseEl.querySelector(
          `.apexcharts-treemap-rect[i='${i}'][j='${j}']`
        );
      }
      if (type === "radialBar") {
        return baseEl.querySelector(
          `.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`
        );
      }
      if (type === "bar" || type === "candlestick" || type === "boxPlot" || type === "rangeBar") {
        return baseEl.querySelector(
          `.apexcharts-series[data\\:realIndex='${i}'] path[j='${j}']`
        );
      }
      const marker = baseEl.querySelector(
        `.apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker[rel='${j}']`
      );
      return marker || null;
    }
    // ─── Click / Enter ────────────────────────────────────────────────────────
    _fireClick() {
      const w = this.w;
      const ttCtx = w.globals.tooltip;
      if (!ttCtx) return;
      const syntheticEvent = {
        type: "mouseup",
        clientX: 0,
        clientY: 0
      };
      ttCtx.markerClick(syntheticEvent, this.seriesIndex, this.dataPointIndex);
    }
    // ─── Helpers ──────────────────────────────────────────────────────────────
    _isNavEnabled() {
      const a11y = this.w.config.chart.accessibility;
      return a11y.enabled && a11y.keyboard.enabled && a11y.keyboard.navigation.enabled;
    }
    _getSeriesCount() {
      const w = this.w;
      const type = w.config.chart.type;
      if (type === "pie" || type === "donut" || type === "polarArea") {
        return 1;
      }
      return w.seriesData.series.length;
    }
    /**
     * @param {number} si
     */
    _getDataPointCount(si) {
      const w = this.w;
      const type = w.config.chart.type;
      if (type === "pie" || type === "donut" || type === "polarArea") {
        return w.seriesData.series.length;
      }
      const series = w.seriesData.series;
      return series[si] && Array.isArray(series[si]) ? series[si].length : 0;
    }
    _clampCursor() {
      const seriesCount = this._getSeriesCount();
      if (this.seriesIndex >= seriesCount) this.seriesIndex = seriesCount - 1;
      if (this.seriesIndex < 0) this.seriesIndex = 0;
      const dpCount = this._getDataPointCount(this.seriesIndex);
      if (this.dataPointIndex >= dpCount) this.dataPointIndex = dpCount - 1;
      if (this.dataPointIndex < 0) this.dataPointIndex = 0;
    }
    /**
     * When the chart is zoomed in, the current dataPointIndex may point to a
     * data point that is outside the visible viewport. Snap the cursor to the
     * first data point whose x-value falls within [minX, maxX].
     *
     * Only adjusts when w.seriesData.seriesX is populated (numeric/datetime axes).
     * Category-only charts (seriesX entries are strings or auto-indices) are
     * unaffected — all points are always visible.
     */
    _snapToVisibleRange() {
      const w = this.w;
      const gl = w.globals;
      const si = this.seriesIndex;
      if (!w.interact.zoomed) return;
      const seriesX = w.seriesData.seriesX && w.seriesData.seriesX[si];
      if (!seriesX || !seriesX.length) return;
      const minX = gl.minX;
      const maxX = gl.maxX;
      if (minX === void 0 || maxX === void 0) return;
      const currentX = seriesX[this.dataPointIndex];
      if (currentX >= minX && currentX <= maxX) return;
      const dpCount = seriesX.length;
      for (let di = 0; di < dpCount; di++) {
        if (seriesX[di] >= minX && seriesX[di] <= maxX) {
          this.dataPointIndex = di;
          return;
        }
      }
    }
    /**
     * Snap to the nearest visible data point in the given navigation direction.
     * direction > 0 → find the first visible point (left boundary of zoomed range)
     * direction < 0 → find the last visible point (right boundary of zoomed range)
     * @param {number} direction
     */
    _snapToVisibleRangeInDirection(direction) {
      const w = this.w;
      const gl = w.globals;
      const si = this.seriesIndex;
      const seriesX = w.seriesData.seriesX && w.seriesData.seriesX[si];
      if (!seriesX || !seriesX.length) return;
      const minX = gl.minX;
      const maxX = gl.maxX;
      if (minX === void 0 || maxX === void 0) return;
      const dpCount = seriesX.length;
      if (direction >= 0) {
        for (let di = 0; di < dpCount; di++) {
          if (seriesX[di] >= minX && seriesX[di] <= maxX) {
            this.dataPointIndex = di;
            return;
          }
        }
      } else {
        for (let di = dpCount - 1; di >= 0; di--) {
          if (seriesX[di] >= minX && seriesX[di] <= maxX) {
            this.dataPointIndex = di;
            return;
          }
        }
      }
    }
    /**
     * Check whether the data point at (si, di) is within the current visible
     * x-axis range. Used to skip out-of-viewport points during keyboard nav.
     * @param {number} si
     * @param {number} di
     */
    _isDataPointVisible(si, di) {
      const w = this.w;
      const gl = w.globals;
      if (!w.interact.zoomed) return true;
      const seriesX = w.seriesData.seriesX && w.seriesData.seriesX[si];
      if (!seriesX) return true;
      const x = seriesX[di];
      if (x === void 0) return true;
      return x >= gl.minX && x <= gl.maxX;
    }
  }
  ApexCharts.registerFeatures({ keyboardNavigation: KeyboardNavigation });
  class BarDataLabels {
    /**
     * @param {import('../../../charts/Bar').default} barCtx
     */
    constructor(barCtx) {
      this.w = barCtx.w;
      this.barCtx = barCtx;
      this.totalFormatter = this.w.config.plotOptions.bar.dataLabels.total.formatter;
      if (!this.totalFormatter) {
        this.totalFormatter = this.w.config.dataLabels.formatter;
      }
    }
    /** handleBarDataLabels is used to calculate the positions for the data-labels
     * It also sets the element's data attr for bars and calls drawCalculatedBarDataLabels()
     * After calculating, it also calls the function to draw data labels
     * @memberof Bar
     * @param {Record<string, any>} opts - bar properties used throughout the bar drawing function
     * @return {object} dataLabels node-element which you can append later
     **/
    handleBarDataLabels(opts) {
      const {
        x,
        y,
        y1,
        y2,
        i,
        j,
        realIndex,
        columnGroupIndex,
        series,
        barHeight,
        barWidth,
        barXPosition,
        barYPosition,
        visibleSeries
      } = opts;
      const w = this.w;
      const graphics = new Graphics(this.barCtx.w);
      const strokeWidth = Array.isArray(this.barCtx.strokeWidth) ? this.barCtx.strokeWidth[realIndex] : this.barCtx.strokeWidth;
      let bcx;
      let bcy;
      if (w.axisFlags.isXNumeric && !w.globals.isBarHorizontal) {
        bcx = x + barWidth * (visibleSeries + 1);
        bcy = y + barHeight * (visibleSeries + 1) - strokeWidth;
      } else {
        bcx = x + barWidth * visibleSeries;
        bcy = y + barHeight * visibleSeries;
      }
      let dataLabels = null;
      let totalDataLabels = null;
      let dataLabelsX = x;
      let dataLabelsY = y;
      let dataLabelsPos = (
        /** @type {any} */
        {}
      );
      const dataLabelsConfig = w.config.dataLabels;
      const barDataLabelsConfig = this.barCtx.barOptions.dataLabels;
      const barTotalDataLabelsConfig = this.barCtx.barOptions.dataLabels.total;
      if (typeof barYPosition !== "undefined" && this.barCtx.isRangeBar) {
        bcy = barYPosition;
        dataLabelsY = barYPosition;
      }
      if (typeof barXPosition !== "undefined" && this.barCtx.isVerticalGroupedRangeBar) {
        bcx = barXPosition;
        dataLabelsX = barXPosition;
      }
      const offX = dataLabelsConfig.offsetX;
      const offY = dataLabelsConfig.offsetY;
      let textRects = {
        width: 0,
        height: 0
      };
      if (w.config.dataLabels.enabled) {
        const yLabel = w.seriesData.series[i][j];
        textRects = graphics.getTextRects(
          w.config.dataLabels.formatter ? w.config.dataLabels.formatter(yLabel, __spreadProps(__spreadValues({}, w), {
            seriesIndex: i,
            dataPointIndex: j,
            w
          })) : w.formatters.yLabelFormatters[0](yLabel),
          parseFloat(dataLabelsConfig.style.fontSize).toString()
        );
      }
      const params = {
        x,
        y,
        i,
        j,
        realIndex,
        columnGroupIndex,
        bcx,
        bcy,
        barHeight,
        barWidth,
        textRects,
        strokeWidth,
        dataLabelsX,
        dataLabelsY,
        dataLabelsConfig,
        barDataLabelsConfig,
        barTotalDataLabelsConfig,
        offX,
        offY
      };
      if (this.barCtx.isHorizontal) {
        dataLabelsPos = this.calculateBarsDataLabelsPosition(params);
      } else {
        dataLabelsPos = this.calculateColumnsDataLabelsPosition(params);
      }
      dataLabels = this.drawCalculatedDataLabels({
        x: dataLabelsPos.dataLabelsX,
        y: dataLabelsPos.dataLabelsY,
        val: this.barCtx.isRangeBar ? [y1, y2] : w.config.chart.stackType === "100%" ? series[realIndex][j] : w.seriesData.series[realIndex][j],
        i: realIndex,
        j,
        barWidth,
        barHeight,
        textRects,
        dataLabelsConfig
      });
      if (w.config.chart.stacked && barTotalDataLabelsConfig.enabled) {
        totalDataLabels = this.drawTotalDataLabels({
          x: dataLabelsPos.totalDataLabelsX,
          y: dataLabelsPos.totalDataLabelsY,
          barWidth,
          barHeight,
          realIndex,
          textAnchor: dataLabelsPos.totalDataLabelsAnchor,
          val: this.getStackedTotalDataLabel({ realIndex, j }),
          dataLabelsConfig,
          barTotalDataLabelsConfig
        });
      }
      return {
        dataLabelsPos,
        dataLabels,
        totalDataLabels
      };
    }
    /** @param {{realIndex: any, j: any}} opts */
    getStackedTotalDataLabel({ realIndex, j }) {
      const w = this.w;
      let val = this.barCtx.stackedSeriesTotals[j];
      if (this.totalFormatter) {
        val = this.totalFormatter(val, __spreadProps(__spreadValues({}, w), {
          seriesIndex: realIndex,
          dataPointIndex: j,
          w
        }));
      }
      return val;
    }
    /**
     * @param {Record<string, any>} opts
     */
    calculateColumnsDataLabelsPosition(opts) {
      const w = this.w;
      let {
        i,
        j,
        realIndex,
        y,
        bcx,
        barWidth,
        barHeight,
        textRects,
        dataLabelsX,
        dataLabelsY,
        dataLabelsConfig,
        barDataLabelsConfig,
        barTotalDataLabelsConfig,
        strokeWidth,
        offX,
        offY
      } = opts;
      let totalDataLabelsY;
      let totalDataLabelsX;
      const totalDataLabelsAnchor = "middle";
      const totalDataLabelsBcx = bcx;
      barHeight = Math.abs(barHeight);
      const vertical = w.config.plotOptions.bar.dataLabels.orientation === "vertical";
      const { zeroEncounters } = this.barCtx.barHelpers.getZeroValueEncounters({
        i,
        j
      });
      bcx = bcx - strokeWidth / 2;
      const dataPointsDividedWidth = w.layout.gridWidth / w.globals.dataPoints;
      if (this.barCtx.isVerticalGroupedRangeBar) {
        dataLabelsX += barWidth / 2;
      } else {
        if (w.axisFlags.isXNumeric) {
          dataLabelsX = bcx - barWidth / 2 + offX;
        } else {
          dataLabelsX = bcx - dataPointsDividedWidth + barWidth / 2 + offX;
        }
        if (!w.config.chart.stacked && zeroEncounters > 0 && w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
          dataLabelsX -= barWidth * zeroEncounters;
        }
      }
      if (vertical) {
        const offsetDLX = 2;
        dataLabelsX = dataLabelsX + textRects.height / 2 - strokeWidth / 2 - offsetDLX;
      }
      const valIsNegative = w.seriesData.series[i][j] < 0;
      let newY = y;
      if (this.barCtx.isReversed) {
        newY = y + (valIsNegative ? barHeight : -barHeight);
      }
      switch (barDataLabelsConfig.position) {
        case "center":
          if (vertical) {
            if (valIsNegative) {
              dataLabelsY = newY - barHeight / 2 + offY;
            } else {
              dataLabelsY = newY + barHeight / 2 - offY;
            }
          } else {
            if (valIsNegative) {
              dataLabelsY = newY - barHeight / 2 + textRects.height / 2 + offY;
            } else {
              dataLabelsY = newY + barHeight / 2 + textRects.height / 2 - offY;
            }
          }
          break;
        case "bottom":
          if (vertical) {
            if (valIsNegative) {
              dataLabelsY = newY - barHeight + offY;
            } else {
              dataLabelsY = newY + barHeight - offY;
            }
          } else {
            if (valIsNegative) {
              dataLabelsY = newY - barHeight + textRects.height + strokeWidth + offY;
            } else {
              dataLabelsY = newY + barHeight - textRects.height / 2 + strokeWidth - offY;
            }
          }
          break;
        case "top":
          if (vertical) {
            if (valIsNegative) {
              dataLabelsY = newY + offY;
            } else {
              dataLabelsY = newY - offY;
            }
          } else {
            if (valIsNegative) {
              dataLabelsY = newY - textRects.height / 2 - offY;
            } else {
              dataLabelsY = newY + textRects.height + offY;
            }
          }
          break;
      }
      let lowestPrevY = newY;
      w.labelData.seriesGroups.forEach((sg) => {
        var _a;
        (_a = this.barCtx[sg.join(",")]) == null ? void 0 : _a.prevY.forEach(
          (arr) => {
            if (valIsNegative) {
              lowestPrevY = Math.max(arr[j], lowestPrevY);
            } else {
              lowestPrevY = Math.min(arr[j], lowestPrevY);
            }
          }
        );
      });
      if (this.barCtx.lastActiveBarSerieIndex === realIndex && barTotalDataLabelsConfig.enabled) {
        const ADDITIONAL_OFFY = 18;
        const graphics = new Graphics(this.barCtx.w);
        const totalLabeltextRects = graphics.getTextRects(
          this.getStackedTotalDataLabel({ realIndex, j }),
          dataLabelsConfig.fontSize
        );
        if (valIsNegative) {
          totalDataLabelsY = lowestPrevY - totalLabeltextRects.height / 2 - offY - barTotalDataLabelsConfig.offsetY + ADDITIONAL_OFFY;
        } else {
          totalDataLabelsY = lowestPrevY + totalLabeltextRects.height + offY + barTotalDataLabelsConfig.offsetY - ADDITIONAL_OFFY;
        }
        const xDivision = dataPointsDividedWidth;
        totalDataLabelsX = totalDataLabelsBcx + (w.axisFlags.isXNumeric ? -barWidth * w.globals.barGroups.length / 2 : w.globals.barGroups.length * barWidth / 2 - (w.globals.barGroups.length - 1) * barWidth - xDivision) + barTotalDataLabelsConfig.offsetX;
      }
      if (!w.config.chart.stacked) {
        if (dataLabelsY < 0) {
          dataLabelsY = 0 + strokeWidth;
        } else if (dataLabelsY + textRects.height / 3 > w.layout.gridHeight) {
          dataLabelsY = w.layout.gridHeight - strokeWidth;
        }
      }
      return {
        bcx,
        bcy: y,
        dataLabelsX,
        dataLabelsY,
        totalDataLabelsX,
        totalDataLabelsY,
        totalDataLabelsAnchor
      };
    }
    /**
     * @param {Record<string, any>} opts
     */
    calculateBarsDataLabelsPosition(opts) {
      const w = this.w;
      let {
        x,
        i,
        j,
        realIndex,
        bcy,
        barHeight,
        barWidth,
        textRects,
        dataLabelsX,
        strokeWidth,
        dataLabelsConfig,
        barDataLabelsConfig,
        barTotalDataLabelsConfig,
        offX,
        offY
      } = opts;
      const dataPointsDividedHeight = w.layout.gridHeight / w.globals.dataPoints;
      const { zeroEncounters } = this.barCtx.barHelpers.getZeroValueEncounters({
        i,
        j
      });
      barWidth = Math.abs(barWidth);
      let dataLabelsY = bcy - (this.barCtx.isRangeBar ? 0 : dataPointsDividedHeight) + barHeight / 2 + textRects.height / 2 + offY - 3;
      if (!w.config.chart.stacked && zeroEncounters > 0 && w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
        dataLabelsY -= barHeight * zeroEncounters;
      }
      let totalDataLabelsX;
      let totalDataLabelsY;
      let totalDataLabelsAnchor = "start";
      const valIsNegative = w.seriesData.series[i][j] < 0;
      let newX = x;
      if (this.barCtx.isReversed) {
        newX = x + (valIsNegative ? -barWidth : barWidth);
        totalDataLabelsAnchor = valIsNegative ? "start" : "end";
      }
      switch (barDataLabelsConfig.position) {
        case "center":
          if (valIsNegative) {
            dataLabelsX = newX + barWidth / 2 - offX;
          } else {
            dataLabelsX = Math.max(textRects.width / 2, newX - barWidth / 2) + offX;
          }
          break;
        case "bottom":
          if (valIsNegative) {
            dataLabelsX = newX + barWidth - strokeWidth - offX;
          } else {
            dataLabelsX = newX - barWidth + strokeWidth + offX;
          }
          break;
        case "top":
          if (valIsNegative) {
            dataLabelsX = newX - strokeWidth - offX;
          } else {
            dataLabelsX = newX - strokeWidth + offX;
          }
          break;
      }
      let lowestPrevX = newX;
      w.labelData.seriesGroups.forEach((sg) => {
        var _a;
        (_a = this.barCtx[sg.join(",")]) == null ? void 0 : _a.prevX.forEach(
          (arr) => {
            if (valIsNegative) {
              lowestPrevX = Math.min(arr[j], lowestPrevX);
            } else {
              lowestPrevX = Math.max(arr[j], lowestPrevX);
            }
          }
        );
      });
      if (this.barCtx.lastActiveBarSerieIndex === realIndex && barTotalDataLabelsConfig.enabled) {
        const graphics = new Graphics(this.barCtx.w);
        const totalLabeltextRects = graphics.getTextRects(
          this.getStackedTotalDataLabel({ realIndex, j }),
          dataLabelsConfig.fontSize
        );
        if (valIsNegative) {
          totalDataLabelsX = lowestPrevX - strokeWidth - offX - barTotalDataLabelsConfig.offsetX;
          totalDataLabelsAnchor = "end";
        } else {
          totalDataLabelsX = lowestPrevX + offX + barTotalDataLabelsConfig.offsetX + (this.barCtx.isReversed ? -(barWidth + strokeWidth) : strokeWidth);
        }
        totalDataLabelsY = dataLabelsY - textRects.height / 2 + totalLabeltextRects.height / 2 + barTotalDataLabelsConfig.offsetY + strokeWidth;
        if (w.globals.barGroups.length > 1) {
          totalDataLabelsY = totalDataLabelsY - w.globals.barGroups.length / 2 * (barHeight / 2);
        }
      }
      if (!w.config.chart.stacked) {
        if (dataLabelsConfig.textAnchor === "start") {
          if (dataLabelsX - textRects.width < 0) {
            dataLabelsX = valIsNegative ? textRects.width + strokeWidth : strokeWidth;
          } else if (dataLabelsX + textRects.width > w.layout.gridWidth) {
            dataLabelsX = valIsNegative ? w.layout.gridWidth - strokeWidth : w.layout.gridWidth - textRects.width - strokeWidth;
          }
        } else if (dataLabelsConfig.textAnchor === "middle") {
          if (dataLabelsX - textRects.width / 2 < 0) {
            dataLabelsX = textRects.width / 2 + strokeWidth;
          } else if (dataLabelsX + textRects.width / 2 > w.layout.gridWidth) {
            dataLabelsX = w.layout.gridWidth - textRects.width / 2 - strokeWidth;
          }
        } else if (dataLabelsConfig.textAnchor === "end") {
          if (dataLabelsX < 1) {
            dataLabelsX = textRects.width + strokeWidth;
          } else if (dataLabelsX + 1 > w.layout.gridWidth) {
            dataLabelsX = w.layout.gridWidth - textRects.width - strokeWidth;
          }
        }
      }
      return {
        bcx: x,
        bcy,
        dataLabelsX,
        dataLabelsY,
        totalDataLabelsX,
        totalDataLabelsY,
        totalDataLabelsAnchor
      };
    }
    /** @param {{x: any, y: any, val: any, i: any, j: any, textRects: any, barHeight: any, barWidth: any, dataLabelsConfig: any}} opts */
    drawCalculatedDataLabels({
      x,
      y,
      val,
      i,
      // = realIndex
      j,
      textRects,
      barHeight,
      barWidth,
      dataLabelsConfig
    }) {
      const w = this.w;
      let rotate = "rotate(0)";
      if (w.config.plotOptions.bar.dataLabels.orientation === "vertical")
        rotate = `rotate(-90, ${x}, ${y})`;
      const dataLabels = new DataLabels(this.barCtx.w, this.barCtx.ctx);
      const graphics = new Graphics(this.barCtx.w);
      const formatter = dataLabelsConfig.formatter;
      let elDataLabelsWrap = null;
      const isSeriesNotCollapsed = w.globals.collapsedSeriesIndices.indexOf(i) > -1;
      if (dataLabelsConfig.enabled && !isSeriesNotCollapsed) {
        elDataLabelsWrap = graphics.group({
          class: "apexcharts-data-labels",
          transform: rotate
        });
        let text = "";
        if (typeof val !== "undefined") {
          text = formatter(val, __spreadProps(__spreadValues({}, w), {
            seriesIndex: i,
            dataPointIndex: j,
            w
          }));
        }
        if (!val && w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
          text = "";
        }
        const valIsNegative = w.seriesData.series[i][j] < 0;
        const position = w.config.plotOptions.bar.dataLabels.position;
        if (w.config.plotOptions.bar.dataLabels.orientation === "vertical") {
          if (position === "top") {
            if (valIsNegative) dataLabelsConfig.textAnchor = "end";
            else dataLabelsConfig.textAnchor = "start";
          }
          if (position === "center") {
            dataLabelsConfig.textAnchor = "middle";
          }
          if (position === "bottom") {
            if (valIsNegative) dataLabelsConfig.textAnchor = "end";
            else dataLabelsConfig.textAnchor = "start";
          }
        }
        if (this.barCtx.isRangeBar && this.barCtx.barOptions.dataLabels.hideOverflowingLabels) {
          const txRect = graphics.getTextRects(
            text,
            parseFloat(dataLabelsConfig.style.fontSize).toString()
          );
          if (barWidth < txRect.width) {
            text = "";
          }
        }
        if (w.config.chart.stacked && this.barCtx.barOptions.dataLabels.hideOverflowingLabels) {
          if (this.barCtx.isHorizontal) {
            if (textRects.width / 1.6 > Math.abs(barWidth)) {
              text = "";
            }
          } else {
            if (textRects.height / 1.6 > Math.abs(barHeight)) {
              text = "";
            }
          }
        }
        const modifiedDataLabelsConfig = __spreadValues({}, dataLabelsConfig);
        if (this.barCtx.isHorizontal) {
          if (val < 0) {
            if (dataLabelsConfig.textAnchor === "start") {
              modifiedDataLabelsConfig.textAnchor = "end";
            } else if (dataLabelsConfig.textAnchor === "end") {
              modifiedDataLabelsConfig.textAnchor = "start";
            }
          }
        }
        dataLabels.plotDataLabelsText({
          x,
          y,
          text,
          i,
          j,
          parent: elDataLabelsWrap,
          dataLabelsConfig: modifiedDataLabelsConfig,
          alwaysDrawDataLabel: true,
          offsetCorrection: true
        });
      }
      return elDataLabelsWrap;
    }
    /** @param {{ x?: any, y?: any, val?: any, realIndex?: any, textAnchor?: any, barWidth?: any, barHeight?: any, dataLabelsConfig?: any, barTotalDataLabelsConfig?: any }} opts */
    drawTotalDataLabels({
      x,
      y,
      val,
      realIndex,
      textAnchor,
      barTotalDataLabelsConfig
    }) {
      const graphics = new Graphics(this.barCtx.w);
      let totalDataLabelText;
      if (barTotalDataLabelsConfig.enabled && typeof x !== "undefined" && typeof y !== "undefined" && this.barCtx.lastActiveBarSerieIndex === realIndex) {
        totalDataLabelText = graphics.drawText({
          x,
          y,
          foreColor: barTotalDataLabelsConfig.style.color,
          text: val,
          textAnchor,
          fontFamily: barTotalDataLabelsConfig.style.fontFamily,
          fontSize: barTotalDataLabelsConfig.style.fontSize,
          fontWeight: barTotalDataLabelsConfig.style.fontWeight
        });
      }
      return totalDataLabelText;
    }
  }
  let Helpers$1 = class Helpers {
    /**
     * @param {Record<string, any>} barCtx
     */
    constructor(barCtx) {
      this.w = barCtx.w;
      this.barCtx = barCtx;
    }
    /**
     * @param {any[]} series
     */
    initVariables(series) {
      const w = this.w;
      this.barCtx.series = series;
      this.barCtx.totalItems = 0;
      this.barCtx.seriesLen = 0;
      this.barCtx.visibleI = -1;
      this.barCtx.visibleItems = 1;
      for (let sl = 0; sl < series.length; sl++) {
        if (series[sl].length > 0) {
          this.barCtx.seriesLen = this.barCtx.seriesLen + 1;
          this.barCtx.totalItems += series[sl].length;
        }
        if (w.axisFlags.isXNumeric) {
          for (let j = 0; j < series[sl].length; j++) {
            if (w.seriesData.seriesX[sl][j] > w.globals.minX && w.seriesData.seriesX[sl][j] < w.globals.maxX) {
              this.barCtx.visibleItems++;
            }
          }
        } else {
          this.barCtx.visibleItems = w.globals.dataPoints;
        }
      }
      this.arrBorderRadius = this.createBorderRadiusArr(w.seriesData.series);
      if (Utils$1.isSafari()) {
        this.arrBorderRadius = this.arrBorderRadius.map(
          (brArr) => (
            /**
             * @param {any} _
             */
            brArr.map((_) => "none")
          )
        );
      }
      if (this.barCtx.seriesLen === 0) {
        this.barCtx.seriesLen = 1;
      }
      this.barCtx.zeroSerieses = [];
      if (!w.globals.comboCharts) {
        this.checkZeroSeries({ series });
      }
    }
    /**
     * @param {number} realIndex
     */
    initialPositions(realIndex) {
      const w = this.w;
      let x, y, yDivision, xDivision, barHeight, barWidth, zeroH, zeroW;
      let dataPoints = w.globals.dataPoints;
      if (this.barCtx.isRangeBar) {
        dataPoints = w.labelData.labels.length;
      }
      let seriesLen = this.barCtx.seriesLen;
      if (w.config.plotOptions.bar.rangeBarGroupRows) {
        seriesLen = 1;
      }
      if (this.barCtx.isHorizontal) {
        yDivision = w.layout.gridHeight / dataPoints;
        barHeight = yDivision / seriesLen;
        if (w.axisFlags.isXNumeric) {
          yDivision = w.layout.gridHeight / this.barCtx.totalItems;
          barHeight = yDivision / this.barCtx.seriesLen;
        }
        barHeight = barHeight * parseInt(this.barCtx.barOptions.barHeight, 10) / 100;
        if (String(this.barCtx.barOptions.barHeight).indexOf("%") === -1) {
          barHeight = parseInt(this.barCtx.barOptions.barHeight, 10);
        }
        zeroW = this.barCtx.baseLineInvertedY + w.globals.padHorizontal + (this.barCtx.isReversed ? w.layout.gridWidth : 0) - (this.barCtx.isReversed ? this.barCtx.baseLineInvertedY * 2 : 0);
        if (this.barCtx.isFunnel) {
          zeroW = w.layout.gridWidth / 2;
        }
        y = (yDivision - barHeight * this.barCtx.seriesLen) / 2;
      } else {
        xDivision = w.layout.gridWidth / this.barCtx.visibleItems;
        if (w.config.xaxis.convertedCatToNumeric) {
          xDivision = w.layout.gridWidth / w.globals.dataPoints;
        }
        barWidth = xDivision / seriesLen * parseInt(this.barCtx.barOptions.columnWidth, 10) / 100;
        if (w.axisFlags.isXNumeric) {
          const xRatio = this.barCtx.xRatio;
          if (w.globals.minXDiff && w.globals.minXDiff !== 0.5 && w.globals.minXDiff / xRatio > 0) {
            xDivision = w.globals.minXDiff / xRatio;
          }
          barWidth = xDivision / seriesLen * parseInt(this.barCtx.barOptions.columnWidth, 10) / 100;
          if (barWidth < 1) {
            barWidth = 1;
          }
        }
        if (String(this.barCtx.barOptions.columnWidth).indexOf("%") === -1) {
          barWidth = parseInt(this.barCtx.barOptions.columnWidth, 10);
        }
        zeroH = w.layout.gridHeight - this.barCtx.baseLineY[this.barCtx.translationsIndex] - (this.barCtx.isReversed ? w.layout.gridHeight : 0) + (this.barCtx.isReversed ? this.barCtx.baseLineY[this.barCtx.translationsIndex] * 2 : 0);
        if (w.axisFlags.isXNumeric) {
          const xForNumericX = this.barCtx.getBarXForNumericXAxis({
            x,
            j: 0,
            realIndex,
            barWidth
          });
          x = xForNumericX.x;
        } else {
          x = w.globals.padHorizontal + Utils$1.noExponents(xDivision - barWidth * this.barCtx.seriesLen) / 2;
        }
      }
      w.globals.barHeight = barHeight;
      w.globals.barWidth = barWidth;
      return {
        x,
        y,
        yDivision,
        xDivision,
        barHeight,
        barWidth,
        zeroH,
        zeroW
      };
    }
    /**
     * @param {Record<string, any>} ctx
     */
    initializeStackedPrevVars(ctx) {
      const w = ctx.w;
      w.labelData.seriesGroups.forEach((group) => {
        if (!ctx[group]) ctx[group] = {};
        ctx[group].prevY = [];
        ctx[group].prevX = [];
        ctx[group].prevYF = [];
        ctx[group].prevXF = [];
        ctx[group].prevYVal = [];
        ctx[group].prevXVal = [];
      });
    }
    /**
     * @param {Record<string, any>} ctx
     */
    initializeStackedXYVars(ctx) {
      const w = ctx.w;
      w.labelData.seriesGroups.forEach((group) => {
        if (!ctx[group]) ctx[group] = {};
        ctx[group].xArrj = [];
        ctx[group].xArrjF = [];
        ctx[group].xArrjVal = [];
        ctx[group].yArrj = [];
        ctx[group].yArrjF = [];
        ctx[group].yArrjVal = [];
      });
    }
    /**
     * @param {any[]} series
     * @param {number} i
     * @param {number} j
     * @param {number} realIndex
     */
    getPathFillColor(series, i, j, realIndex) {
      var _a, _b, _c, _d;
      const w = this.w;
      const fill = new Fill(this.barCtx.w);
      let fillColor = null;
      const seriesNumber = this.barCtx.barOptions.distributed ? j : i;
      let useRangeColor = false;
      if (this.barCtx.barOptions.colors.ranges.length > 0) {
        const colorRange = this.barCtx.barOptions.colors.ranges;
        colorRange.map((range) => {
          if (series[i][j] >= range.from && series[i][j] <= range.to) {
            fillColor = range.color;
            useRangeColor = true;
          }
        });
      }
      const pathFill = fill.fillPath({
        seriesNumber: this.barCtx.barOptions.distributed ? seriesNumber : realIndex,
        dataPointIndex: j,
        color: fillColor,
        value: series[i][j],
        fillConfig: (_a = w.config.series[i].data[j]) == null ? void 0 : _a.fill,
        fillType: ((_c = (_b = w.config.series[i].data[j]) == null ? void 0 : _b.fill) == null ? void 0 : _c.type) ? (_d = w.config.series[i].data[j]) == null ? void 0 : _d.fill.type : Array.isArray(w.config.fill.type) ? w.config.fill.type[realIndex] : w.config.fill.type
      });
      return {
        color: pathFill,
        useRangeColor
      };
    }
    /**
     * @param {number} i
     * @param {number} j
     * @param {number} realIndex
     */
    getStrokeWidth(i, j, realIndex) {
      let strokeWidth = 0;
      const w = this.w;
      if (typeof this.barCtx.series[i][j] === "undefined" || this.barCtx.series[i][j] === null || w.config.chart.type === "bar" && !this.barCtx.series[i][j]) {
        this.barCtx.isNullValue = true;
      } else {
        this.barCtx.isNullValue = false;
      }
      if (w.config.stroke.show) {
        if (!this.barCtx.isNullValue) {
          strokeWidth = Array.isArray(this.barCtx.strokeWidth) ? this.barCtx.strokeWidth[realIndex] : this.barCtx.strokeWidth;
        }
      }
      return strokeWidth;
    }
    /**
     * @param {any[]} series
     */
    createBorderRadiusArr(series) {
      var _a;
      const w = this.w;
      const alwaysApplyRadius = !this.w.config.chart.stacked || w.config.plotOptions.bar.borderRadius <= 0;
      const numSeries = series.length;
      const numColumns = ((_a = series[0]) == null ? void 0 : _a.length) | 0;
      const output = Array.from(
        { length: numSeries },
        () => Array(numColumns).fill(alwaysApplyRadius ? "top" : "none")
      );
      if (alwaysApplyRadius) return output;
      const chartType = this.w.config.chart.type;
      for (let j = 0; j < numColumns; j++) {
        const positiveIndices = [];
        const negativeIndices = [];
        let nonZeroCount = 0;
        for (let i = 0; i < numSeries; i++) {
          const value = series[i][j];
          if (value > 0) {
            positiveIndices.push(i);
            nonZeroCount++;
          } else if (value < 0) {
            negativeIndices.push(i);
            nonZeroCount++;
          }
        }
        if (positiveIndices.length > 0 && negativeIndices.length === 0) {
          if (positiveIndices.length === 1) {
            output[positiveIndices[0]][j] = chartType === "bar" && numColumns === 1 ? "top" : "both";
          } else {
            const firstPositiveIndex = positiveIndices[0];
            const lastPositiveIndex = positiveIndices[positiveIndices.length - 1];
            for (const i of positiveIndices) {
              if (i === firstPositiveIndex) {
                output[i][j] = chartType === "bar" && numColumns === 1 ? "top" : "bottom";
              } else if (i === lastPositiveIndex) {
                output[i][j] = "top";
              } else {
                output[i][j] = "none";
              }
            }
          }
        } else if (negativeIndices.length > 0 && positiveIndices.length === 0) {
          if (negativeIndices.length === 1) {
            output[negativeIndices[0]][j] = "both";
          } else {
            const highestNegativeIndex = Math.max(...negativeIndices);
            const lowestNegativeIndex = Math.min(...negativeIndices);
            for (const i of negativeIndices) {
              if (i === highestNegativeIndex) {
                output[i][j] = "bottom";
              } else if (i === lowestNegativeIndex) {
                output[i][j] = "top";
              } else {
                output[i][j] = "none";
              }
            }
          }
        } else if (positiveIndices.length > 0 && negativeIndices.length > 0) {
          const lastPositiveIndex = positiveIndices[positiveIndices.length - 1];
          for (const i of positiveIndices) {
            if (i === lastPositiveIndex) {
              output[i][j] = "top";
            } else {
              output[i][j] = "none";
            }
          }
          const highestNegativeIndex = Math.max(...negativeIndices);
          for (const i of negativeIndices) {
            if (i === highestNegativeIndex) {
              output[i][j] = "bottom";
            } else {
              output[i][j] = "none";
            }
          }
        } else if (nonZeroCount === 1) {
          const index = positiveIndices[0] || negativeIndices[0];
          output[index][j] = "both";
        }
      }
      return output;
    }
    /** @param {{ j?: any, i?: any, x1?: any, x2?: any, y1?: any, y2?: any, bc?: any, elSeries?: any }} opts */
    barBackground({ j, i, x1, x2, y1, y2, elSeries }) {
      const w = this.w;
      const graphics = new Graphics(this.barCtx.w);
      const sr = new Series(this.barCtx.w);
      const activeSeriesIndex = sr.getActiveConfigSeriesIndex();
      if (this.barCtx.barOptions.colors.backgroundBarColors.length > 0 && activeSeriesIndex === i) {
        if (j >= this.barCtx.barOptions.colors.backgroundBarColors.length) {
          j %= this.barCtx.barOptions.colors.backgroundBarColors.length;
        }
        const bcolor = this.barCtx.barOptions.colors.backgroundBarColors[j];
        const rect = graphics.drawRect(
          typeof x1 !== "undefined" ? x1 : 0,
          typeof y1 !== "undefined" ? y1 : 0,
          typeof x2 !== "undefined" ? x2 : w.layout.gridWidth,
          typeof y2 !== "undefined" ? y2 : w.layout.gridHeight,
          this.barCtx.barOptions.colors.backgroundBarRadius,
          bcolor,
          this.barCtx.barOptions.colors.backgroundBarOpacity
        );
        elSeries.add(rect);
        rect.node.classList.add("apexcharts-backgroundBar");
      }
    }
    /** @param {{ barWidth?: any, barXPosition?: any, y1?: any, y2?: any, yRatio?: any, strokeWidth?: any, isReversed?: any, series?: any, seriesGroup?: any, realIndex?: any, i?: any, j?: any, w?: any }} opts */
    getColumnPaths({
      barWidth,
      barXPosition,
      y1,
      y2,
      strokeWidth,
      isReversed,
      series,
      seriesGroup,
      realIndex,
      i,
      j,
      w
    }) {
      var _a;
      const graphics = new Graphics(this.barCtx.w);
      strokeWidth = Array.isArray(strokeWidth) ? strokeWidth[realIndex] : strokeWidth;
      if (!strokeWidth) strokeWidth = 0;
      let bW = barWidth;
      let bXP = barXPosition;
      if ((_a = w.config.series[realIndex].data[j]) == null ? void 0 : _a.columnWidthOffset) {
        bXP = barXPosition - w.config.series[realIndex].data[j].columnWidthOffset / 2;
        bW = barWidth + w.config.series[realIndex].data[j].columnWidthOffset;
      }
      const strokeCenter = strokeWidth / 2;
      const x1 = bXP + strokeCenter;
      const x2 = bXP + bW - strokeCenter;
      const direction = (series[i][j] >= 0 ? 1 : -1) * (isReversed ? -1 : 1);
      y1 += 1e-3 - strokeCenter * direction;
      y2 += 1e-3 + strokeCenter * direction;
      let pathTo = graphics.move(x1, y1);
      let pathFrom = graphics.move(x1, y1);
      const sl = graphics.line(x2, y1);
      if (w.globals.previousPaths.length > 0) {
        pathFrom = this.barCtx.getPreviousPath(realIndex, j, false);
      }
      pathTo = pathTo + graphics.line(x1, y2) + graphics.line(x2, y2) + sl + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
      pathFrom = pathFrom + graphics.line(x1, y1) + sl + sl + sl + sl + sl + graphics.line(x1, y1) + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
      if (this.arrBorderRadius[realIndex][j] !== "none") {
        pathTo = graphics.roundPathCorners(
          pathTo,
          w.config.plotOptions.bar.borderRadius
        );
      }
      if (w.config.chart.stacked) {
        let _ctx = this.barCtx;
        _ctx = this.barCtx[seriesGroup];
        _ctx.yArrj.push(y2 - strokeCenter * direction);
        _ctx.yArrjF.push(Math.abs(y1 - y2 + strokeWidth * direction));
        _ctx.yArrjVal.push(this.barCtx.series[i][j]);
      }
      return {
        pathTo,
        pathFrom
      };
    }
    /** @param {{ barYPosition?: any, barHeight?: any, x1?: any, x2?: any, strokeWidth?: any, isReversed?: any, series?: any, seriesGroup?: any, realIndex?: any, i?: any, j?: any, w?: any }} opts */
    getBarpaths({
      barYPosition,
      barHeight,
      x1,
      x2,
      strokeWidth,
      isReversed,
      series,
      seriesGroup,
      realIndex,
      i,
      j,
      w
    }) {
      var _a;
      const graphics = new Graphics(this.barCtx.w);
      strokeWidth = Array.isArray(strokeWidth) ? strokeWidth[realIndex] : strokeWidth;
      if (!strokeWidth) strokeWidth = 0;
      let bYP = barYPosition;
      let bH = barHeight;
      if ((_a = w.config.series[realIndex].data[j]) == null ? void 0 : _a.barHeightOffset) {
        bYP = barYPosition - w.config.series[realIndex].data[j].barHeightOffset / 2;
        bH = barHeight + w.config.series[realIndex].data[j].barHeightOffset;
      }
      const strokeCenter = strokeWidth / 2;
      const y1 = bYP + strokeCenter;
      const y2 = bYP + bH - strokeCenter;
      const direction = (series[i][j] >= 0 ? 1 : -1) * (isReversed ? -1 : 1);
      x1 += 1e-3 + strokeCenter * direction;
      x2 += 1e-3 - strokeCenter * direction;
      let pathTo = graphics.move(x1, y1);
      let pathFrom = graphics.move(x1, y1);
      if (w.globals.previousPaths.length > 0) {
        pathFrom = this.barCtx.getPreviousPath(realIndex, j, false);
      }
      const sl = graphics.line(x1, y2);
      pathTo = pathTo + graphics.line(x2, y1) + graphics.line(x2, y2) + sl + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
      pathFrom = pathFrom + graphics.line(x1, y1) + sl + sl + sl + sl + sl + graphics.line(x1, y1) + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
      if (this.arrBorderRadius[realIndex][j] !== "none") {
        pathTo = graphics.roundPathCorners(
          pathTo,
          w.config.plotOptions.bar.borderRadius
        );
      }
      if (w.config.chart.stacked) {
        let _ctx = this.barCtx;
        _ctx = this.barCtx[seriesGroup];
        _ctx.xArrj.push(x2 + strokeCenter * direction);
        _ctx.xArrjF.push(Math.abs(x1 - x2 - strokeWidth * direction));
        _ctx.xArrjVal.push(this.barCtx.series[i][j]);
      }
      return {
        pathTo,
        pathFrom
      };
    }
    /** @param {{series: any}} opts */
    checkZeroSeries({ series }) {
      const w = this.w;
      for (let zs = 0; zs < series.length; zs++) {
        let total = 0;
        for (let zsj = 0; zsj < series[w.globals.maxValsInArrayIndex].length; zsj++) {
          total += series[zs][zsj];
        }
        if (total === 0) {
          this.barCtx.zeroSerieses.push(zs);
        }
      }
    }
    /**
     * @param {number} value
     * @param {number} zeroW
     */
    getXForValue(value, zeroW, zeroPositionForNull = true) {
      let xForVal = zeroPositionForNull ? zeroW : null;
      if (typeof value !== "undefined" && value !== null) {
        xForVal = zeroW + value / this.barCtx.invertedYRatio - (this.barCtx.isReversed ? value / this.barCtx.invertedYRatio : 0) * 2;
      }
      return xForVal;
    }
    /**
     * @param {number} value
     * @param {number} zeroH
     * @param {number} translationsIndex
     */
    getYForValue(value, zeroH, translationsIndex, zeroPositionForNull = true) {
      let yForVal = zeroPositionForNull ? zeroH : null;
      if (typeof value !== "undefined" && value !== null) {
        yForVal = zeroH - value / this.barCtx.yRatio[translationsIndex] + (this.barCtx.isReversed ? value / this.barCtx.yRatio[translationsIndex] : 0) * 2;
      }
      return yForVal;
    }
    /**
     * @param {string} type
     * @param {number} zeroW
     * @param {number} zeroH
     * @param {number} i
     * @param {number} j
     * @param {number} translationsIndex
     */
    getGoalValues(type, zeroW, zeroH, i, j, translationsIndex) {
      const w = this.w;
      const goals = [];
      const pushGoal = (value, attrs) => {
        goals.push({
          [type]: type === "x" ? this.getXForValue(value, zeroW, false) : this.getYForValue(value, zeroH, translationsIndex, false),
          attrs
        });
      };
      if (w.seriesData.seriesGoals[i] && w.seriesData.seriesGoals[i][j] && Array.isArray(w.seriesData.seriesGoals[i][j])) {
        w.seriesData.seriesGoals[i][j].forEach((goal) => {
          pushGoal(goal.value, goal);
        });
      }
      if (this.barCtx.barOptions.isDumbbell && w.rangeData.seriesRange.length) {
        const colors = this.barCtx.barOptions.dumbbellColors ? this.barCtx.barOptions.dumbbellColors : w.globals.colors;
        const commonAttrs = {
          strokeHeight: type === "x" ? 0 : w.globals.markers.size[i],
          strokeWidth: type === "x" ? w.globals.markers.size[i] : 0,
          strokeDashArray: 0,
          strokeLineCap: "round",
          strokeColor: Array.isArray(colors[i]) ? colors[i][0] : colors[i]
        };
        pushGoal(w.rangeData.seriesRangeStart[i][j], commonAttrs);
        pushGoal(w.rangeData.seriesRangeEnd[i][j], __spreadProps(__spreadValues({}, commonAttrs), {
          strokeColor: Array.isArray(colors[i]) ? colors[i][1] : colors[i]
        }));
      }
      return goals;
    }
    /** @param {{barXPosition: any, barYPosition: any, goalX: any, goalY: any, barWidth: any, barHeight: any}} opts */
    drawGoalLine({
      barXPosition,
      barYPosition,
      goalX,
      goalY,
      barWidth,
      barHeight
    }) {
      const graphics = new Graphics(this.barCtx.w);
      const lineGroup = graphics.group({
        className: "apexcharts-bar-goals-groups"
      });
      lineGroup.node.classList.add("apexcharts-element-hidden");
      this.barCtx.w.globals.delayedElements.push({
        el: lineGroup.node
      });
      lineGroup.attr(
        "clip-path",
        `url(#gridRectMarkerMask${this.barCtx.w.globals.cuid})`
      );
      let line = null;
      if (this.barCtx.isHorizontal) {
        if (Array.isArray(goalX)) {
          goalX.forEach((goal) => {
            if (goal.x >= -1 && goal.x <= graphics.w.layout.gridWidth + 1) {
              const sHeight = typeof goal.attrs.strokeHeight !== "undefined" ? goal.attrs.strokeHeight : barHeight / 2;
              const y = barYPosition + sHeight + barHeight / 2;
              line = graphics.drawLine(
                goal.x,
                y - sHeight * 2,
                goal.x,
                y,
                goal.attrs.strokeColor ? goal.attrs.strokeColor : void 0,
                goal.attrs.strokeDashArray,
                goal.attrs.strokeWidth ? goal.attrs.strokeWidth : 2,
                goal.attrs.strokeLineCap
              );
              lineGroup.add(line);
            }
          });
        }
      } else {
        if (Array.isArray(goalY)) {
          goalY.forEach((goal) => {
            if (goal.y >= -1 && goal.y <= graphics.w.layout.gridHeight + 1) {
              const sWidth = typeof goal.attrs.strokeWidth !== "undefined" ? goal.attrs.strokeWidth : barWidth / 2;
              const x = barXPosition + sWidth + barWidth / 2;
              line = graphics.drawLine(
                x - sWidth * 2,
                goal.y,
                x,
                goal.y,
                goal.attrs.strokeColor ? goal.attrs.strokeColor : void 0,
                goal.attrs.strokeDashArray,
                goal.attrs.strokeHeight ? goal.attrs.strokeHeight : 2,
                goal.attrs.strokeLineCap
              );
              lineGroup.add(line);
            }
          });
        }
      }
      return lineGroup;
    }
    /** @param {{prevPaths: any, currPaths: any, color: any, realIndex: any, j: any}} opts */
    drawBarShadow({ prevPaths, currPaths, color, realIndex, j }) {
      const w = this.w;
      const { x: prevX2, x1: prevX1, barYPosition: prevY1 } = prevPaths;
      const { x: currX2, x1: currX1, barYPosition: currY1 } = currPaths;
      const prevY2 = prevY1 + currPaths.barHeight;
      const graphics = new Graphics(this.barCtx.w);
      const utils = new Utils$1();
      const shadowPath = graphics.move(prevX1, prevY2) + graphics.line(prevX2, prevY2) + graphics.line(currX2, currY1) + graphics.line(currX1, currY1) + graphics.line(prevX1, prevY2) + (w.config.plotOptions.bar.borderRadiusApplication === "around" || this.arrBorderRadius[realIndex][j] === "both" ? " Z" : " z");
      return graphics.drawPath({
        d: shadowPath,
        fill: utils.shadeColor(0.5, Utils$1.rgb2hex(color)),
        stroke: "none",
        strokeWidth: 0,
        fillOpacity: 1,
        classes: "apexcharts-bar-shadow apexcharts-decoration-element"
      });
    }
    /** @param {{i: any, j: any}} opts */
    getZeroValueEncounters({ i, j }) {
      var _a;
      const w = this.w;
      let nonZeroColumns = 0;
      let zeroEncounters = 0;
      const seriesIndices = w.config.plotOptions.bar.horizontal ? w.seriesData.series.map((_, _i) => _i) : ((_a = w.globals.columnSeries) == null ? void 0 : _a.i.map((_i) => _i)) || [];
      seriesIndices.forEach((_si) => {
        const val = w.globals.seriesPercent[_si][j];
        if (val) {
          nonZeroColumns++;
        }
        if (_si < i && val === 0) {
          zeroEncounters++;
        }
      });
      return {
        nonZeroColumns,
        zeroEncounters
      };
    }
    /**
     * @param {number} seriesIndex
     */
    getGroupIndex(seriesIndex) {
      const w = this.w;
      const groupIndex = w.labelData.seriesGroups.findIndex(
        (group) => (
          // w.config.series[i].name may be undefined, so use
          // w.seriesData.seriesNames[i], which has default names for those
          // series. w.labelData.seriesGroups[] uses the same default naming.
          group.indexOf(w.seriesData.seriesNames[seriesIndex]) > -1
        )
      );
      const cGI = this.barCtx.columnGroupIndices;
      let columnGroupIndex = cGI.indexOf(groupIndex);
      if (columnGroupIndex < 0) {
        cGI.push(groupIndex);
        columnGroupIndex = cGI.length - 1;
      }
      return { groupIndex, columnGroupIndex };
    }
  };
  class Bar {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     * @param {import('../types/internal').XYRatios} xyRatios
     */
    constructor(w, ctx, xyRatios) {
      this.ctx = ctx;
      this.w = w;
      this.barOptions = w.config.plotOptions.bar;
      this.isHorizontal = this.barOptions.horizontal;
      this.strokeWidth = w.config.stroke.width;
      this.isNullValue = false;
      this.isRangeBar = w.rangeData.seriesRange.length && this.isHorizontal;
      this.isVerticalGroupedRangeBar = !w.globals.isBarHorizontal && w.rangeData.seriesRange.length && w.config.plotOptions.bar.rangeBarGroupRows;
      this.isFunnel = this.barOptions.isFunnel;
      this.xyRatios = xyRatios;
      this.xRatio = 0;
      this.yRatio = [];
      this.invertedXRatio = 0;
      this.invertedYRatio = 0;
      this.baseLineY = [];
      this.baseLineInvertedY = 0;
      if (this.xyRatios !== null) {
        this.xRatio = xyRatios.xRatio;
        this.yRatio = xyRatios.yRatio;
        this.invertedXRatio = xyRatios.invertedXRatio;
        this.invertedYRatio = xyRatios.invertedYRatio;
        this.baseLineY = xyRatios.baseLineY;
        this.baseLineInvertedY = xyRatios.baseLineInvertedY;
      }
      this.yaxisIndex = 0;
      this.translationsIndex = 0;
      this.seriesLen = 0;
      this.pathArr = [];
      this.series = [];
      this.elSeries = null;
      this.visibleI = 0;
      this.isReversed = false;
      const ser = new Series(this.w);
      this.lastActiveBarSerieIndex = ser.getActiveConfigSeriesIndex("desc", [
        "bar",
        "column"
      ]);
      this.columnGroupIndices = [];
      const barSeriesIndices = ser.getBarSeriesIndices();
      const coreUtils = new CoreUtils(this.w);
      this.stackedSeriesTotals = coreUtils.getStackedSeriesTotals(
        this.w.config.series.map((s, i) => {
          return barSeriesIndices.indexOf(i) === -1 ? i : -1;
        }).filter((s) => {
          return s !== -1;
        })
      );
      this.barHelpers = new Helpers$1(this);
    }
    /** primary draw method which is called on bar object
     * @memberof Bar
     * @param {any[]} series - user supplied series values
     * @param {number} seriesIndex - the index by which series will be drawn on the svg
     * @return {Element} element which is supplied to parent chart draw method for appending
     **/
    draw(series, seriesIndex) {
      var _a;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const coreUtils = new CoreUtils(this.w);
      series = coreUtils.getLogSeries(series);
      this.series = series;
      this.yRatio = coreUtils.getLogYRatios(this.yRatio);
      this.barHelpers.initVariables(series);
      const ret = graphics.group({
        class: "apexcharts-bar-series apexcharts-plot-series"
      });
      if (w.config.dataLabels.enabled) {
        if (this.totalItems > this.barOptions.dataLabels.maxItems) {
          console.warn(
            "WARNING: DataLabels are enabled but there are too many to display. This may cause performance issue when rendering - ApexCharts"
          );
        }
      }
      for (let i = 0, bc = 0; i < series.length; i++, bc++) {
        let x, y;
        const yArrj = [];
        const xArrj = [];
        const realIndex = w.globals.comboCharts ? (
          /** @type {any} */
          seriesIndex[i]
        ) : i;
        const { columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
        const elSeries = graphics.group({
          class: `apexcharts-series`,
          rel: i + 1,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
          "data:realIndex": realIndex
        });
        Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
        if (series[i].length > 0) {
          this.visibleI = this.visibleI + 1;
        }
        if (this.yRatio.length > 1) {
          this.yaxisIndex = w.globals.seriesYAxisReverseMap[realIndex];
          this.translationsIndex = realIndex;
        }
        const translationsIndex = this.translationsIndex;
        this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed;
        const initPositions = this.barHelpers.initialPositions(realIndex);
        const {
          y: initY,
          yDivision,
          // yDivision is the GRIDHEIGHT divided by number of datapoints (bars)
          zeroW,
          // zeroW is the baseline where 0 meets x axis
          x: initX,
          xDivision,
          // xDivision is the GRIDWIDTH divided by number of datapoints (columns)
          zeroH
          // zeroH is the baseline where 0 meets y axis
        } = initPositions;
        let barHeight = initPositions.barHeight;
        let barWidth = initPositions.barWidth;
        y = initY;
        x = initX;
        if (!this.isHorizontal) {
          xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
        }
        const elDataLabelsWrap = graphics.group({
          class: "apexcharts-datalabels",
          "data:realIndex": realIndex
        });
        w.globals.delayedElements.push({
          el: elDataLabelsWrap.node
        });
        elDataLabelsWrap.node.classList.add("apexcharts-element-hidden");
        const elGoalsMarkers = graphics.group({
          class: "apexcharts-bar-goals-markers"
        });
        const elBarShadows = graphics.group({
          class: "apexcharts-bar-shadows"
        });
        w.globals.delayedElements.push({
          el: elBarShadows.node
        });
        elBarShadows.node.classList.add("apexcharts-element-hidden");
        for (let j = 0; j < series[i].length; j++) {
          const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
          let paths = (
            /** @type {any} */
            null
          );
          const pathsParams = {
            indexes: {
              i,
              j,
              realIndex,
              translationsIndex,
              bc
            },
            x,
            y,
            strokeWidth,
            elSeries
          };
          if (this.isHorizontal) {
            paths = this.drawBarPaths(__spreadProps(__spreadValues({}, pathsParams), {
              barHeight,
              zeroW,
              yDivision
            }));
            barWidth = this.series[i][j] / this.invertedYRatio;
          } else {
            paths = this.drawColumnPaths(__spreadProps(__spreadValues({}, pathsParams), {
              xDivision,
              barWidth,
              zeroH
            }));
            barHeight = this.series[i][j] / this.yRatio[translationsIndex];
          }
          const pathFill = this.barHelpers.getPathFillColor(
            series,
            i,
            j,
            realIndex
          );
          if (this.isFunnel && this.barOptions.isFunnel3d && this.pathArr.length && j > 0) {
            const barShadow = this.barHelpers.drawBarShadow({
              color: typeof pathFill.color === "string" && ((_a = pathFill.color) == null ? void 0 : _a.indexOf("url")) === -1 ? pathFill.color : Utils$1.hexToRgba(w.globals.colors[i]),
              prevPaths: this.pathArr[this.pathArr.length - 1],
              currPaths: paths,
              realIndex,
              j
            });
            elBarShadows.add(barShadow);
            if (w.config.chart.dropShadow.enabled) {
              const filters = new Filters(this.w);
              filters.dropShadow(barShadow, w.config.chart.dropShadow, realIndex);
            }
          }
          this.pathArr.push(paths);
          const barGoalLine = this.barHelpers.drawGoalLine({
            barXPosition: paths.barXPosition,
            barYPosition: paths.barYPosition,
            goalX: paths.goalX,
            goalY: paths.goalY,
            barHeight,
            barWidth
          });
          if (barGoalLine) {
            elGoalsMarkers.add(barGoalLine);
          }
          y = paths.y;
          x = paths.x;
          if (j > 0) {
            xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
          }
          yArrj.push(y);
          this.renderSeries(__spreadProps(__spreadValues({
            realIndex,
            pathFill: pathFill.color
          }, pathFill.useRangeColor ? { lineFill: pathFill.color } : {}), {
            j,
            i,
            columnGroupIndex,
            pathFrom: paths.pathFrom,
            pathTo: paths.pathTo,
            strokeWidth,
            elSeries,
            x,
            y,
            series,
            barHeight: Math.abs(paths.barHeight ? paths.barHeight : barHeight),
            barWidth: Math.abs(paths.barWidth ? paths.barWidth : barWidth),
            elDataLabelsWrap,
            elGoalsMarkers,
            elBarShadows,
            visibleSeries: this.visibleI,
            type: "bar"
          }));
        }
        w.globals.seriesXvalues[realIndex] = xArrj;
        w.globals.seriesYvalues[realIndex] = yArrj;
        ret.add(elSeries);
      }
      return ret;
    }
    /** @param {{ realIndex?: any, pathFill?: any, lineFill?: any, j?: any, i?: any, columnGroupIndex?: any, pathFrom?: any, pathTo?: any, strokeWidth?: any, elSeries?: any, x?: any, y?: any, y1?: any, y2?: any, series?: any, barHeight?: any, barWidth?: any, barXPosition?: any, barYPosition?: any, elDataLabelsWrap?: any, elGoalsMarkers?: any, elBarShadows?: any, visibleSeries?: any, type?: any, classes?: any }} opts */
    renderSeries({
      realIndex,
      pathFill,
      lineFill,
      j,
      i,
      columnGroupIndex,
      pathFrom,
      pathTo,
      strokeWidth,
      elSeries,
      x,
      // x pos
      y,
      // y pos
      y1,
      // absolute value
      y2,
      // absolute value
      series,
      barHeight,
      barWidth,
      barXPosition,
      barYPosition,
      elDataLabelsWrap,
      elGoalsMarkers,
      elBarShadows,
      visibleSeries,
      type,
      classes
    }) {
      const w = this.w;
      const graphics = new Graphics(this.w, this.ctx);
      let skipDrawing = false;
      if (!elSeries._bindingsDelegated) {
        elSeries._bindingsDelegated = true;
        graphics.setupEventDelegation(elSeries, `.apexcharts-${type}-area`);
      }
      if (!lineFill) {
        let fetchColor = function(i2) {
          const exp = w.config.stroke.colors;
          let c;
          if (Array.isArray(exp) && exp.length > 0) {
            c = exp[i2];
            if (!c) c = "";
            if (typeof c === "function") {
              return c({
                value: w.seriesData.series[i2][j],
                dataPointIndex: j,
                w
              });
            }
          }
          return c;
        };
        const checkAvailableColor = typeof w.globals.stroke.colors[realIndex] === "function" ? fetchColor(realIndex) : w.globals.stroke.colors[realIndex];
        lineFill = this.barOptions.distributed ? w.globals.stroke.colors[j] : checkAvailableColor;
      }
      const barDataLabels = new BarDataLabels(this);
      const dataLabelsObj = (
        /** @type {any} */
        barDataLabels.handleBarDataLabels({
          x,
          y,
          y1,
          y2,
          i,
          j,
          series,
          realIndex,
          columnGroupIndex,
          barHeight,
          barWidth,
          barXPosition,
          barYPosition,
          visibleSeries
        })
      );
      if (!w.globals.isBarHorizontal) {
        if (dataLabelsObj.dataLabelsPos.dataLabelsX + Math.max(barWidth, w.globals.barPadForNumericAxis) < 0 || dataLabelsObj.dataLabelsPos.dataLabelsX - Math.max(barWidth, w.globals.barPadForNumericAxis) > w.layout.gridWidth) {
          skipDrawing = true;
        }
      }
      if (
        /** @type {Record<string,any>} */
        w.config.series[i].data[j] && /** @type {Record<string,any>} */
        w.config.series[i].data[j].strokeColor
      ) {
        lineFill = /** @type {Record<string,any>} */
        w.config.series[i].data[j].strokeColor;
      }
      if (this.isNullValue) {
        pathFill = "none";
      }
      const delay = j / w.config.chart.animations.animateGradually.delay * (w.config.chart.animations.speed / w.globals.dataPoints) / 2.4;
      if (!skipDrawing) {
        const renderedPath = (
          /** @type {any} */
          graphics.renderPaths({
            i,
            j,
            realIndex,
            pathFrom,
            pathTo,
            stroke: lineFill,
            strokeWidth,
            strokeLineCap: w.config.stroke.lineCap,
            fill: pathFill,
            animationDelay: delay,
            initialSpeed: w.config.chart.animations.speed,
            dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed,
            className: `apexcharts-${type}-area ${classes}`,
            chartType: type,
            bindEventsOnPaths: false
          })
        );
        renderedPath.attr("clip-path", `url(#gridRectBarMask${w.globals.cuid})`);
        const forecast = w.config.forecastDataPoints;
        if (forecast.count > 0) {
          if (j >= w.globals.dataPoints - forecast.count) {
            renderedPath.node.setAttribute("stroke-dasharray", forecast.dashArray);
            renderedPath.node.setAttribute("stroke-width", forecast.strokeWidth);
            renderedPath.node.setAttribute("fill-opacity", forecast.fillOpacity);
          }
        }
        if (typeof y1 !== "undefined" && typeof y2 !== "undefined") {
          renderedPath.attr("data-range-y1", y1);
          renderedPath.attr("data-range-y2", y2);
        }
        const filters = new Filters(this.w);
        filters.setSelectionFilter(renderedPath, realIndex, j);
        elSeries.add(renderedPath);
        renderedPath.attr({
          cy: dataLabelsObj.dataLabelsPos.bcy,
          cx: dataLabelsObj.dataLabelsPos.bcx,
          j,
          val: w.seriesData.series[i][j],
          barHeight,
          barWidth
        });
        if (dataLabelsObj.dataLabels !== null) {
          elDataLabelsWrap.add(dataLabelsObj.dataLabels);
        }
        if (dataLabelsObj.totalDataLabels) {
          elDataLabelsWrap.add(dataLabelsObj.totalDataLabels);
        }
        elSeries.add(elDataLabelsWrap);
        if (elGoalsMarkers) {
          elSeries.add(elGoalsMarkers);
        }
        if (elBarShadows) {
          elSeries.add(elBarShadows);
        }
      }
      return elSeries;
    }
    /** @param {{indexes: any, barHeight: any, strokeWidth: any, zeroW: any, x: any, y: any, yDivision: any, elSeries: any}} opts */
    drawBarPaths({
      indexes,
      barHeight,
      strokeWidth,
      zeroW,
      x,
      y,
      yDivision,
      elSeries
    }) {
      const w = this.w;
      const i = indexes.i;
      const j = indexes.j;
      let barYPosition;
      if (w.axisFlags.isXNumeric) {
        y = (w.seriesData.seriesX[i][j] - w.globals.minX) / this.invertedXRatio - barHeight;
        barYPosition = y + barHeight * this.visibleI;
      } else {
        if (w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
          const { nonZeroColumns, zeroEncounters } = this.barHelpers.getZeroValueEncounters({ i, j });
          if (nonZeroColumns > 0) {
            barHeight = this.seriesLen * barHeight / nonZeroColumns;
          }
          barYPosition = y + barHeight * this.visibleI;
          barYPosition -= barHeight * zeroEncounters;
        } else {
          barYPosition = y + barHeight * this.visibleI;
        }
      }
      if (this.isFunnel) {
        const _zeroW = zeroW != null ? zeroW : 0;
        zeroW = _zeroW - /** @type {number} */
        /** @type {any} */
        (this.barHelpers.getXForValue(
          /** @type {any} */
          this.series[i][j],
          _zeroW
        ) - _zeroW) / 2;
      }
      x = this.barHelpers.getXForValue(
        /** @type {any} */
        this.series[i][j],
        zeroW != null ? zeroW : 0
      );
      const paths = (
        /** @type {any} */
        this.barHelpers.getBarpaths({
          barYPosition,
          barHeight,
          x1: zeroW,
          x2: x,
          strokeWidth,
          isReversed: this.isReversed,
          series: this.series,
          realIndex: indexes.realIndex,
          i,
          j,
          w
        })
      );
      if (!w.axisFlags.isXNumeric) {
        y = y + yDivision;
      }
      this.barHelpers.barBackground({
        j,
        i,
        y1: barYPosition - barHeight * this.visibleI,
        y2: barHeight * this.seriesLen,
        elSeries
      });
      return {
        pathTo: paths.pathTo,
        pathFrom: paths.pathFrom,
        x1: zeroW,
        x,
        y,
        goalX: this.barHelpers.getGoalValues(
          "x",
          zeroW,
          /** @type {any} */
          null,
          i,
          j,
          0
        ),
        barYPosition,
        barHeight
      };
    }
    /** @param {{indexes: any, x: any, y: any, xDivision: any, barWidth: any, zeroH: any, strokeWidth: any, elSeries: any}} opts */
    drawColumnPaths({
      indexes,
      x,
      y,
      xDivision,
      barWidth,
      zeroH,
      strokeWidth,
      elSeries
    }) {
      const w = this.w;
      const realIndex = indexes.realIndex;
      const translationsIndex = indexes.translationsIndex;
      const i = indexes.i;
      const j = indexes.j;
      const bc = indexes.bc;
      let barXPosition;
      if (w.axisFlags.isXNumeric) {
        const xForNumericX = this.getBarXForNumericXAxis({
          x,
          j,
          realIndex,
          barWidth
        });
        x = xForNumericX.x;
        barXPosition = xForNumericX.barXPosition;
      } else {
        if (w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
          const { nonZeroColumns, zeroEncounters } = this.barHelpers.getZeroValueEncounters({ i, j });
          if (nonZeroColumns > 0) {
            barWidth = this.seriesLen * barWidth / nonZeroColumns;
          }
          barXPosition = x + barWidth * this.visibleI;
          barXPosition -= barWidth * zeroEncounters;
        } else {
          barXPosition = x + barWidth * this.visibleI;
        }
      }
      y = this.barHelpers.getYForValue(
        /** @type {any} */
        this.series[i][j],
        zeroH,
        translationsIndex
      );
      const paths = (
        /** @type {any} */
        this.barHelpers.getColumnPaths({
          barXPosition,
          barWidth,
          y1: zeroH,
          y2: y,
          strokeWidth,
          isReversed: this.isReversed,
          series: this.series,
          realIndex,
          i,
          j,
          w
        })
      );
      if (!w.axisFlags.isXNumeric) {
        x = x + xDivision;
      }
      this.barHelpers.barBackground({
        bc,
        j,
        i,
        x1: barXPosition - strokeWidth / 2 - barWidth * this.visibleI,
        x2: barWidth * this.seriesLen + strokeWidth / 2,
        elSeries
      });
      return {
        pathTo: paths.pathTo,
        pathFrom: paths.pathFrom,
        x,
        y,
        goalY: this.barHelpers.getGoalValues(
          "y",
          /** @type {any} */
          null,
          zeroH,
          i,
          j,
          translationsIndex
        ),
        barXPosition,
        barWidth
      };
    }
    /** @param {{x: any, barWidth: any, realIndex: any, j: any}} opts */
    getBarXForNumericXAxis({ x, barWidth, realIndex, j }) {
      const w = this.w;
      let sxI = realIndex;
      if (!w.seriesData.seriesX[realIndex].length) {
        sxI = w.globals.maxValsInArrayIndex;
      }
      if (Utils$1.isNumber(w.seriesData.seriesX[sxI][j])) {
        x = (w.seriesData.seriesX[sxI][j] - w.globals.minX) / this.xRatio - barWidth * this.seriesLen / 2;
      }
      return {
        barXPosition: x + barWidth * this.visibleI,
        x
      };
    }
    /** getPreviousPath is a common function for bars/columns which is used to get previous paths when data changes.
     * @memberof Bar
     * @param {number} realIndex - current iterating i
     * @param {number} j - current iterating series's j index
     * @return {string} pathFrom is the string which will be appended in animations
     **/
    getPreviousPath(realIndex, j) {
      const w = this.w;
      let pathFrom = "M 0 0";
      for (let pp = 0; pp < w.globals.previousPaths.length; pp++) {
        const gpp = w.globals.previousPaths[pp];
        if (gpp.paths && gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(String(realIndex), 10)) {
          if (typeof w.globals.previousPaths[pp].paths[j] !== "undefined") {
            pathFrom = w.globals.previousPaths[pp].paths[j].d;
          }
        }
      }
      return pathFrom;
    }
  }
  class BarStacked extends Bar {
    /**
     * @param {any[]} series
     * @param {number} seriesIndex
     */
    draw(series, seriesIndex) {
      const w = this.w;
      this.graphics = new Graphics(this.w);
      this.bar = new Bar(this.w, this.ctx, this.xyRatios);
      const coreUtils = new CoreUtils(this.w);
      series = coreUtils.getLogSeries(series);
      this.yRatio = coreUtils.getLogYRatios(this.yRatio);
      this.barHelpers.initVariables(series);
      if (w.config.chart.stackType === "100%") {
        series = w.globals.comboCharts ? (
          /** @type {any} */
          seriesIndex.map(
            (_) => w.globals.seriesPercent[_]
          )
        ) : w.globals.seriesPercent.slice();
      }
      this.series = series;
      this.barHelpers.initializeStackedPrevVars(this);
      const ret = this.graphics.group({
        class: "apexcharts-bar-series apexcharts-plot-series"
      });
      let x = 0;
      let y = 0;
      for (let i = 0, bc = 0; i < series.length; i++, bc++) {
        const realIndex = w.globals.comboCharts ? (
          /** @type {any} */
          seriesIndex[i]
        ) : i;
        const { groupIndex, columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
        this.groupCtx = /** @type {any} */
        this[
          /** @type {any} */
          w.labelData.seriesGroups[groupIndex]
        ];
        const xArrValues = [];
        const yArrValues = [];
        let translationsIndex = 0;
        if (this.yRatio.length > 1) {
          this.yaxisIndex = /** @type {any} */
          w.globals.seriesYAxisReverseMap[realIndex][0];
          translationsIndex = realIndex;
        }
        this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed;
        let elSeries = this.graphics.group({
          class: `apexcharts-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
          rel: i + 1,
          "data:realIndex": realIndex
        });
        Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
        const elDataLabelsWrap = this.graphics.group({
          class: "apexcharts-datalabels",
          "data:realIndex": realIndex
        });
        const elGoalsMarkers = this.graphics.group({
          class: "apexcharts-bar-goals-markers"
        });
        const initPositions = this.initialPositions(
          x,
          y,
          void 0,
          void 0,
          void 0,
          void 0,
          translationsIndex
        );
        const {
          xDivision,
          // xDivision is the GRIDWIDTH divided by number of datapoints (columns)
          yDivision,
          // yDivision is the GRIDHEIGHT divided by number of datapoints (bars)
          zeroH,
          // zeroH is the baseline where 0 meets y axis
          zeroW
          // zeroW is the baseline where 0 meets x axis
        } = initPositions;
        let barHeight = initPositions.barHeight;
        let barWidth = initPositions.barWidth;
        y = initPositions.y;
        x = initPositions.x;
        w.globals.barHeight = barHeight;
        w.globals.barWidth = barWidth;
        this.barHelpers.initializeStackedXYVars(this);
        if (this.groupCtx.prevY.length === 1 && /**
         * @param {number} val
         */
        this.groupCtx.prevY[0].every((val) => isNaN(val))) {
          this.groupCtx.prevY[0] = this.groupCtx.prevY[0].map(() => zeroH);
          this.groupCtx.prevYF[0] = this.groupCtx.prevYF[0].map(() => 0);
        }
        for (let j = 0; j < w.globals.dataPoints; j++) {
          const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
          const commonPathOpts = {
            indexes: { i, j, realIndex, translationsIndex, bc },
            strokeWidth,
            x,
            y,
            elSeries,
            columnGroupIndex,
            seriesGroup: w.labelData.seriesGroups[groupIndex]
          };
          let paths = (
            /** @type {any} */
            null
          );
          if (this.isHorizontal) {
            paths = this.drawStackedBarPaths(__spreadProps(__spreadValues({}, commonPathOpts), {
              zeroW,
              barHeight,
              yDivision
            }));
            barWidth = this.series[i][j] / this.invertedYRatio;
          } else {
            paths = this.drawStackedColumnPaths(__spreadProps(__spreadValues({}, commonPathOpts), {
              xDivision,
              barWidth,
              zeroH
            }));
            barHeight = this.series[i][j] / this.yRatio[translationsIndex];
          }
          const barGoalLine = this.barHelpers.drawGoalLine({
            barXPosition: paths.barXPosition,
            barYPosition: paths.barYPosition,
            goalX: paths.goalX,
            goalY: paths.goalY,
            barHeight,
            barWidth
          });
          if (barGoalLine) {
            elGoalsMarkers.add(barGoalLine);
          }
          y = paths.y;
          x = paths.x;
          xArrValues.push(x);
          yArrValues.push(y);
          const pathFill = this.barHelpers.getPathFillColor(
            series,
            i,
            j,
            realIndex
          );
          let classes = "";
          const flipClass = w.globals.isBarHorizontal ? "apexcharts-flip-x" : "apexcharts-flip-y";
          if (this.barHelpers.arrBorderRadius[realIndex][j] === "bottom" && w.seriesData.series[realIndex][j] > 0 || this.barHelpers.arrBorderRadius[realIndex][j] === "top" && w.seriesData.series[realIndex][j] < 0) {
            classes = flipClass;
          }
          elSeries = this.renderSeries(__spreadProps(__spreadValues({
            realIndex,
            pathFill: pathFill.color
          }, pathFill.useRangeColor ? { lineFill: pathFill.color } : {}), {
            j,
            i,
            columnGroupIndex,
            pathFrom: paths.pathFrom,
            pathTo: paths.pathTo,
            strokeWidth,
            elSeries,
            x,
            y,
            series,
            barHeight,
            barWidth,
            elDataLabelsWrap,
            elGoalsMarkers,
            type: "bar",
            visibleSeries: columnGroupIndex,
            classes
          }));
        }
        w.globals.seriesXvalues[realIndex] = xArrValues;
        w.globals.seriesYvalues[realIndex] = yArrValues;
        this.groupCtx.prevY.push(this.groupCtx.yArrj);
        this.groupCtx.prevYF.push(this.groupCtx.yArrjF);
        this.groupCtx.prevYVal.push(this.groupCtx.yArrjVal);
        this.groupCtx.prevX.push(this.groupCtx.xArrj);
        this.groupCtx.prevXF.push(this.groupCtx.xArrjF);
        this.groupCtx.prevXVal.push(this.groupCtx.xArrjVal);
        ret.add(elSeries);
      }
      return ret;
    }
    /**
     * @param {number} x
     * @param {number} y
     * @param {number | undefined} xDivision
     * @param {number | undefined} yDivision
     * @param {number | undefined} zeroH
     * @param {number | undefined} zeroW
     * @param {number} translationsIndex
     */
    initialPositions(x, y, xDivision, yDivision, zeroH, zeroW, translationsIndex) {
      const w = this.w;
      let barHeight, barWidth;
      if (this.isHorizontal) {
        yDivision = w.layout.gridHeight / w.globals.dataPoints;
        const userBarHeight = w.config.plotOptions.bar.barHeight;
        if (String(userBarHeight).indexOf("%") === -1) {
          barHeight = parseInt(userBarHeight, 10);
        } else {
          barHeight = yDivision * parseInt(userBarHeight, 10) / 100;
        }
        zeroW = w.globals.padHorizontal + (this.isReversed ? w.layout.gridWidth - this.baseLineInvertedY : this.baseLineInvertedY);
        y = (yDivision - barHeight) / 2;
      } else {
        xDivision = w.layout.gridWidth / w.globals.dataPoints;
        barWidth = xDivision;
        const userColumnWidth = w.config.plotOptions.bar.columnWidth;
        if (w.axisFlags.isXNumeric && w.globals.dataPoints > 1) {
          xDivision = w.globals.minXDiff / this.xRatio;
          barWidth = xDivision * parseInt(this.barOptions.columnWidth, 10) / 100;
        } else if (String(userColumnWidth).indexOf("%") === -1) {
          barWidth = parseInt(userColumnWidth, 10);
        } else {
          barWidth *= parseInt(userColumnWidth, 10) / 100;
        }
        if (this.isReversed) {
          zeroH = this.baseLineY[translationsIndex];
        } else {
          zeroH = w.layout.gridHeight - this.baseLineY[translationsIndex];
        }
        x = w.globals.padHorizontal + (xDivision - barWidth) / 2;
      }
      const subDivisions = w.globals.barGroups.length || 1;
      return {
        x,
        y,
        yDivision,
        xDivision,
        barHeight: (barHeight != null ? barHeight : 0) / subDivisions,
        barWidth: (barWidth != null ? barWidth : 0) / subDivisions,
        zeroH,
        zeroW
      };
    }
    /** @param {{indexes: any, barHeight: any, strokeWidth: any, zeroW: any, x: any, y: any, columnGroupIndex: any, seriesGroup: any, yDivision: any, elSeries: any}} opts */
    drawStackedBarPaths({
      indexes,
      barHeight,
      strokeWidth,
      zeroW,
      x,
      y,
      columnGroupIndex,
      seriesGroup,
      yDivision,
      elSeries
    }) {
      var _a, _b, _c, _d, _e;
      const w = this.w;
      const barYPosition = y + columnGroupIndex * barHeight;
      let barXPosition;
      const i = indexes.i;
      const j = indexes.j;
      const realIndex = indexes.realIndex;
      const translationsIndex = indexes.translationsIndex;
      let prevBarW = 0;
      for (let k = 0; k < this.groupCtx.prevXF.length; k++) {
        prevBarW = prevBarW + this.groupCtx.prevXF[k][j];
      }
      let gsi = i;
      if (
        /** @type {Record<string,any>} */
        w.config.series[realIndex].name
      ) {
        gsi = seriesGroup.indexOf(
          /** @type {Record<string,any>} */
          w.config.series[realIndex].name
        );
      }
      if (gsi > 0) {
        let bXP = zeroW;
        if (this.groupCtx.prevXVal[gsi - 1][j] < 0) {
          bXP = /** @type {any} */
          ((_a = this.series[i]) == null ? void 0 : _a[j]) >= 0 ? this.groupCtx.prevX[gsi - 1][j] + prevBarW - (this.isReversed ? prevBarW : 0) * 2 : this.groupCtx.prevX[gsi - 1][j];
        } else if (this.groupCtx.prevXVal[gsi - 1][j] >= 0) {
          bXP = /** @type {any} */
          ((_b = this.series[i]) == null ? void 0 : _b[j]) >= 0 ? this.groupCtx.prevX[gsi - 1][j] : this.groupCtx.prevX[gsi - 1][j] - prevBarW + (this.isReversed ? prevBarW : 0) * 2;
        }
        barXPosition = bXP;
      } else {
        barXPosition = zeroW;
      }
      if (
        /** @type {any} */
        ((_c = this.series[i]) == null ? void 0 : _c[j]) === null
      ) {
        x = barXPosition;
      } else {
        x = barXPosition + /** @type {any} */
        ((_d = this.series[i]) == null ? void 0 : _d[j]) / this.invertedYRatio - (this.isReversed ? (
          /** @type {any} */
          ((_e = this.series[i]) == null ? void 0 : _e[j]) / this.invertedYRatio
        ) : 0) * 2;
      }
      const paths = this.barHelpers.getBarpaths({
        barYPosition,
        barHeight,
        x1: barXPosition,
        x2: x,
        strokeWidth,
        isReversed: this.isReversed,
        series: this.series,
        realIndex: indexes.realIndex,
        seriesGroup,
        i,
        j,
        w
      });
      this.barHelpers.barBackground({
        j,
        i,
        y1: barYPosition,
        y2: barHeight,
        elSeries
      });
      y = y + yDivision;
      return {
        pathTo: paths.pathTo,
        pathFrom: paths.pathFrom,
        goalX: this.barHelpers.getGoalValues(
          "x",
          zeroW,
          /** @type {any} */
          null,
          i,
          j,
          translationsIndex
        ),
        barXPosition,
        barYPosition,
        x,
        y
      };
    }
    /** @param {{indexes: any, x: any, y: any, xDivision: any, barWidth: any, zeroH: any, columnGroupIndex: any, seriesGroup: any, elSeries: any}} opts */
    drawStackedColumnPaths({
      indexes,
      x,
      y,
      xDivision,
      barWidth,
      zeroH,
      columnGroupIndex,
      seriesGroup,
      elSeries
    }) {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i;
      const w = this.w;
      const i = indexes.i;
      const j = indexes.j;
      const bc = indexes.bc;
      const realIndex = indexes.realIndex;
      const translationsIndex = indexes.translationsIndex;
      if (w.axisFlags.isXNumeric) {
        let seriesVal = w.seriesData.seriesX[realIndex][j];
        if (!seriesVal) seriesVal = 0;
        x = (seriesVal - w.globals.minX) / this.xRatio - barWidth / 2 * w.globals.barGroups.length;
      }
      const barXPosition = x + columnGroupIndex * barWidth;
      let barYPosition;
      let prevBarH = 0;
      for (let k = 0; k < this.groupCtx.prevYF.length; k++) {
        prevBarH = prevBarH + (!isNaN(this.groupCtx.prevYF[k][j]) ? this.groupCtx.prevYF[k][j] : 0);
      }
      let gsi = i;
      if (seriesGroup) {
        gsi = seriesGroup.indexOf(w.seriesData.seriesNames[realIndex]);
      }
      if (gsi > 0 && !w.axisFlags.isXNumeric || gsi > 0 && w.axisFlags.isXNumeric && w.seriesData.seriesX[realIndex - 1][j] === w.seriesData.seriesX[realIndex][j]) {
        let bYP;
        let prevYValue;
        const p = Math.min(this.yRatio.length + 1, realIndex + 1);
        if (this.groupCtx.prevY[gsi - 1] !== void 0 && this.groupCtx.prevY[gsi - 1].length) {
          for (let ii = 1; ii < p; ii++) {
            if (!isNaN((_a = this.groupCtx.prevY[gsi - ii]) == null ? void 0 : _a[j])) {
              prevYValue = this.groupCtx.prevY[gsi - ii][j];
              break;
            }
          }
        }
        for (let ii = 1; ii < p; ii++) {
          if (((_b = this.groupCtx.prevYVal[gsi - ii]) == null ? void 0 : _b[j]) < 0) {
            bYP = /** @type {any} */
            ((_c = this.series[i]) == null ? void 0 : _c[j]) >= 0 ? prevYValue - prevBarH + (this.isReversed ? prevBarH : 0) * 2 : prevYValue;
            break;
          } else if (((_d = this.groupCtx.prevYVal[gsi - ii]) == null ? void 0 : _d[j]) >= 0) {
            bYP = /** @type {any} */
            ((_e = this.series[i]) == null ? void 0 : _e[j]) >= 0 ? prevYValue : prevYValue + prevBarH - (this.isReversed ? prevBarH : 0) * 2;
            break;
          }
        }
        if (typeof bYP === "undefined") bYP = w.layout.gridHeight;
        if (
          /**
           * @param {number} val
           */
          ((_f = this.groupCtx.prevYF[0]) == null ? void 0 : _f.every((val) => val === 0)) && this.groupCtx.prevYF.slice(1, gsi).every(
            (arr) => arr.every((val) => isNaN(val))
          )
        ) {
          barYPosition = zeroH;
        } else {
          barYPosition = bYP;
        }
      } else {
        barYPosition = zeroH;
      }
      if (
        /** @type {any} */
        (_g = this.series[i]) == null ? void 0 : _g[j]
      ) {
        y = barYPosition - /** @type {any} */
        ((_h = this.series[i]) == null ? void 0 : _h[j]) / this.yRatio[translationsIndex] + (this.isReversed ? (
          /** @type {any} */
          ((_i = this.series[i]) == null ? void 0 : _i[j]) / this.yRatio[translationsIndex]
        ) : 0) * 2;
      } else {
        y = barYPosition;
      }
      const paths = this.barHelpers.getColumnPaths({
        barXPosition,
        barWidth,
        y1: barYPosition,
        y2: y,
        yRatio: this.yRatio[translationsIndex],
        strokeWidth: this.strokeWidth,
        isReversed: this.isReversed,
        series: this.series,
        seriesGroup,
        realIndex: indexes.realIndex,
        i,
        j,
        w
      });
      this.barHelpers.barBackground({
        bc,
        j,
        i,
        x1: barXPosition,
        x2: barWidth,
        elSeries
      });
      return {
        pathTo: paths.pathTo,
        pathFrom: paths.pathFrom,
        goalY: this.barHelpers.getGoalValues(
          "y",
          /** @type {any} */
          null,
          zeroH,
          i,
          j,
          0
        ),
        barXPosition,
        x: w.axisFlags.isXNumeric ? x : x + xDivision,
        y
      };
    }
  }
  class BoxCandleStick extends Bar {
    /**
     * @param {any[]} series
     * @param {string} ctype
     * @param {number} seriesIndex
     */
    // @ts-ignore -- BoxCandleStick.draw has an extra ctype param compared to Bar.draw
    draw(series, ctype, seriesIndex) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const type = w.globals.comboCharts ? ctype : w.config.chart.type;
      const fill = new Fill(this.w);
      this.candlestickOptions = this.w.config.plotOptions.candlestick;
      this.boxOptions = this.w.config.plotOptions.boxPlot;
      this.isHorizontal = w.config.plotOptions.bar.horizontal;
      this.isOHLC = this.candlestickOptions && this.candlestickOptions.type === "ohlc";
      this.coreUtils = new CoreUtils(this.w);
      series = this.coreUtils.getLogSeries(series);
      this.series = series;
      this.yRatio = this.coreUtils.getLogYRatios(this.yRatio);
      this.barHelpers.initVariables(series);
      const ret = graphics.group({
        class: `apexcharts-${type}-series apexcharts-plot-series`
      });
      for (let i = 0; i < series.length; i++) {
        this.isBoxPlot = w.config.chart.type === "boxPlot" || /** @type {Record<string,any>} */
        w.config.series[i].type === "boxPlot";
        let x;
        let y;
        const yArrj = [];
        const xArrj = [];
        const realIndex = w.globals.comboCharts ? (
          /** @type {any} */
          seriesIndex[i]
        ) : i;
        const { columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
        const elSeries = graphics.group({
          class: `apexcharts-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
          rel: i + 1,
          "data:realIndex": realIndex
        });
        Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
        if (series[i].length > 0) {
          this.visibleI = this.visibleI + 1;
        }
        let translationsIndex = 0;
        if (this.yRatio.length > 1) {
          this.yaxisIndex = /** @type {any} */
          w.globals.seriesYAxisReverseMap[realIndex][0];
          translationsIndex = realIndex;
        }
        const initPositions = this.barHelpers.initialPositions(realIndex);
        const {
          y: initY,
          barHeight,
          yDivision,
          // yDivision is the GRIDHEIGHT divided by number of datapoints (bars)
          zeroW,
          // zeroW is the baseline where 0 meets x axis
          x: initX,
          barWidth,
          xDivision,
          // xDivision is the GRIDWIDTH divided by number of datapoints (columns)
          zeroH
          // zeroH is the baseline where 0 meets y axis
        } = initPositions;
        y = initY;
        x = initX;
        xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
        const elDataLabelsWrap = graphics.group({
          class: "apexcharts-datalabels",
          "data:realIndex": realIndex
        });
        const elGoalsMarkers = graphics.group({
          class: "apexcharts-bar-goals-markers"
        });
        for (let j = 0; j < w.globals.dataPoints; j++) {
          const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
          let paths = (
            /** @type {any} */
            null
          );
          const pathsParams = {
            indexes: {
              i,
              j,
              realIndex,
              translationsIndex
            },
            x,
            y,
            strokeWidth,
            elSeries
          };
          if (this.isHorizontal) {
            paths = this.drawHorizontalBoxPaths(__spreadProps(__spreadValues({}, pathsParams), {
              yDivision,
              barHeight,
              zeroW
            }));
          } else {
            paths = this.drawVerticalBoxPaths(__spreadProps(__spreadValues({}, pathsParams), {
              xDivision,
              barWidth,
              zeroH
            }));
          }
          y = paths.y;
          x = paths.x;
          const barGoalLine = this.barHelpers.drawGoalLine({
            barXPosition: paths.barXPosition,
            barYPosition: paths.barYPosition,
            goalX: paths.goalX,
            goalY: paths.goalY,
            barHeight,
            barWidth
          });
          if (barGoalLine) {
            elGoalsMarkers.add(barGoalLine);
          }
          if (j > 0) {
            xArrj.push(x + (barWidth != null ? barWidth : 0) / 2);
          }
          yArrj.push(y);
          paths.pathTo.forEach(
            (pathTo, pi) => {
              const lineFill = !this.isBoxPlot && this.candlestickOptions.wick.useFillColor ? paths.color[pi] : w.globals.stroke.colors[i];
              const pathFill = fill.fillPath({
                seriesNumber: realIndex,
                dataPointIndex: j,
                color: paths.color[pi],
                value: series[i][j]
              });
              this.renderSeries({
                realIndex,
                pathFill,
                lineFill,
                j,
                i,
                pathFrom: paths.pathFrom,
                pathTo,
                strokeWidth,
                elSeries,
                x,
                y,
                series,
                columnGroupIndex,
                barHeight,
                barWidth,
                elDataLabelsWrap,
                elGoalsMarkers,
                visibleSeries: this.visibleI,
                type: w.config.chart.type
              });
            }
          );
        }
        w.globals.seriesXvalues[realIndex] = xArrj;
        w.globals.seriesYvalues[realIndex] = yArrj;
        ret.add(elSeries);
      }
      return ret;
    }
    /** @param {{indexes: any, x: any, xDivision: any, barWidth: any, zeroH: any, strokeWidth: any}} opts */
    drawVerticalBoxPaths({
      indexes,
      x,
      xDivision,
      barWidth,
      zeroH,
      strokeWidth
    }) {
      var _a, _b;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const i = indexes.i;
      const j = indexes.j;
      const { colors: candleColors } = w.config.plotOptions.candlestick;
      const { colors: boxColors } = this.boxOptions;
      const realIndex = indexes.realIndex;
      const getColor = (color2) => Array.isArray(color2) ? color2[realIndex] : color2;
      const colorPos = getColor(candleColors.upward);
      const colorNeg = getColor(candleColors.downward);
      const yRatio = this.yRatio[indexes.translationsIndex];
      const ohlc = this.getOHLCValue(realIndex, j);
      let l1 = zeroH;
      let l2 = zeroH;
      let color = ohlc.o < ohlc.c ? [colorPos] : [colorNeg];
      if (this.isBoxPlot) {
        color = [getColor(boxColors.lower), getColor(boxColors.upper)];
      }
      let y1 = Math.min(ohlc.o, ohlc.c);
      let y2 = Math.max(ohlc.o, ohlc.c);
      let m = ohlc.m;
      if (w.axisFlags.isXNumeric) {
        x = (w.seriesData.seriesX[realIndex][j] - w.globals.minX) / this.xRatio - barWidth / 2;
      }
      const barXPosition = x + barWidth * this.visibleI;
      if (typeof /** @type {any} */
      ((_a = this.series[i]) == null ? void 0 : _a[j]) === "undefined" || /** @type {any} */
      ((_b = this.series[i]) == null ? void 0 : _b[j]) === null) {
        y1 = zeroH;
        y2 = zeroH;
      } else {
        y1 = zeroH - y1 / yRatio;
        y2 = zeroH - y2 / yRatio;
        l1 = zeroH - ohlc.h / yRatio;
        l2 = zeroH - ohlc.l / yRatio;
        m = zeroH - ohlc.m / yRatio;
      }
      let pathTo;
      let pathFrom = graphics.move(barXPosition + barWidth / 2, y1);
      if (w.globals.previousPaths.length > 0) {
        pathFrom = this.getPreviousPath(realIndex, j);
      }
      if (this.isOHLC) {
        const centerX = barXPosition + barWidth / 2;
        const openY = zeroH - ohlc.o / yRatio;
        const closeY = zeroH - ohlc.c / yRatio;
        pathTo = [
          graphics.move(centerX, l1) + graphics.line(centerX, l2) + graphics.move(centerX, openY) + graphics.line(barXPosition, openY) + graphics.move(centerX, closeY) + graphics.line(barXPosition + barWidth, closeY)
        ];
      } else if (this.isBoxPlot) {
        pathTo = [
          graphics.move(barXPosition, y1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 4, l1) + graphics.line(barXPosition + barWidth - barWidth / 4, l1) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition + barWidth, m) + graphics.line(barXPosition, m) + graphics.line(barXPosition, y1 + strokeWidth / 2),
          graphics.move(barXPosition, m) + graphics.line(barXPosition + barWidth, m) + graphics.line(barXPosition + barWidth, y2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth - barWidth / 4, l2) + graphics.line(barXPosition + barWidth / 4, l2) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition, y2) + graphics.line(barXPosition, m) + "z"
        ];
      } else {
        pathTo = [
          graphics.move(barXPosition, y2) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth / 2, l1) + graphics.line(barXPosition + barWidth / 2, y2) + graphics.line(barXPosition + barWidth, y2) + graphics.line(barXPosition + barWidth, y1) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition + barWidth / 2, l2) + graphics.line(barXPosition + barWidth / 2, y1) + graphics.line(barXPosition, y1) + graphics.line(barXPosition, y2 - strokeWidth / 2)
        ];
      }
      pathFrom = pathFrom + graphics.move(barXPosition, y1);
      if (!w.axisFlags.isXNumeric) {
        x = x + xDivision;
      }
      return {
        pathTo,
        pathFrom,
        x,
        y: y2,
        goalY: this.barHelpers.getGoalValues(
          "y",
          /** @type {any} */
          null,
          zeroH,
          i,
          j,
          indexes.translationsIndex
        ),
        barXPosition,
        color
      };
    }
    /** @param {{indexes: any, y: any, yDivision: any, barHeight: any, zeroW: any, strokeWidth: any}} opts */
    drawHorizontalBoxPaths({
      indexes,
      y,
      yDivision,
      barHeight,
      zeroW,
      strokeWidth
    }) {
      var _a, _b;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const i = indexes.i;
      const j = indexes.j;
      const realIndex = indexes.realIndex;
      const { colors: candleColors } = w.config.plotOptions.candlestick;
      const { colors: boxColors } = this.boxOptions;
      const getColor = (color2) => Array.isArray(color2) ? color2[realIndex] : color2;
      const yRatio = this.invertedYRatio;
      const ohlc = this.getOHLCValue(realIndex, j);
      let color = ohlc.o < ohlc.c ? [getColor(candleColors.upward)] : [getColor(candleColors.downward)];
      if (this.isBoxPlot) {
        color = [getColor(boxColors.lower), getColor(boxColors.upper)];
      }
      let l1 = zeroW;
      let l2 = zeroW;
      let x1 = Math.min(ohlc.o, ohlc.c);
      let x2 = Math.max(ohlc.o, ohlc.c);
      let m = ohlc.m;
      if (w.axisFlags.isXNumeric) {
        y = (w.seriesData.seriesX[realIndex][j] - w.globals.minX) / this.invertedXRatio - barHeight / 2;
      }
      const barYPosition = y + barHeight * this.visibleI;
      if (typeof /** @type {any} */
      ((_a = this.series[i]) == null ? void 0 : _a[j]) === "undefined" || /** @type {any} */
      ((_b = this.series[i]) == null ? void 0 : _b[j]) === null) {
        x1 = zeroW;
        x2 = zeroW;
      } else {
        x1 = zeroW + x1 / yRatio;
        x2 = zeroW + x2 / yRatio;
        l1 = zeroW + ohlc.h / yRatio;
        l2 = zeroW + ohlc.l / yRatio;
        m = zeroW + ohlc.m / yRatio;
      }
      let pathFrom = graphics.move(x1, barYPosition + barHeight / 2);
      if (w.globals.previousPaths.length > 0) {
        pathFrom = this.getPreviousPath(realIndex, j);
      }
      const pathTo = [
        graphics.move(x1, barYPosition) + graphics.line(x1, barYPosition + barHeight / 2) + graphics.line(l1, barYPosition + barHeight / 2) + graphics.line(l1, barYPosition + barHeight / 2 - barHeight / 4) + graphics.line(l1, barYPosition + barHeight / 2 + barHeight / 4) + graphics.line(l1, barYPosition + barHeight / 2) + graphics.line(x1, barYPosition + barHeight / 2) + graphics.line(x1, barYPosition + barHeight) + graphics.line(m, barYPosition + barHeight) + graphics.line(m, barYPosition) + graphics.line(x1 + strokeWidth / 2, barYPosition),
        graphics.move(m, barYPosition) + graphics.line(m, barYPosition + barHeight) + graphics.line(x2, barYPosition + barHeight) + graphics.line(x2, barYPosition + barHeight / 2) + graphics.line(l2, barYPosition + barHeight / 2) + graphics.line(l2, barYPosition + barHeight - barHeight / 4) + graphics.line(l2, barYPosition + barHeight / 4) + graphics.line(l2, barYPosition + barHeight / 2) + graphics.line(x2, barYPosition + barHeight / 2) + graphics.line(x2, barYPosition) + graphics.line(m, barYPosition) + "z"
      ];
      pathFrom = pathFrom + graphics.move(x1, barYPosition);
      if (!w.axisFlags.isXNumeric) {
        y = y + yDivision;
      }
      return {
        pathTo,
        pathFrom,
        x: x2,
        y,
        goalX: this.barHelpers.getGoalValues(
          "x",
          zeroW,
          /** @type {any} */
          null,
          i,
          j,
          0
        ),
        barYPosition,
        color
      };
    }
    /**
     * @param {number} i
     * @param {number} j
     */
    getOHLCValue(i, j) {
      const w = this.w;
      const coreUtils = this.coreUtils;
      const getCandleVal = (arr) => arr[i] && arr[i][j] != null ? (
        /** @type {any} */
        coreUtils.getLogValAtSeriesIndex(arr[i][j], i)
      ) : 0;
      const h = getCandleVal(w.candleData.seriesCandleH);
      const o = getCandleVal(w.candleData.seriesCandleO);
      const m = getCandleVal(w.candleData.seriesCandleM);
      const c = getCandleVal(w.candleData.seriesCandleC);
      const l = getCandleVal(w.candleData.seriesCandleL);
      return {
        o: this.isBoxPlot ? h : o,
        h: this.isBoxPlot ? o : h,
        m,
        l: this.isBoxPlot ? c : l,
        c: this.isBoxPlot ? l : c
      };
    }
  }
  class TreemapHelpers {
    /**
     * @param {import('../../../types/internal').ChartStateW} w
     * @param {import('../../../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.ctx = ctx;
      this.w = w;
    }
    checkColorRange() {
      const w = this.w;
      let negRange = false;
      const chartOpts = w.config.plotOptions[w.config.chart.type];
      if (chartOpts.colorScale.ranges.length > 0) {
        chartOpts.colorScale.ranges.map((range) => {
          if (range.from <= 0) {
            negRange = true;
          }
        });
      }
      return negRange;
    }
    /**
     * @param {string} chartType
     * @param {number} i
     * @param {number} j
     * @param {any} negRange
     */
    getShadeColor(chartType, i, j, negRange) {
      const w = this.w;
      let colorShadePercent = 1;
      const shadeIntensity = w.config.plotOptions[chartType].shadeIntensity;
      const colorProps = this.determineColor(chartType, i, j);
      if (
        /** @type {any} */
        w.globals.hasNegs || negRange
      ) {
        if (w.config.plotOptions[chartType].reverseNegativeShade) {
          if (colorProps.percent < 0) {
            colorShadePercent = colorProps.percent / 100 * (shadeIntensity * 1.25);
          } else {
            colorShadePercent = (1 - colorProps.percent / 100) * (shadeIntensity * 1.25);
          }
        } else {
          if (colorProps.percent <= 0) {
            colorShadePercent = 1 - (1 + colorProps.percent / 100) * shadeIntensity;
          } else {
            colorShadePercent = (1 - colorProps.percent / 100) * shadeIntensity;
          }
        }
      } else {
        colorShadePercent = 1 - colorProps.percent / 100;
        if (chartType === "treemap") {
          colorShadePercent = (1 - colorProps.percent / 100) * (shadeIntensity * 1.25);
        }
      }
      let color = colorProps.color;
      const utils = new Utils$1();
      if (w.config.plotOptions[chartType].enableShades) {
        if (this.w.config.theme.mode === "dark") {
          const shadeColor = utils.shadeColor(
            colorShadePercent * -1,
            colorProps.color
          );
          color = Utils$1.hexToRgba(
            Utils$1.isColorHex(shadeColor) ? shadeColor : Utils$1.rgb2hex(shadeColor),
            w.config.fill.opacity
          );
        } else {
          const shadeColor = utils.shadeColor(colorShadePercent, colorProps.color);
          color = Utils$1.hexToRgba(
            Utils$1.isColorHex(shadeColor) ? shadeColor : Utils$1.rgb2hex(shadeColor),
            w.config.fill.opacity
          );
        }
      }
      return { color, colorProps };
    }
    /**
     * @param {string} chartType
     * @param {number} i
     * @param {number} j
     */
    determineColor(chartType, i, j) {
      const w = this.w;
      const val = w.seriesData.series[i][j];
      const chartOpts = w.config.plotOptions[chartType];
      let seriesNumber = chartOpts.colorScale.inverse ? j : i;
      if (chartOpts.distributed && w.config.chart.type === "treemap") {
        seriesNumber = j;
      }
      let color = w.globals.colors[seriesNumber];
      let foreColor = null;
      let min = Math.min(...w.seriesData.series[i]);
      let max = Math.max(...w.seriesData.series[i]);
      if (!chartOpts.distributed && chartType === "heatmap") {
        min = w.globals.minY;
        max = w.globals.maxY;
      }
      if (typeof chartOpts.colorScale.min !== "undefined") {
        min = chartOpts.colorScale.min < w.globals.minY ? chartOpts.colorScale.min : w.globals.minY;
        max = chartOpts.colorScale.max > w.globals.maxY ? chartOpts.colorScale.max : w.globals.maxY;
      }
      const total = Math.abs(max) + Math.abs(min);
      let percent = 100 * val / (total === 0 ? total - 1e-6 : total);
      if (chartOpts.colorScale.ranges.length > 0) {
        const colorRange = chartOpts.colorScale.ranges;
        colorRange.map((range) => {
          if (val >= range.from && val <= range.to) {
            color = range.color;
            foreColor = range.foreColor ? range.foreColor : null;
            min = range.from;
            max = range.to;
            const rTotal = Math.abs(max) + Math.abs(min);
            percent = 100 * val / (rTotal === 0 ? rTotal - 1e-6 : rTotal);
          }
        });
      }
      return {
        color,
        foreColor,
        percent
      };
    }
    /** @param {{ text?: any, x?: any, y?: any, i?: any, j?: any, colorProps?: any, fontSize?: any, series?: any }} opts */
    calculateDataLabels({ text, x, y, i, j, colorProps, fontSize }) {
      const w = this.w;
      const dataLabelsConfig = w.config.dataLabels;
      const graphics = new Graphics(this.w);
      const dataLabels = new DataLabels(this.w, this.ctx);
      let elDataLabelsWrap = null;
      if (dataLabelsConfig.enabled) {
        elDataLabelsWrap = graphics.group({
          class: "apexcharts-data-labels"
        });
        const offX = dataLabelsConfig.offsetX;
        const offY = dataLabelsConfig.offsetY;
        const dataLabelsX = x + offX;
        const dataLabelsY = y + parseFloat(dataLabelsConfig.style.fontSize) / 3 + offY;
        dataLabels.plotDataLabelsText({
          x: dataLabelsX,
          y: dataLabelsY,
          text,
          i,
          j,
          color: colorProps.foreColor,
          parent: elDataLabelsWrap,
          fontSize,
          dataLabelsConfig
        });
      }
      return elDataLabelsWrap;
    }
  }
  class HeatMap {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     * @param {import('../types/internal').XYRatios} xyRatios
     */
    constructor(w, ctx, xyRatios) {
      this.ctx = ctx;
      this.w = w;
      this.xRatio = xyRatios.xRatio;
      this.yRatio = xyRatios.yRatio;
      this.dynamicAnim = this.w.config.chart.animations.dynamicAnimation;
      this.helpers = new TreemapHelpers(w, ctx);
      this.rectRadius = this.w.config.plotOptions.heatmap.radius;
      this.strokeWidth = this.w.config.stroke.show ? this.w.config.stroke.width : 0;
    }
    /**
     * @param {any[]} series
     */
    draw(series) {
      const w = this.w;
      const graphics = new Graphics(this.w, this.ctx);
      const ret = graphics.group({
        class: "apexcharts-heatmap"
      });
      ret.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
      const xDivision = w.layout.gridWidth / w.globals.dataPoints;
      const yDivision = w.layout.gridHeight / w.seriesData.series.length;
      let y1 = 0;
      let rev = false;
      this.negRange = this.helpers.checkColorRange();
      const heatSeries = series.slice();
      if (w.config.yaxis[0].reversed) {
        rev = true;
        heatSeries.reverse();
      }
      for (let i = rev ? 0 : heatSeries.length - 1; rev ? i < heatSeries.length : i >= 0; rev ? i++ : i--) {
        const elSeries = graphics.group({
          class: `apexcharts-series apexcharts-heatmap-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
          rel: i + 1,
          "data:realIndex": i
        });
        Series.addCollapsedClassToSeries(this.w, elSeries, i);
        graphics.setupEventDelegation(elSeries, ".apexcharts-heatmap-rect");
        if (w.config.chart.dropShadow.enabled) {
          const shadow = w.config.chart.dropShadow;
          const filters = new Filters(this.w);
          filters.dropShadow(elSeries, shadow, i);
        }
        let x1 = 0;
        const shadeIntensity = w.config.plotOptions.heatmap.shadeIntensity;
        let j = 0;
        for (let dIndex = 0; dIndex < w.globals.dataPoints; dIndex++) {
          if (w.seriesData.seriesX.length && !w.globals.allSeriesHasEqualX) {
            if (w.globals.minX + w.globals.minXDiff * dIndex < w.seriesData.seriesX[i][j]) {
              x1 = x1 + xDivision;
              continue;
            }
          }
          if (j >= heatSeries[i].length) break;
          const heatColor = this.helpers.getShadeColor(
            w.config.chart.type,
            i,
            j,
            this.negRange
          );
          let color = heatColor.color;
          const heatColorProps = heatColor.colorProps;
          if (w.config.fill.type === "image") {
            const fill = new Fill(this.w);
            color = fill.fillPath({
              seriesNumber: i,
              dataPointIndex: j,
              opacity: (
                /** @type {any} */
                w.globals.hasNegs ? heatColorProps.percent < 0 ? 1 - (1 + heatColorProps.percent / 100) : shadeIntensity + heatColorProps.percent / 100 : heatColorProps.percent / 100
              ),
              patternID: Utils$1.randomId(),
              width: w.config.fill.image.width ? w.config.fill.image.width : xDivision,
              height: w.config.fill.image.height ? w.config.fill.image.height : yDivision
            });
          }
          const radius = this.rectRadius;
          const rect = graphics.drawRect(x1, y1, xDivision, yDivision, radius);
          rect.attr({
            cx: x1,
            cy: y1
          });
          rect.node.classList.add("apexcharts-heatmap-rect");
          elSeries.add(rect);
          rect.attr({
            fill: color,
            i,
            index: i,
            j,
            val: series[i][j],
            "stroke-width": this.strokeWidth,
            stroke: w.config.plotOptions.heatmap.useFillColorAsStroke ? color : w.globals.stroke.colors[0],
            color
          });
          if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
            let speed = 1;
            if (!w.globals.resized) {
              speed = w.config.chart.animations.speed;
            }
            this.animateHeatMap(rect, x1, y1, xDivision, yDivision, speed);
          }
          if (w.globals.dataChanged) {
            let speed = 1;
            if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
              speed = this.dynamicAnim.speed;
              let colorFrom = w.globals.previousPaths[i] && w.globals.previousPaths[i][j] && w.globals.previousPaths[i][j].color;
              if (!colorFrom) colorFrom = "rgba(255, 255, 255, 0)";
              this.animateHeatColor(
                rect,
                Utils$1.isColorHex(colorFrom) ? colorFrom : Utils$1.rgb2hex(colorFrom),
                Utils$1.isColorHex(color) ? color : Utils$1.rgb2hex(color),
                speed
              );
            }
          }
          const formatter = w.config.dataLabels.formatter;
          const formattedText = formatter(w.seriesData.series[i][j], {
            value: w.seriesData.series[i][j],
            seriesIndex: i,
            dataPointIndex: j,
            w
          });
          const dataLabels = this.helpers.calculateDataLabels({
            text: formattedText,
            x: x1 + xDivision / 2,
            y: y1 + yDivision / 2,
            i,
            j,
            colorProps: heatColorProps,
            series: heatSeries
          });
          if (dataLabels !== null) {
            elSeries.add(dataLabels);
          }
          x1 = x1 + xDivision;
          j++;
        }
        y1 = y1 + yDivision;
        ret.add(elSeries);
      }
      const yAxisScale = (
        /** @type {any[]} */
        w.globals.yAxisScale[0].result.slice()
      );
      if (w.config.yaxis[0].reversed) {
        yAxisScale.unshift("");
      } else {
        yAxisScale.push("");
      }
      w.globals.yAxisScale[0].result = yAxisScale;
      return ret;
    }
    /**
     * @param {any} el
     * @param {number} x
     * @param {number} y
     * @param {number} width
     * @param {number} height
     * @param {number} speed
     */
    animateHeatMap(el, x, y, width, height, speed) {
      const animations = new Animations(this.w);
      animations.animateRect(
        el,
        {
          x: x + width / 2,
          y: y + height / 2,
          width: 0,
          height: 0
        },
        {
          x,
          y,
          width,
          height
        },
        speed,
        () => {
          animations.animationCompleted(el);
        }
      );
    }
    /**
     * @param {any} el
     * @param {string} colorFrom
     * @param {string} colorTo
     * @param {number} speed
     */
    animateHeatColor(el, colorFrom, colorTo, speed) {
      el.attr({
        fill: colorFrom
      }).animate(speed).attr({
        fill: colorTo
      });
    }
  }
  class Helpers {
    /**
     * @param {import('../../../charts/Line').default} lineCtx
     */
    constructor(lineCtx) {
      this.w = lineCtx.w;
      this.lineCtx = lineCtx;
    }
    /**
     * @param {number} i
     * @param {any[]} series
     */
    sameValueSeriesFix(i, series) {
      const w = this.w;
      if (w.config.fill.type === "gradient" || w.config.fill.type[i] === "gradient") {
        const coreUtils = new CoreUtils(this.lineCtx.w);
        if (coreUtils.seriesHaveSameValues(i)) {
          const gSeries = series[i].slice();
          gSeries[gSeries.length - 1] = gSeries[gSeries.length - 1] + 1e-6;
          series[i] = gSeries;
        }
      }
      return series;
    }
    /** @param {{series: any, realIndex: any, x: any, y: any, i: any, j: any, prevY: any}} opts */
    calculatePoints({ series, realIndex, x, y, i, j, prevY }) {
      const w = this.w;
      const ptX = [];
      const ptY = [];
      let xPT1st = this.lineCtx.categoryAxisCorrection + w.config.markers.offsetX;
      if (w.axisFlags.isXNumeric) {
        xPT1st = (w.seriesData.seriesX[realIndex][0] - w.globals.minX) / this.lineCtx.xRatio + w.config.markers.offsetX;
      }
      if (j === 0) {
        ptX.push(xPT1st);
        ptY.push(
          Utils$1.isNumber(series[i][0]) ? prevY + w.config.markers.offsetY : null
        );
      }
      ptX.push(x + w.config.markers.offsetX);
      ptY.push(
        Utils$1.isNumber(series[i][j + 1]) ? y + w.config.markers.offsetY : null
      );
      return {
        x: ptX,
        y: ptY
      };
    }
    /** @param {{pathFromLine: any, pathFromArea: any, realIndex: any}} opts */
    checkPreviousPaths({ pathFromLine, pathFromArea, realIndex }) {
      const w = this.w;
      for (let pp = 0; pp < w.globals.previousPaths.length; pp++) {
        const gpp = w.globals.previousPaths[pp];
        if ((gpp.type === "line" || gpp.type === "area") && gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(realIndex, 10)) {
          if (gpp.type === "line") {
            this.lineCtx.appendPathFrom = false;
            pathFromLine = w.globals.previousPaths[pp].paths[0].d;
          } else if (gpp.type === "area") {
            this.lineCtx.appendPathFrom = false;
            pathFromArea = w.globals.previousPaths[pp].paths[0].d;
            if (w.config.stroke.show && w.globals.previousPaths[pp].paths[1]) {
              pathFromLine = w.globals.previousPaths[pp].paths[1].d;
            }
          }
        }
      }
      return {
        pathFromLine,
        pathFromArea
      };
    }
    /** @param {{i: any, realIndex: any, series: any, prevY: any, lineYPosition: any, translationsIndex: any}} opts */
    determineFirstPrevY({
      i,
      realIndex,
      series,
      prevY,
      lineYPosition,
      translationsIndex
    }) {
      var _a, _b, _c;
      const w = this.w;
      const stackSeries = w.config.chart.stacked && !w.globals.comboCharts || w.config.chart.stacked && w.globals.comboCharts && (!this.w.config.chart.stackOnlyBar || /** @type {any} */
      ((_a = this.w.config.series[realIndex]) == null ? void 0 : _a.type) === "bar" || /** @type {any} */
      ((_b = this.w.config.series[realIndex]) == null ? void 0 : _b.type) === "column");
      if (typeof ((_c = series[i]) == null ? void 0 : _c[0]) !== "undefined") {
        if (stackSeries) {
          if (i > 0) {
            lineYPosition = this.lineCtx.prevSeriesY[i - 1][0];
          } else {
            lineYPosition = this.lineCtx.zeroY;
          }
        } else {
          lineYPosition = this.lineCtx.zeroY;
        }
        prevY = lineYPosition - series[i][0] / this.lineCtx.yRatio[translationsIndex] + (this.lineCtx.isReversed ? series[i][0] / this.lineCtx.yRatio[translationsIndex] : 0) * 2;
      } else {
        if (stackSeries && i > 0 && typeof series[i][0] === "undefined") {
          for (let s = i - 1; s >= 0; s--) {
            if (series[s][0] !== null && typeof series[s][0] !== "undefined") {
              lineYPosition = this.lineCtx.prevSeriesY[s][0];
              prevY = lineYPosition;
              break;
            }
          }
        }
      }
      return {
        prevY,
        lineYPosition
      };
    }
  }
  const tangents = (points) => {
    const m = finiteDifferences(points);
    const n = points.length - 1;
    const ε = 1e-6;
    const tgts = [];
    let a, b, d, s;
    for (let i = 0; i < n; i++) {
      d = slope(points[i], points[i + 1]);
      if (Math.abs(d) < ε) {
        m[i] = m[i + 1] = 0;
      } else {
        a = m[i] / d;
        b = m[i + 1] / d;
        s = a * a + b * b;
        if (s > 9) {
          s = d * 3 / Math.sqrt(s);
          m[i] = s * a;
          m[i + 1] = s * b;
        }
      }
    }
    for (let i = 0; i <= n; i++) {
      s = (points[Math.min(n, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i]));
      tgts.push([s || 0, m[i] * s || 0]);
    }
    return tgts;
  };
  const svgPath = (points) => {
    let p = "";
    for (let i = 0; i < points.length; i++) {
      const point = points[i];
      const n = point.length;
      if (n > 4) {
        p += `C${point[0]}, ${point[1]}`;
        p += `, ${point[2]}, ${point[3]}`;
        p += `, ${point[4]}, ${point[5]}`;
      } else if (n > 2) {
        p += `S${point[0]}, ${point[1]}`;
        p += `, ${point[2]}, ${point[3]}`;
      }
    }
    return p;
  };
  const spline = {
    /**
     * Convert 'points' to bezier
     * @param {any[]} points
     * @returns {any[]}
     */
    points(points) {
      const tgts = tangents(points);
      const p = points[1];
      const p0 = points[0];
      const pts = [];
      const t = tgts[1];
      const t0 = tgts[0];
      pts.push(p0, [
        p0[0] + t0[0],
        p0[1] + t0[1],
        p[0] - t[0],
        p[1] - t[1],
        p[0],
        p[1]
      ]);
      for (let i = 2, n = tgts.length; i < n; i++) {
        const p2 = points[i];
        const t2 = tgts[i];
        pts.push([p2[0] - t2[0], p2[1] - t2[1], p2[0], p2[1]]);
      }
      return pts;
    },
    /**
     * Slice out a segment of 'points'
     * @param {any[]} points
     * @param {Number} start
     * @param {Number} end
     * @returns {any[]}
     */
    slice(points, start, end) {
      const pts = points.slice(start, end);
      if (start) {
        if (end - start > 1 && pts[1].length < 6) {
          const n = pts[0].length;
          pts[1] = [
            pts[0][n - 2] * 2 - pts[0][n - 4],
            pts[0][n - 1] * 2 - pts[0][n - 3]
          ].concat(pts[1]);
        }
        pts[0] = pts[0].slice(-2);
      }
      return pts;
    }
  };
  function slope(p0, p1) {
    return (p1[1] - p0[1]) / (p1[0] - p0[0]);
  }
  function finiteDifferences(points) {
    const m = [];
    let p0 = points[0];
    let p1 = points[1];
    let d = m[0] = slope(p0, p1);
    let i = 1;
    for (let n = points.length - 1; i < n; i++) {
      p0 = p1;
      p1 = points[i + 1];
      m[i] = (d + (d = slope(p0, p1))) * 0.5;
    }
    m[i] = d;
    return m;
  }
  class Line {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     * @param {import('../types/internal').XYRatios} xyRatios
     * @param {boolean} isPointsChart
     */
    constructor(w, ctx, xyRatios, isPointsChart) {
      this.ctx = ctx;
      this.w = w;
      this.xyRatios = xyRatios;
      this.xRatio = 0;
      this.yRatio = [];
      this.zRatio = 0;
      this.baseLineY = [];
      this.pointsChart = !(this.w.config.chart.type !== "bubble" && this.w.config.chart.type !== "scatter") || isPointsChart;
      this.scatter = new Scatter(this.w, this.ctx);
      this.noNegatives = this.w.globals.minX === Number.MAX_VALUE;
      this.lineHelpers = new Helpers(this);
      this.markers = new Markers(this.w, this.ctx);
      this.prevSeriesY = [];
      this.categoryAxisCorrection = 0;
      this.yaxisIndex = 0;
      this.xDivision = 0;
      this.zeroY = 0;
      this.areaBottomY = 0;
      this.strokeWidth = 0;
      this.isReversed = false;
      this.appendPathFrom = false;
      this.elSeries = null;
      this.elPointsMain = null;
      this.elDataLabelsWrap = null;
    }
    /**
     * @param {any[]} series
     * @param {string} ctype
     * @param {number} seriesIndex
     * @param {any} seriesRangeEnd
     */
    draw(series, ctype, seriesIndex, seriesRangeEnd) {
      var _a;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const type = w.globals.comboCharts ? ctype : w.config.chart.type;
      const ret = graphics.group({
        class: `apexcharts-${type}-series apexcharts-plot-series`
      });
      const coreUtils = new CoreUtils(this.w);
      this.yRatio = this.xyRatios.yRatio;
      this.zRatio = this.xyRatios.zRatio;
      this.xRatio = this.xyRatios.xRatio;
      this.baseLineY = this.xyRatios.baseLineY;
      series = coreUtils.getLogSeries(series);
      this.yRatio = coreUtils.getLogYRatios(this.yRatio);
      this.prevSeriesY = [];
      const allSeries = [];
      for (let i = 0; i < series.length; i++) {
        series = this.lineHelpers.sameValueSeriesFix(i, series);
        const realIndex = w.globals.comboCharts ? (
          /** @type {any} */
          seriesIndex[i]
        ) : i;
        const translationsIndex = this.yRatio.length > 1 ? realIndex : 0;
        this._initSerieVariables(series, i, realIndex);
        const yArrj = [];
        const y2Arrj = [];
        const xArrj = [];
        let x = w.globals.padHorizontal + this.categoryAxisCorrection;
        const y = 1;
        const linePaths = [];
        const areaPaths = [];
        Series.addCollapsedClassToSeries(this.w, this.elSeries, realIndex);
        if (w.axisFlags.isXNumeric && w.seriesData.seriesX.length > 0) {
          x = (w.seriesData.seriesX[realIndex][0] - w.globals.minX) / this.xRatio;
        }
        xArrj.push(x);
        const pX = x;
        let pY2;
        const prevX = pX;
        let prevY = this.zeroY;
        let prevY2 = this.zeroY;
        const lineYPosition = 0;
        const firstPrevY = this.lineHelpers.determineFirstPrevY({
          i,
          realIndex,
          series,
          prevY,
          lineYPosition,
          translationsIndex
        });
        prevY = firstPrevY.prevY;
        if (w.config.stroke.curve === "monotoneCubic" && series[i][0] === null) {
          yArrj.push(null);
        } else {
          yArrj.push(prevY);
        }
        const pY = prevY;
        let firstPrevY2;
        if (type === "rangeArea") {
          firstPrevY2 = this.lineHelpers.determineFirstPrevY({
            i,
            realIndex,
            series: seriesRangeEnd,
            prevY: prevY2,
            lineYPosition,
            translationsIndex
          });
          prevY2 = firstPrevY2.prevY;
          pY2 = prevY2;
          y2Arrj.push(yArrj[0] !== null ? prevY2 : null);
        }
        const pathsFrom = this._calculatePathsFrom({
          type,
          series,
          i,
          realIndex,
          translationsIndex,
          prevX,
          prevY,
          prevY2
        });
        const rYArrj = [yArrj[0]];
        const rY2Arrj = [y2Arrj[0]];
        const iteratingOpts = {
          type,
          series,
          realIndex,
          translationsIndex,
          i,
          x,
          y,
          pX,
          pY,
          pathsFrom,
          linePaths,
          areaPaths,
          seriesIndex,
          lineYPosition,
          xArrj,
          yArrj,
          y2Arrj,
          seriesRangeEnd
        };
        const paths = this._iterateOverDataPoints(__spreadProps(__spreadValues({}, iteratingOpts), {
          iterations: type === "rangeArea" ? series[i].length - 1 : void 0,
          isRangeStart: true
        }));
        if (type === "rangeArea") {
          const pathsFrom2 = this._calculatePathsFrom({
            series: seriesRangeEnd,
            i,
            realIndex,
            prevX,
            prevY: prevY2
          });
          const rangePaths = this._iterateOverDataPoints(__spreadProps(__spreadValues({}, iteratingOpts), {
            series: seriesRangeEnd,
            xArrj: [x],
            yArrj: rYArrj,
            y2Arrj: rY2Arrj,
            pY: pY2,
            areaPaths: paths.areaPaths,
            pathsFrom: pathsFrom2,
            iterations: seriesRangeEnd[i].length - 1,
            isRangeStart: false
          }));
          const segments = paths.linePaths.length / 2;
          for (let s = 0; s < segments; s++) {
            paths.linePaths[s] = rangePaths.linePaths[s + segments] + paths.linePaths[s];
          }
          paths.linePaths.splice(segments);
          paths.pathFromLine = rangePaths.pathFromLine + paths.pathFromLine;
        } else {
          paths.pathFromArea += "z";
        }
        this._handlePaths({ type, realIndex, i, paths });
        this.elSeries.add(this.elPointsMain);
        this.elSeries.add(this.elDataLabelsWrap);
        allSeries.push(this.elSeries);
      }
      if (typeof /** @type {Record<string,any>} */
      ((_a = w.config.series[0]) == null ? void 0 : _a.zIndex) !== "undefined") {
        allSeries.sort(
          (a, b) => Number(a.node.getAttribute("zIndex")) - Number(b.node.getAttribute("zIndex"))
        );
      }
      if (w.config.chart.stacked) {
        for (let s = allSeries.length - 1; s >= 0; s--) {
          ret.add(allSeries[s]);
        }
      } else {
        for (let s = 0; s < allSeries.length; s++) {
          ret.add(allSeries[s]);
        }
      }
      return ret;
    }
    /**
     * @param {any[]} series
     * @param {number} i
     * @param {number} realIndex
     */
    _initSerieVariables(series, i, realIndex) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      this.xDivision = w.layout.gridWidth / (w.globals.dataPoints - (w.config.xaxis.tickPlacement === "on" ? 1 : 0));
      this.strokeWidth = Array.isArray(w.config.stroke.width) ? w.config.stroke.width[realIndex] : w.config.stroke.width;
      let translationsIndex = 0;
      if (this.yRatio.length > 1) {
        this.yaxisIndex = w.globals.seriesYAxisReverseMap[realIndex];
        translationsIndex = realIndex;
      }
      this.isReversed = w.config.yaxis[this.yaxisIndex] && w.config.yaxis[this.yaxisIndex].reversed;
      this.zeroY = w.layout.gridHeight - this.baseLineY[translationsIndex] - (this.isReversed ? w.layout.gridHeight : 0) + (this.isReversed ? this.baseLineY[translationsIndex] * 2 : 0);
      this.areaBottomY = this.zeroY;
      if (this.zeroY > w.layout.gridHeight || w.config.plotOptions.area.fillTo === "end") {
        this.areaBottomY = w.layout.gridHeight;
      }
      this.categoryAxisCorrection = this.xDivision / 2;
      const seriesItem = (
        /** @type {Record<string,any>} */
        w.config.series[realIndex]
      );
      this.elSeries = graphics.group({
        class: `apexcharts-series`,
        zIndex: typeof seriesItem.zIndex !== "undefined" ? seriesItem.zIndex : realIndex,
        seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex])
      });
      this.elPointsMain = graphics.group({
        class: "apexcharts-series-markers-wrap",
        "data:realIndex": realIndex
      });
      if (w.globals.hasNullValues) {
        const firstPoint = this.markers.plotChartMarkers({
          pointsPos: {
            x: [0],
            y: [w.layout.gridHeight + w.globals.markers.largestSize]
          },
          seriesIndex: i,
          j: 0,
          pSize: 0.1,
          alwaysDrawMarker: true,
          isVirtualPoint: true
        });
        if (firstPoint !== null) {
          this.elPointsMain.add(firstPoint);
        }
      }
      this.elDataLabelsWrap = graphics.group({
        class: "apexcharts-datalabels",
        "data:realIndex": realIndex
      });
      const longestSeries = series[i].length === w.globals.dataPoints;
      this.elSeries.attr({
        "data:longestSeries": longestSeries,
        rel: i + 1,
        "data:realIndex": realIndex
      });
      this.appendPathFrom = true;
    }
    /** @param {{ type?: any, series?: any, i?: any, realIndex?: any, translationsIndex?: any, prevX?: any, prevY?: any, prevY2?: any }} opts */
    _calculatePathsFrom({
      type,
      series,
      i,
      realIndex,
      translationsIndex,
      prevX,
      prevY,
      prevY2
    }) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      let linePath, areaPath, pathFromLine, pathFromArea;
      if (series[i][0] === null) {
        for (let s = 0; s < series[i].length; s++) {
          if (series[i][s] !== null) {
            prevX = this.xDivision * s;
            prevY = this.zeroY - series[i][s] / this.yRatio[translationsIndex];
            linePath = graphics.move(prevX, prevY);
            areaPath = graphics.move(prevX, this.areaBottomY);
            break;
          }
        }
      } else {
        linePath = graphics.move(prevX, prevY);
        if (type === "rangeArea") {
          linePath = graphics.move(prevX, prevY2) + graphics.line(prevX, prevY);
        }
        areaPath = graphics.move(prevX, this.areaBottomY) + graphics.line(prevX, prevY);
      }
      pathFromLine = graphics.move(0, this.areaBottomY) + graphics.line(0, this.areaBottomY);
      pathFromArea = graphics.move(0, this.areaBottomY) + graphics.line(0, this.areaBottomY);
      if (w.globals.previousPaths.length > 0) {
        const pathFrom = this.lineHelpers.checkPreviousPaths({
          pathFromLine,
          pathFromArea,
          realIndex
        });
        pathFromLine = pathFrom.pathFromLine;
        pathFromArea = pathFrom.pathFromArea;
      }
      return {
        prevX,
        prevY,
        linePath,
        areaPath,
        pathFromLine,
        pathFromArea
      };
    }
    /** @param {{type: any, realIndex: any, i: any, paths: any}} opts */
    _handlePaths({ type, realIndex, i, paths }) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const fill = new Fill(this.w);
      this.prevSeriesY.push(paths.yArrj);
      w.globals.seriesXvalues[realIndex] = paths.xArrj;
      w.globals.seriesYvalues[realIndex] = paths.yArrj;
      const forecast = w.config.forecastDataPoints;
      if (forecast.count > 0 && type !== "rangeArea") {
        const forecastCutoff = w.globals.seriesXvalues[realIndex][w.globals.seriesXvalues[realIndex].length - forecast.count - 1];
        const elForecastMask = graphics.drawRect(
          forecastCutoff,
          0,
          w.layout.gridWidth,
          w.layout.gridHeight,
          0
        );
        w.dom.elForecastMask.appendChild(elForecastMask.node);
        const elNonForecastMask = graphics.drawRect(
          0,
          0,
          forecastCutoff,
          w.layout.gridHeight,
          0
        );
        w.dom.elNonForecastMask.appendChild(elNonForecastMask.node);
      }
      if (!this.pointsChart) {
        w.globals.delayedElements.push({
          el: this.elPointsMain.node,
          index: realIndex
        });
      }
      const defaultRenderedPathOptions = {
        i,
        realIndex,
        animationDelay: i,
        initialSpeed: w.config.chart.animations.speed,
        dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed,
        className: `apexcharts-${type}`
      };
      if (type === "area") {
        const pathFill = fill.fillPath({
          seriesNumber: realIndex
        });
        for (let p = 0; p < paths.areaPaths.length; p++) {
          const renderedPath = graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
            pathFrom: paths.pathFromArea,
            pathTo: paths.areaPaths[p],
            stroke: "none",
            strokeWidth: 0,
            strokeLineCap: null,
            fill: pathFill
          }));
          this.elSeries.add(renderedPath);
        }
      }
      if (w.config.stroke.show && !this.pointsChart) {
        let lineFill = null;
        if (type === "line") {
          lineFill = fill.fillPath({
            seriesNumber: realIndex,
            i
          });
        } else {
          if (w.config.stroke.fill.type === "solid") {
            lineFill = w.globals.stroke.colors[realIndex];
          } else {
            const prevFill = w.config.fill;
            w.config.fill = w.config.stroke.fill;
            lineFill = fill.fillPath({
              seriesNumber: realIndex,
              i
            });
            w.config.fill = prevFill;
          }
        }
        for (let p = 0; p < paths.linePaths.length; p++) {
          let pathFill = lineFill;
          if (type === "rangeArea") {
            pathFill = fill.fillPath({
              seriesNumber: realIndex
            });
          }
          const linePathCommonOpts = __spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
            pathFrom: paths.pathFromLine,
            pathTo: paths.linePaths[p],
            stroke: lineFill,
            strokeWidth: this.strokeWidth,
            strokeLineCap: w.config.stroke.lineCap,
            fill: type === "rangeArea" ? pathFill : "none"
          });
          const renderedPath = graphics.renderPaths(linePathCommonOpts);
          this.elSeries.add(renderedPath);
          renderedPath.attr("fill-rule", `evenodd`);
          if (forecast.count > 0 && type !== "rangeArea") {
            const renderedForecastPath = graphics.renderPaths(linePathCommonOpts);
            renderedForecastPath.node.setAttribute(
              "stroke-dasharray",
              forecast.dashArray
            );
            if (forecast.strokeWidth) {
              renderedForecastPath.node.setAttribute(
                "stroke-width",
                forecast.strokeWidth
              );
            }
            this.elSeries.add(renderedForecastPath);
            renderedForecastPath.attr(
              "clip-path",
              `url(#forecastMask${w.globals.cuid})`
            );
            renderedPath.attr(
              "clip-path",
              `url(#nonForecastMask${w.globals.cuid})`
            );
          }
        }
      }
    }
    _iterateOverDataPoints({
      type,
      series,
      iterations,
      realIndex,
      translationsIndex,
      i,
      x,
      y,
      pX,
      pY,
      pathsFrom,
      linePaths,
      areaPaths,
      seriesIndex,
      lineYPosition,
      xArrj,
      yArrj,
      y2Arrj,
      isRangeStart,
      seriesRangeEnd
    }) {
      var _a, _b;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const yRatio = this.yRatio;
      let { prevY, linePath, areaPath, pathFromLine, pathFromArea } = pathsFrom;
      const minY = Utils$1.isNumber(w.globals.minYArr[realIndex]) ? w.globals.minYArr[realIndex] : w.globals.minY;
      if (!iterations) {
        iterations = w.globals.dataPoints > 1 ? w.globals.dataPoints - 1 : w.globals.dataPoints;
      }
      const getY = (_y, lineYPos) => {
        return lineYPos - _y / yRatio[translationsIndex] + (this.isReversed ? _y / yRatio[translationsIndex] : 0) * 2;
      };
      let y2 = y;
      const stackSeries = w.config.chart.stacked && !w.globals.comboCharts || w.config.chart.stacked && w.globals.comboCharts && (!this.w.config.chart.stackOnlyBar || /** @type {Record<string,any>} */
      ((_a = this.w.config.series[realIndex]) == null ? void 0 : _a.type) === "bar" || /** @type {Record<string,any>} */
      ((_b = this.w.config.series[realIndex]) == null ? void 0 : _b.type) === "column");
      let curve = w.config.stroke.curve;
      if (Array.isArray(curve)) {
        if (Array.isArray(seriesIndex)) {
          curve = curve[seriesIndex[i]];
        } else {
          curve = curve[i];
        }
      }
      let pathState = 0;
      let segmentStartX;
      for (let j = 0; j < iterations; j++) {
        if (series[i].length === 0) break;
        const isNull = typeof series[i][j + 1] === "undefined" || series[i][j + 1] === null;
        if (w.axisFlags.isXNumeric) {
          let sX = w.seriesData.seriesX[realIndex][j + 1];
          if (typeof w.seriesData.seriesX[realIndex][j + 1] === "undefined") {
            sX = w.seriesData.seriesX[realIndex][iterations - 1];
          }
          x = (sX - w.globals.minX) / this.xRatio;
        } else {
          x = x + this.xDivision;
        }
        if (stackSeries) {
          if (i > 0 && w.globals.collapsedSeries.length < w.config.series.length - 1) {
            const prevIndex = (pi) => {
              for (let pii = pi; pii > 0; pii--) {
                if (w.globals.collapsedSeriesIndices.indexOf(
                  (seriesIndex == null ? void 0 : seriesIndex[pii]) || pii
                ) > -1) {
                  pii--;
                } else {
                  return pii;
                }
              }
              return 0;
            };
            lineYPosition = this.prevSeriesY[prevIndex(i - 1)][j + 1];
          } else {
            lineYPosition = this.zeroY;
          }
        } else {
          lineYPosition = this.zeroY;
        }
        if (isNull) {
          y = getY(minY, lineYPosition);
        } else {
          y = getY(series[i][j + 1], lineYPosition);
          if (type === "rangeArea") {
            y2 = getY(seriesRangeEnd[i][j + 1], lineYPosition);
          }
        }
        xArrj.push(series[i][j + 1] === null ? null : x);
        if (isNull && (w.config.stroke.curve === "smooth" || w.config.stroke.curve === "monotoneCubic")) {
          yArrj.push(null);
          y2Arrj.push(null);
        } else {
          yArrj.push(y);
          y2Arrj.push(y2);
        }
        const pointsPos = this.lineHelpers.calculatePoints({
          series,
          x,
          y,
          realIndex,
          i,
          j,
          prevY
        });
        const calculatedPaths = this._createPaths({
          type,
          series,
          i,
          j,
          x,
          y,
          y2,
          xArrj,
          yArrj,
          y2Arrj,
          pX,
          pY,
          pathState,
          segmentStartX,
          linePath,
          areaPath,
          linePaths,
          areaPaths,
          curve,
          isRangeStart
        });
        areaPaths = calculatedPaths.areaPaths;
        linePaths = calculatedPaths.linePaths;
        pX = calculatedPaths.pX;
        pY = calculatedPaths.pY;
        pathState = calculatedPaths.pathState;
        segmentStartX = calculatedPaths.segmentStartX;
        areaPath = calculatedPaths.areaPath;
        linePath = calculatedPaths.linePath;
        if (this.appendPathFrom && !w.globals.hasNullValues && !(curve === "monotoneCubic" && type === "rangeArea")) {
          pathFromLine += graphics.line(x, this.areaBottomY);
          pathFromArea += graphics.line(x, this.areaBottomY);
        }
        this.handleNullDataPoints(series, pointsPos, i, j, realIndex);
        this._handleMarkersAndLabels({
          type,
          pointsPos,
          i,
          j,
          realIndex,
          isRangeStart
        });
      }
      return {
        yArrj,
        xArrj,
        pathFromArea,
        areaPaths,
        pathFromLine,
        linePaths,
        linePath,
        areaPath
      };
    }
    /** @param {{type: any, pointsPos: any, isRangeStart: any, i: any, j: any, realIndex: any}} opts */
    _handleMarkersAndLabels({ type, pointsPos, isRangeStart, i, j, realIndex }) {
      const w = this.w;
      const dataLabels = new DataLabels(this.w, this.ctx);
      if (!this.pointsChart) {
        if (w.seriesData.series[i].length > 1) {
          this.elPointsMain.node.classList.add("apexcharts-element-hidden");
        }
        const elPointsWrap = this.markers.plotChartMarkers({
          pointsPos,
          seriesIndex: realIndex,
          j: j + 1
        });
        if (elPointsWrap !== null) {
          this.elPointsMain.add(elPointsWrap);
        }
      } else {
        this.scatter.draw(this.elSeries, j, {
          realIndex,
          pointsPos,
          zRatio: this.zRatio,
          elParent: this.elPointsMain
        });
      }
      const drawnLabels = dataLabels.drawDataLabel({
        type,
        isRangeStart,
        pos: pointsPos,
        i: realIndex,
        j: j + 1
      });
      if (drawnLabels !== null) {
        this.elDataLabelsWrap.add(drawnLabels);
      }
    }
    /** @param {{type: any, series: any, i: any, j: any, x: any, y: any, xArrj: any, yArrj: any, y2: any, y2Arrj: any, pX: any, pY: any, pathState: any, segmentStartX: any, linePath: any, areaPath: any, linePaths: any, areaPaths: any, curve: any, isRangeStart: any}} opts */
    _createPaths({
      type,
      series,
      i,
      j,
      x,
      y,
      xArrj,
      yArrj,
      y2,
      y2Arrj,
      pX,
      pY,
      pathState,
      segmentStartX,
      linePath,
      areaPath,
      linePaths,
      areaPaths,
      curve,
      isRangeStart
    }) {
      const graphics = new Graphics(this.w);
      const areaBottomY = this.areaBottomY;
      const rangeArea = type === "rangeArea";
      const isLowerRangeAreaPath = type === "rangeArea" && isRangeStart;
      switch (curve) {
        case "monotoneCubic": {
          const yAj = isRangeStart ? yArrj : y2Arrj;
          const getSmoothInputs = (xArr, yArr) => {
            return xArr.map((_, i2) => {
              return [_, yArr[i2]];
            }).filter((_) => _[1] !== null);
          };
          const getSegmentLengths = (yArr) => {
            const segLens = [];
            let count = 0;
            yArr.forEach((_) => {
              if (_ !== null) {
                count++;
              } else if (count > 0) {
                segLens.push(count);
                count = 0;
              }
            });
            if (count > 0) {
              segLens.push(count);
            }
            return segLens;
          };
          const getSegments = (yArr, points) => {
            const segLens = getSegmentLengths(yArr);
            const segments = [];
            for (let i2 = 0, len = 0; i2 < segLens.length; len += segLens[i2++]) {
              segments[i2] = spline.slice(points, len, len + segLens[i2]);
            }
            return segments;
          };
          switch (pathState) {
            case 0:
              if (yAj[j + 1] === null) {
                break;
              }
              pathState = 1;
            // falls through
            case 1:
              if (!(rangeArea ? xArrj.length === series[i].length : j === series[i].length - 2)) {
                break;
              }
            // falls through
            case 2: {
              const _xAj = isRangeStart ? xArrj : xArrj.slice().reverse();
              const _yAj = isRangeStart ? yAj : yAj.slice().reverse();
              const smoothInputs = getSmoothInputs(_xAj, _yAj);
              const points = smoothInputs.length > 1 ? spline.points(smoothInputs) : smoothInputs;
              let smoothInputsLower = [];
              if (rangeArea) {
                if (isLowerRangeAreaPath) {
                  areaPaths = smoothInputs;
                } else {
                  smoothInputsLower = areaPaths.reverse();
                }
              }
              let segmentCount = 0;
              let smoothInputsIndex = 0;
              getSegments(_yAj, points).forEach((_) => {
                segmentCount++;
                const svgPoints = svgPath(_);
                const _start = smoothInputsIndex;
                smoothInputsIndex += _.length;
                const _end = smoothInputsIndex - 1;
                if (isLowerRangeAreaPath) {
                  linePath = graphics.move(
                    smoothInputs[_start][0],
                    smoothInputs[_start][1]
                  ) + svgPoints;
                } else if (rangeArea) {
                  linePath = graphics.move(
                    smoothInputsLower[_start][0],
                    smoothInputsLower[_start][1]
                  ) + graphics.line(
                    smoothInputs[_start][0],
                    smoothInputs[_start][1]
                  ) + svgPoints + graphics.line(
                    smoothInputsLower[_end][0],
                    smoothInputsLower[_end][1]
                  );
                } else {
                  linePath = graphics.move(
                    smoothInputs[_start][0],
                    smoothInputs[_start][1]
                  ) + svgPoints;
                  areaPath = linePath + graphics.line(smoothInputs[_end][0], areaBottomY) + graphics.line(smoothInputs[_start][0], areaBottomY) + "z";
                  areaPaths.push(areaPath);
                }
                linePaths.push(linePath);
              });
              if (rangeArea && segmentCount > 1 && !isLowerRangeAreaPath) {
                const upperLinePaths = linePaths.slice(segmentCount).reverse();
                linePaths.splice(segmentCount);
                upperLinePaths.forEach(
                  (u) => linePaths.push(u)
                );
              }
              pathState = 0;
              break;
            }
          }
          break;
        }
        case "smooth": {
          const length = (x - pX) * 0.35;
          if (series[i][j] === null) {
            pathState = 0;
          } else {
            switch (pathState) {
              case 0:
                segmentStartX = pX;
                if (isLowerRangeAreaPath) {
                  linePath = graphics.move(pX, y2Arrj[j]) + graphics.line(pX, pY);
                } else {
                  linePath = graphics.move(pX, pY);
                }
                areaPath = graphics.move(pX, pY);
                if (series[i][j + 1] === null || typeof series[i][j + 1] === "undefined") {
                  linePaths.push(linePath);
                  areaPaths.push(areaPath);
                  break;
                }
                pathState = 1;
                if (j < series[i].length - 2) {
                  const p = graphics.curve(pX + length, pY, x - length, y, x, y);
                  linePath += p;
                  areaPath += p;
                  break;
                }
              // falls through
              case 1:
                if (series[i][j + 1] === null) {
                  if (isLowerRangeAreaPath) {
                    linePath += graphics.line(pX, y2);
                  } else {
                    linePath += graphics.move(pX, pY);
                  }
                  areaPath += graphics.line(pX, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                  linePaths.push(linePath);
                  areaPaths.push(areaPath);
                  pathState = -1;
                } else {
                  const p = graphics.curve(pX + length, pY, x - length, y, x, y);
                  linePath += p;
                  areaPath += p;
                  if (j >= series[i].length - 2) {
                    if (isLowerRangeAreaPath) {
                      linePath += graphics.curve(x, y, x, y, x, y2) + graphics.move(x, y2);
                    }
                    areaPath += graphics.curve(x, y, x, y, x, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                    linePaths.push(linePath);
                    areaPaths.push(areaPath);
                    pathState = -1;
                  }
                }
                break;
            }
          }
          pX = x;
          pY = y;
          break;
        }
        default: {
          const pathToPoint = (curve2, x2, y3) => {
            let path = "";
            switch (curve2) {
              case "stepline":
                path = graphics.line(x2, null, "H") + graphics.line(null, y3, "V");
                break;
              case "linestep":
                path = graphics.line(null, y3, "V") + graphics.line(x2, null, "H");
                break;
              case "straight":
                path = graphics.line(x2, y3);
                break;
            }
            return path;
          };
          if (series[i][j] === null) {
            pathState = 0;
          } else {
            switch (pathState) {
              case 0:
                segmentStartX = pX;
                if (isLowerRangeAreaPath) {
                  linePath = graphics.move(pX, y2Arrj[j]) + graphics.line(pX, pY);
                } else {
                  linePath = graphics.move(pX, pY);
                }
                areaPath = graphics.move(pX, pY);
                if (series[i][j + 1] === null || typeof series[i][j + 1] === "undefined") {
                  linePaths.push(linePath);
                  areaPaths.push(areaPath);
                  break;
                }
                pathState = 1;
                if (j < series[i].length - 2) {
                  const p = pathToPoint(curve, x, y);
                  linePath += p;
                  areaPath += p;
                  break;
                }
              // falls through
              case 1:
                if (series[i][j + 1] === null) {
                  if (isLowerRangeAreaPath) {
                    linePath += graphics.line(pX, y2);
                  } else {
                    linePath += graphics.move(pX, pY);
                  }
                  areaPath += graphics.line(pX, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                  linePaths.push(linePath);
                  areaPaths.push(areaPath);
                  pathState = -1;
                } else {
                  const p = pathToPoint(curve, x, y);
                  linePath += p;
                  areaPath += p;
                  if (j >= series[i].length - 2) {
                    if (isLowerRangeAreaPath) {
                      linePath += graphics.line(x, y2);
                    }
                    areaPath += graphics.line(x, areaBottomY) + graphics.line(segmentStartX, areaBottomY) + "z";
                    linePaths.push(linePath);
                    areaPaths.push(areaPath);
                    pathState = -1;
                  }
                }
                break;
            }
          }
          pX = x;
          pY = y;
          break;
        }
      }
      return {
        linePaths,
        areaPaths,
        pX,
        pY,
        pathState,
        segmentStartX,
        linePath,
        areaPath
      };
    }
    /**
     * @param {any[]} series
     * @param {any} pointsPos
     * @param {number} i
     * @param {number} j
     * @param {number} realIndex
     */
    handleNullDataPoints(series, pointsPos, i, j, realIndex) {
      const w = this.w;
      if (series[i][j] === null && w.config.markers.showNullDataPoints || series[i].length === 1) {
        let pSize = this.strokeWidth - w.config.markers.strokeWidth / 2;
        if (!(pSize > 0)) {
          pSize = 0;
        }
        const elPointsWrap = this.markers.plotChartMarkers({
          pointsPos,
          seriesIndex: realIndex,
          j: j + 1,
          pSize,
          alwaysDrawMarker: true
        });
        if (elPointsWrap !== null) {
          this.elPointsMain.add(elPointsWrap);
        }
      }
    }
  }
  class CircularChartsHelpers {
    /**
     * @param {import('../../../types/internal').ChartStateW} w
     */
    constructor(w) {
      this.w = w;
    }
    /**
     * @param {number} x
     * @param {number} y
     * @param {number} i
     * @param {string | number} text
     */
    drawYAxisTexts(x, y, i, text) {
      const w = this.w;
      const yaxisConfig = w.config.yaxis[0];
      const formatter = w.formatters.yLabelFormatters[0];
      const graphics = new Graphics(this.w);
      const yaxisLabel = graphics.drawText({
        x: x + yaxisConfig.labels.offsetX,
        y: y + yaxisConfig.labels.offsetY,
        text: formatter(text, i),
        textAnchor: "middle",
        fontSize: yaxisConfig.labels.style.fontSize,
        fontFamily: yaxisConfig.labels.style.fontFamily,
        foreColor: Array.isArray(yaxisConfig.labels.style.colors) ? yaxisConfig.labels.style.colors[i] : yaxisConfig.labels.style.colors
      });
      return yaxisLabel;
    }
  }
  class Pie {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.ctx = ctx;
      this.w = w;
      this.chartType = this.w.config.chart.type;
      this.initialAnim = this.w.config.chart.animations.enabled;
      this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled;
      this.animBeginArr = [0];
      this.animDur = 0;
      this.donutDataLabels = this.w.config.plotOptions.pie.donut.labels;
      this.lineColorArr = w.globals.stroke.colors !== void 0 ? w.globals.stroke.colors : w.globals.colors;
      this.defaultSize = Math.min(w.layout.gridWidth, w.layout.gridHeight);
      this.centerY = this.defaultSize / 2;
      this.centerX = w.layout.gridWidth / 2;
      if (w.config.chart.type === "radialBar") {
        this.fullAngle = 360;
      } else {
        this.fullAngle = Math.abs(
          w.config.plotOptions.pie.endAngle - w.config.plotOptions.pie.startAngle
        );
      }
      this.initialAngle = w.config.plotOptions.pie.startAngle % this.fullAngle;
      w.globals.radialSize = this.defaultSize / 2.05 - w.config.stroke.width - (!w.config.chart.sparkline.enabled ? w.config.chart.dropShadow.blur : 0);
      this.donutSize = w.globals.radialSize * parseInt(w.config.plotOptions.pie.donut.size, 10) / 100;
      const scaleSize = w.config.plotOptions.pie.customScale;
      const halfW = w.layout.gridWidth / 2;
      const halfH = w.layout.gridHeight / 2;
      this.translateX = halfW - halfW * scaleSize;
      this.translateY = halfH - halfH * scaleSize;
      this.dataLabelsGroup = new Graphics(this.w).group({
        class: "apexcharts-datalabels-group",
        transform: `translate(${this.translateX}, ${this.translateY}) scale(${scaleSize})`
      });
      this.maxY = 0;
      this.sliceLabels = [];
      this.sliceSizes = [];
      this.prevSectorAngleArr = [];
    }
    /**
     * @param {any[]} series
     */
    draw(series) {
      const self2 = this;
      const w = this.w;
      const graphics = new Graphics(this.w);
      const elPie = graphics.group({
        class: "apexcharts-pie"
      });
      if (w.globals.noData) return elPie;
      let total = 0;
      for (let k = 0; k < series.length; k++) {
        total += Utils$1.negToZero(series[k]);
      }
      const sectorAngleArr = [];
      const elSeries = graphics.group();
      if (total === 0) {
        total = 1e-5;
      }
      series.forEach((m) => {
        this.maxY = Math.max(this.maxY, m);
      });
      if (w.config.yaxis[0].max) {
        this.maxY = w.config.yaxis[0].max;
      }
      if (w.config.grid.position === "back" && this.chartType === "polarArea") {
        this.drawPolarElements(elPie);
      }
      for (let i = 0; i < series.length; i++) {
        const angle = this.fullAngle * Utils$1.negToZero(series[i]) / total;
        sectorAngleArr.push(angle);
        if (this.chartType === "polarArea") {
          sectorAngleArr[i] = this.fullAngle / series.length;
          this.sliceSizes.push(w.globals.radialSize * series[i] / this.maxY);
        } else {
          this.sliceSizes.push(w.globals.radialSize);
        }
      }
      if (w.globals.dataChanged) {
        let prevTotal = 0;
        for (let k = 0; k < w.globals.previousPaths.length; k++) {
          prevTotal += Utils$1.negToZero(w.globals.previousPaths[k]);
        }
        let previousAngle;
        for (let i = 0; i < w.globals.previousPaths.length; i++) {
          previousAngle = this.fullAngle * Utils$1.negToZero(w.globals.previousPaths[i]) / prevTotal;
          this.prevSectorAngleArr.push(previousAngle);
        }
      }
      if (this.donutSize < 0) {
        this.donutSize = 0;
      }
      if (this.chartType === "donut") {
        const circle = graphics.drawCircle(this.donutSize);
        circle.attr({
          cx: this.centerX,
          cy: this.centerY,
          fill: w.config.plotOptions.pie.donut.background ? w.config.plotOptions.pie.donut.background : "transparent"
        });
        elSeries.add(circle);
      }
      const elG = self2.drawArcs(sectorAngleArr, series);
      this.sliceLabels.forEach((s) => {
        elG.add(s);
      });
      elSeries.attr({
        transform: `translate(${this.translateX}, ${this.translateY}) scale(${w.config.plotOptions.pie.customScale})`
      });
      elSeries.add(elG);
      elPie.add(elSeries);
      if (this.donutDataLabels.show) {
        const dataLabels = this.renderInnerDataLabels(
          this.dataLabelsGroup,
          this.donutDataLabels,
          {
            hollowSize: this.donutSize,
            centerX: this.centerX,
            centerY: this.centerY,
            opacity: this.donutDataLabels.show
          }
        );
        elPie.add(dataLabels);
      }
      if (w.config.grid.position === "front" && this.chartType === "polarArea") {
        this.drawPolarElements(elPie);
      }
      return elPie;
    }
    // core function for drawing pie arcs
    /**
     * @param {any[]} sectorAngleArr
     * @param {any[]} series
     */
    drawArcs(sectorAngleArr, series) {
      const w = this.w;
      const filters = new Filters(this.w);
      const graphics = new Graphics(this.w);
      const fill = new Fill(this.w);
      const g = graphics.group({
        class: "apexcharts-slices"
      });
      let startAngle = this.initialAngle;
      let prevStartAngle = this.initialAngle;
      let endAngle = this.initialAngle;
      let prevEndAngle = this.initialAngle;
      this.strokeWidth = w.config.stroke.show ? w.config.stroke.width : 0;
      for (let i = 0; i < sectorAngleArr.length; i++) {
        const elPieArc = graphics.group({
          class: `apexcharts-series apexcharts-pie-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
          rel: i + 1,
          "data:realIndex": i
        });
        g.add(elPieArc);
        startAngle = endAngle;
        prevStartAngle = prevEndAngle;
        endAngle = startAngle + sectorAngleArr[i];
        prevEndAngle = prevStartAngle + this.prevSectorAngleArr[i];
        const angle = endAngle < startAngle ? this.fullAngle + endAngle - startAngle : endAngle - startAngle;
        const pathFill = fill.fillPath({
          seriesNumber: i,
          size: this.sliceSizes[i],
          value: series[i]
        });
        const path = this.getChangedPath(prevStartAngle, prevEndAngle);
        const elPath = graphics.drawPath({
          d: path,
          stroke: Array.isArray(this.lineColorArr) ? this.lineColorArr[i] : this.lineColorArr,
          strokeWidth: 0,
          fill: pathFill,
          fillOpacity: w.config.fill.opacity,
          classes: `apexcharts-pie-area apexcharts-${this.chartType.toLowerCase()}-slice-${i}`
        });
        elPath.attr({
          index: 0,
          j: i
        });
        filters.setSelectionFilter(elPath, 0, i);
        if (w.config.chart.dropShadow.enabled) {
          const shadow = w.config.chart.dropShadow;
          filters.dropShadow(elPath, shadow, i);
        }
        this.addListeners(elPath, this.donutDataLabels);
        let labelPosition = {
          x: 0,
          y: 0
        };
        const midAngle = (startAngle + angle / 2) % this.fullAngle;
        let arcCenter = { x: this.centerX, y: this.centerY };
        if (this.chartType === "pie" || this.chartType === "polarArea") {
          labelPosition = Utils$1.polarToCartesian(
            this.centerX,
            this.centerY,
            w.globals.radialSize / 1.25 + w.config.plotOptions.pie.dataLabels.offset,
            midAngle
          );
          arcCenter = Utils$1.polarToCartesian(
            this.centerX,
            this.centerY,
            w.globals.radialSize / 2,
            midAngle
          );
        } else if (this.chartType === "donut") {
          labelPosition = Utils$1.polarToCartesian(
            this.centerX,
            this.centerY,
            (w.globals.radialSize + this.donutSize) / 2 + w.config.plotOptions.pie.dataLabels.offset,
            midAngle
          );
          arcCenter = Utils$1.polarToCartesian(
            this.centerX,
            this.centerY,
            (w.globals.radialSize + this.donutSize) / 2,
            midAngle
          );
        }
        Graphics.setAttrs(elPath.node, {
          "data:angle": angle,
          "data:startAngle": startAngle,
          "data:strokeWidth": this.strokeWidth,
          "data:value": series[i],
          "data:cx": arcCenter.x,
          "data:cy": arcCenter.y
        });
        elPieArc.add(elPath);
        let dur = 0;
        if (this.initialAnim && !w.globals.resized && !w.globals.dataChanged) {
          dur = angle / this.fullAngle * w.config.chart.animations.speed;
          if (dur === 0) dur = 1;
          this.animDur = dur + this.animDur;
          this.animBeginArr.push(this.animDur);
        } else {
          this.animBeginArr.push(0);
        }
        if (this.dynamicAnim && w.globals.dataChanged) {
          this.animatePaths(elPath, {
            size: this.sliceSizes[i],
            endAngle,
            startAngle,
            prevStartAngle,
            prevEndAngle,
            animateStartingPos: true,
            i,
            animBeginArr: this.animBeginArr,
            shouldSetPrevPaths: true,
            dur: w.config.chart.animations.dynamicAnimation.speed
          });
        } else {
          this.animatePaths(elPath, {
            size: this.sliceSizes[i],
            endAngle,
            startAngle,
            i,
            totalItems: sectorAngleArr.length - 1,
            animBeginArr: this.animBeginArr,
            dur
          });
        }
        if (w.config.plotOptions.pie.expandOnClick && this.chartType !== "polarArea") {
          elPath.node.addEventListener("mouseup", this.pieClicked.bind(this, i));
        }
        if (typeof w.interact.selectedDataPoints[0] !== "undefined" && w.interact.selectedDataPoints[0].indexOf(i) > -1) {
          this.pieClicked(i);
        }
        if (w.config.dataLabels.enabled) {
          const xPos = labelPosition.x;
          const yPos = labelPosition.y;
          let text = 100 * angle / this.fullAngle + "%";
          if (angle !== 0 && w.config.plotOptions.pie.dataLabels.minAngleToShowLabel < sectorAngleArr[i]) {
            const formatter = w.config.dataLabels.formatter;
            if (formatter !== void 0) {
              text = formatter(w.globals.seriesPercent[i][0], {
                seriesIndex: i,
                w
              });
            }
            const foreColor = w.globals.dataLabels.style.colors[i];
            const elPieLabelWrap = graphics.group({
              class: `apexcharts-datalabels`
            });
            const elPieLabel = graphics.drawText({
              x: xPos,
              y: yPos,
              text,
              textAnchor: "middle",
              fontSize: w.config.dataLabels.style.fontSize,
              fontFamily: w.config.dataLabels.style.fontFamily,
              fontWeight: w.config.dataLabels.style.fontWeight,
              foreColor
            });
            elPieLabelWrap.add(elPieLabel);
            if (w.config.dataLabels.dropShadow.enabled) {
              const textShadow = w.config.dataLabels.dropShadow;
              filters.dropShadow(elPieLabel, textShadow);
            }
            elPieLabel.node.classList.add("apexcharts-pie-label");
            if (w.config.chart.animations.animate && w.globals.resized === false) {
              elPieLabel.node.classList.add("apexcharts-pie-label-delay");
              elPieLabel.node.style.animationDelay = w.config.chart.animations.speed / 940 + "s";
            }
            this.sliceLabels.push(elPieLabelWrap);
          }
        }
      }
      return g;
    }
    /**
     * @param {any} elPath
     * @param {Record<string, any>} dataLabels
     */
    addListeners(elPath, dataLabels) {
      const graphics = new Graphics(this.w);
      elPath.node.addEventListener(
        "mouseenter",
        graphics.pathMouseEnter.bind(this, elPath)
      );
      elPath.node.addEventListener(
        "mouseleave",
        graphics.pathMouseLeave.bind(this, elPath)
      );
      elPath.node.addEventListener(
        "mouseleave",
        this.revertDataLabelsInner.bind(this)
      );
      elPath.node.addEventListener(
        "mousedown",
        graphics.pathMouseDown.bind(this, elPath)
      );
      if (!this.donutDataLabels.total.showAlways) {
        elPath.node.addEventListener(
          "mouseenter",
          this.printDataLabelsInner.bind(this, elPath.node, dataLabels)
        );
        elPath.node.addEventListener(
          "mousedown",
          this.printDataLabelsInner.bind(this, elPath.node, dataLabels)
        );
      }
    }
    // This function can be used for other circle charts too
    /**
     * @param {any} el
     * @param {Record<string, any>} opts
     */
    animatePaths(el, opts) {
      const w = this.w;
      const me = this;
      let angle = opts.endAngle < opts.startAngle ? this.fullAngle + opts.endAngle - opts.startAngle : opts.endAngle - opts.startAngle;
      let prevAngle = angle;
      let fromStartAngle = opts.startAngle;
      const toStartAngle = opts.startAngle;
      if (opts.prevStartAngle !== void 0 && opts.prevEndAngle !== void 0) {
        fromStartAngle = opts.prevEndAngle;
        prevAngle = opts.prevEndAngle < opts.prevStartAngle ? this.fullAngle + opts.prevEndAngle - opts.prevStartAngle : opts.prevEndAngle - opts.prevStartAngle;
      }
      if (opts.i === w.config.series.length - 1) {
        if (angle + toStartAngle > this.fullAngle) {
          opts.endAngle = opts.endAngle - (angle + toStartAngle);
        } else if (angle + toStartAngle < this.fullAngle) {
          opts.endAngle = opts.endAngle + (this.fullAngle - (angle + toStartAngle));
        }
      }
      if (angle === this.fullAngle) angle = this.fullAngle - 0.01;
      me.animateArc(el, fromStartAngle, toStartAngle, angle, prevAngle, opts);
    }
    /**
     * @param {any} el
     * @param {number} fromStartAngle
     * @param {number} toStartAngle
     * @param {number} angle
     * @param {number} prevAngle
     * @param {Record<string, any>} opts
     */
    animateArc(el, fromStartAngle, toStartAngle, angle, prevAngle, opts) {
      const me = this;
      const w = this.w;
      const animations = new Animations(this.w);
      const size = opts.size;
      let path;
      if (isNaN(fromStartAngle) || isNaN(prevAngle)) {
        fromStartAngle = toStartAngle;
        prevAngle = angle;
        opts.dur = 0;
      }
      let currAngle = angle;
      let startAngle = toStartAngle;
      const fromAngle = fromStartAngle < toStartAngle ? this.fullAngle + fromStartAngle - toStartAngle : fromStartAngle - toStartAngle;
      if (w.globals.dataChanged && opts.shouldSetPrevPaths) {
        if (opts.prevEndAngle) {
          path = me.getPiePath({
            me,
            startAngle: opts.prevStartAngle,
            angle: opts.prevEndAngle < opts.prevStartAngle ? this.fullAngle + opts.prevEndAngle - opts.prevStartAngle : opts.prevEndAngle - opts.prevStartAngle,
            size
          });
          el.attr({ d: path });
        }
      }
      if (opts.dur !== 0) {
        el.animate(opts.dur, opts.animBeginArr[opts.i]).after(
          /** @this {any} */
          function() {
            if (me.chartType === "pie" || me.chartType === "donut" || me.chartType === "polarArea") {
              this.animate(
                w.config.chart.animations.dynamicAnimation.speed
              ).attr({
                "stroke-width": me.strokeWidth
              });
            }
            if (opts.i === w.config.series.length - 1) {
              animations.animationCompleted(el);
            }
          }
        ).during((pos) => {
          currAngle = fromAngle + (angle - fromAngle) * pos;
          if (opts.animateStartingPos) {
            currAngle = prevAngle + (angle - prevAngle) * pos;
            startAngle = fromStartAngle - prevAngle + (toStartAngle - (fromStartAngle - prevAngle)) * pos;
          }
          path = me.getPiePath({
            me,
            startAngle,
            angle: currAngle,
            size
          });
          el.node.setAttribute("data:pathOrig", path);
          el.attr({
            d: path
          });
        });
      } else {
        path = me.getPiePath({
          me,
          startAngle,
          angle,
          size
        });
        if (!opts.isTrack) {
          w.globals.animationEnded = true;
        }
        el.node.setAttribute("data:pathOrig", path);
        el.attr({
          d: path,
          "stroke-width": me.strokeWidth
        });
      }
    }
    /**
     * @param {number} i
     */
    pieClicked(i) {
      const w = this.w;
      const me = this;
      const size = me.sliceSizes[i] + (w.config.plotOptions.pie.expandOnClick ? 4 : 0);
      const elPath = w.dom.Paper.findOne(
        `.apexcharts-${me.chartType.toLowerCase()}-slice-${i}`
      );
      if (elPath.attr("data:pieClicked") === "true") {
        elPath.attr({
          "data:pieClicked": "false"
        });
        this.revertDataLabelsInner();
        const origPath = elPath.attr("data:pathOrig");
        elPath.attr({
          d: origPath
        });
        return;
      } else {
        const allEls = w.dom.baseEl.getElementsByClassName("apexcharts-pie-area");
        Array.prototype.forEach.call(allEls, (pieSlice) => {
          pieSlice.setAttribute("data:pieClicked", "false");
          const origPath = pieSlice.getAttribute("data:pathOrig");
          if (origPath) {
            pieSlice.setAttribute("d", origPath);
          }
        });
        w.interact.capturedDataPointIndex = i;
        elPath.attr("data:pieClicked", "true");
      }
      const startAngle = parseInt(elPath.attr("data:startAngle"), 10);
      const angle = parseInt(elPath.attr("data:angle"), 10);
      const path = me.getPiePath({
        me,
        startAngle,
        angle,
        size
      });
      if (angle === 360) return;
      elPath.plot(path);
    }
    /**
     * @param {number} prevStartAngle
     * @param {number} prevEndAngle
     */
    getChangedPath(prevStartAngle, prevEndAngle) {
      let path = "";
      if (this.dynamicAnim && this.w.globals.dataChanged) {
        path = this.getPiePath({
          me: this,
          startAngle: prevStartAngle,
          angle: prevEndAngle - prevStartAngle,
          // @ts-ignore — size is set dynamically during draw()
          size: this.size
        });
      }
      return path;
    }
    /** @param {{me: any, startAngle: any, angle: any, size: any}} opts */
    getPiePath({ me, startAngle, angle, size }) {
      let path;
      const graphics = new Graphics(this.w);
      const startDeg = startAngle;
      const startRadians = Math.PI * (startDeg - 90) / 180;
      let endDeg = angle + startAngle;
      if (Math.ceil(endDeg) >= this.fullAngle + this.w.config.plotOptions.pie.startAngle % this.fullAngle) {
        endDeg = this.fullAngle + this.w.config.plotOptions.pie.startAngle % this.fullAngle - 0.01;
      }
      if (Math.ceil(endDeg) > this.fullAngle) endDeg -= this.fullAngle;
      const endRadians = Math.PI * (endDeg - 90) / 180;
      const x1 = me.centerX + size * Math.cos(startRadians);
      const y1 = me.centerY + size * Math.sin(startRadians);
      const x2 = me.centerX + size * Math.cos(endRadians);
      const y2 = me.centerY + size * Math.sin(endRadians);
      const startInner = Utils$1.polarToCartesian(
        me.centerX,
        me.centerY,
        me.donutSize,
        endDeg
      );
      const endInner = Utils$1.polarToCartesian(
        me.centerX,
        me.centerY,
        me.donutSize,
        startDeg
      );
      const largeArc = angle > 180 ? 1 : 0;
      const pathBeginning = ["M", x1, y1, "A", size, size, 0, largeArc, 1, x2, y2];
      if (me.chartType === "donut") {
        path = [
          ...pathBeginning,
          "L",
          startInner.x,
          startInner.y,
          "A",
          me.donutSize,
          me.donutSize,
          0,
          largeArc,
          0,
          endInner.x,
          endInner.y,
          "L",
          x1,
          y1,
          "z"
        ].join(" ");
      } else if (me.chartType === "pie" || me.chartType === "polarArea") {
        path = [...pathBeginning, "L", me.centerX, me.centerY, "L", x1, y1].join(
          " "
        );
      } else {
        path = [...pathBeginning].join(" ");
      }
      return graphics.roundPathCorners(path, this.strokeWidth * 2);
    }
    /**
     * @param {any} parent
     */
    drawPolarElements(parent) {
      const w = this.w;
      const scale = new Scales(this.w);
      const graphics = new Graphics(this.w);
      const helpers = new CircularChartsHelpers(this.w);
      const gCircles = graphics.group();
      const gYAxis = graphics.group();
      const yScale = scale.niceScale(0, Math.ceil(this.maxY), 0);
      const yTexts = yScale.result.reverse();
      const len = yScale.result.length;
      this.maxY = yScale.niceMax;
      let circleSize = w.globals.radialSize;
      const diff = circleSize / (len - 1);
      for (let i = 0; i < len - 1; i++) {
        const circle = graphics.drawCircle(circleSize);
        circle.attr({
          cx: this.centerX,
          cy: this.centerY,
          fill: "none",
          "stroke-width": w.config.plotOptions.polarArea.rings.strokeWidth,
          stroke: w.config.plotOptions.polarArea.rings.strokeColor
        });
        if (w.config.yaxis[0].show) {
          const yLabel = helpers.drawYAxisTexts(
            this.centerX,
            this.centerY - circleSize + parseInt(w.config.yaxis[0].labels.style.fontSize, 10) / 2,
            i,
            yTexts[i]
          );
          gYAxis.add(yLabel);
        }
        gCircles.add(circle);
        circleSize = circleSize - diff;
      }
      this.drawSpokes(parent);
      parent.add(gCircles);
      parent.add(gYAxis);
    }
    /**
     * @param {any} dataLabelsGroup
     * @param {Record<string, any>} dataLabelsConfig
     * @param {Record<string, any>} opts
     */
    renderInnerDataLabels(dataLabelsGroup, dataLabelsConfig, opts) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const showTotal = dataLabelsConfig.total.show;
      dataLabelsGroup.node.innerHTML = "";
      dataLabelsGroup.node.style.opacity = opts.opacity;
      const x = opts.centerX;
      const y = !this.donutDataLabels.total.label ? opts.centerY - opts.centerY / 6 : opts.centerY;
      let labelColor, valueColor;
      if (dataLabelsConfig.name.color === void 0) {
        labelColor = w.globals.colors[0];
      } else {
        labelColor = dataLabelsConfig.name.color;
      }
      let labelFontSize = dataLabelsConfig.name.fontSize;
      let labelFontFamily = dataLabelsConfig.name.fontFamily;
      let labelFontWeight = dataLabelsConfig.name.fontWeight;
      if (dataLabelsConfig.value.color === void 0) {
        valueColor = w.config.chart.foreColor;
      } else {
        valueColor = dataLabelsConfig.value.color;
      }
      const lbFormatter = dataLabelsConfig.value.formatter;
      let val = "";
      let name2 = "";
      if (showTotal) {
        labelColor = dataLabelsConfig.total.color;
        labelFontSize = dataLabelsConfig.total.fontSize;
        labelFontFamily = dataLabelsConfig.total.fontFamily;
        labelFontWeight = dataLabelsConfig.total.fontWeight;
        name2 = !this.donutDataLabels.total.label ? "" : dataLabelsConfig.total.label;
        val = dataLabelsConfig.total.formatter(w);
      } else {
        if (w.seriesData.series.length === 1) {
          val = lbFormatter(w.seriesData.series[0], w);
          name2 = w.seriesData.seriesNames[0];
        }
      }
      if (name2) {
        name2 = dataLabelsConfig.name.formatter(
          name2,
          dataLabelsConfig.total.show,
          w
        );
      }
      if (dataLabelsConfig.name.show) {
        const elLabel = graphics.drawText({
          x,
          y: y + parseFloat(dataLabelsConfig.name.offsetY),
          text: name2,
          textAnchor: "middle",
          foreColor: labelColor,
          fontSize: labelFontSize,
          fontWeight: labelFontWeight,
          fontFamily: labelFontFamily
        });
        elLabel.node.classList.add("apexcharts-datalabel-label");
        dataLabelsGroup.add(elLabel);
      }
      if (dataLabelsConfig.value.show) {
        const valOffset = dataLabelsConfig.name.show ? parseFloat(dataLabelsConfig.value.offsetY) + 16 : dataLabelsConfig.value.offsetY;
        const elValue = graphics.drawText({
          x,
          y: y + valOffset,
          text: val,
          textAnchor: "middle",
          foreColor: valueColor,
          fontWeight: dataLabelsConfig.value.fontWeight,
          fontSize: dataLabelsConfig.value.fontSize,
          fontFamily: dataLabelsConfig.value.fontFamily
        });
        elValue.node.classList.add("apexcharts-datalabel-value");
        dataLabelsGroup.add(elValue);
      }
      return dataLabelsGroup;
    }
    /**
     *
     * @param {string} name - The name of the series
     * @param {string} val - The value of that series
     * @param {any} el - Optional el (indicates which series was hovered/clicked). If this param is not present, means we need to show total
     * @param {Record<string, any>} labelsConfig
     */
    printInnerLabels(labelsConfig, name2, val, el) {
      const w = this.w;
      let labelColor;
      if (el) {
        if (labelsConfig.name.color === void 0) {
          labelColor = w.globals.colors[parseInt(el.parentNode.getAttribute("rel"), 10) - 1];
        } else {
          labelColor = labelsConfig.name.color;
        }
      } else {
        if (w.seriesData.series.length > 1 && labelsConfig.total.show) {
          labelColor = labelsConfig.total.color;
        }
      }
      const elLabel = w.dom.baseEl.querySelector(".apexcharts-datalabel-label");
      const elValue = w.dom.baseEl.querySelector(".apexcharts-datalabel-value");
      const lbFormatter = labelsConfig.value.formatter;
      val = lbFormatter(val, w);
      if (!el && typeof labelsConfig.total.formatter === "function") {
        val = labelsConfig.total.formatter(w);
      }
      const isTotal = name2 === labelsConfig.total.label;
      name2 = !this.donutDataLabels.total.label ? "" : labelsConfig.name.formatter(name2, isTotal, w);
      if (elLabel !== null) {
        elLabel.textContent = name2;
      }
      if (elValue !== null) {
        elValue.textContent = val;
      }
      if (elLabel !== null) {
        const elLabelEl = (
          /** @type {HTMLElement} */
          elLabel
        );
        elLabelEl.style.fill = labelColor;
      }
    }
    /**
     * @param {any} el
     * @param {Record<string, any>} dataLabelsConfig
     */
    printDataLabelsInner(el, dataLabelsConfig) {
      const w = this.w;
      const val = el.getAttribute("data:value");
      const name2 = w.seriesData.seriesNames[parseInt(el.parentNode.getAttribute("rel"), 10) - 1];
      if (w.seriesData.series.length > 1) {
        this.printInnerLabels(dataLabelsConfig, name2, val, el);
      }
      const dataLabelsGroup = w.dom.baseEl.querySelector(
        ".apexcharts-datalabels-group"
      );
      if (dataLabelsGroup !== null) {
        const dataLabelsGroupEl = (
          /** @type {HTMLElement} */
          dataLabelsGroup
        );
        dataLabelsGroupEl.style.opacity = "1";
      }
    }
    /**
     * @param {any} parent
     */
    drawSpokes(parent) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const spokeConfig = w.config.plotOptions.polarArea.spokes;
      if (spokeConfig.strokeWidth === 0) return;
      const spokes = [];
      const angleDivision = 360 / w.seriesData.series.length;
      for (let i = 0; i < w.seriesData.series.length; i++) {
        spokes.push(
          Utils$1.polarToCartesian(
            this.centerX,
            this.centerY,
            w.globals.radialSize,
            w.config.plotOptions.pie.startAngle + angleDivision * i
          )
        );
      }
      spokes.forEach((p, i) => {
        const line = graphics.drawLine(
          p.x,
          p.y,
          this.centerX,
          this.centerY,
          Array.isArray(spokeConfig.connectorColors) ? spokeConfig.connectorColors[i] : spokeConfig.connectorColors
        );
        parent.add(line);
      });
    }
    revertDataLabelsInner() {
      const w = this.w;
      if (this.donutDataLabels.show) {
        const dataLabelsGroup = w.dom.Paper.findOne(
          `.apexcharts-datalabels-group`
        );
        const dataLabels = this.renderInnerDataLabels(
          dataLabelsGroup,
          this.donutDataLabels,
          {
            hollowSize: this.donutSize,
            centerX: this.centerX,
            centerY: this.centerY,
            opacity: this.donutDataLabels.show
          }
        );
        const elPie = w.dom.Paper.findOne(
          ".apexcharts-radialbar, .apexcharts-pie"
        );
        elPie.add(dataLabels);
      }
    }
  }
  class Radar {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.ctx = ctx;
      this.w = w;
      this.chartType = this.w.config.chart.type;
      this.initialAnim = this.w.config.chart.animations.enabled;
      this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled;
      this.animDur = 0;
      this.graphics = new Graphics(this.w);
      this.lineColorArr = w.globals.stroke.colors !== void 0 ? w.globals.stroke.colors : w.globals.colors;
      this.defaultSize = w.globals.svgHeight < w.globals.svgWidth ? w.layout.gridHeight : w.layout.gridWidth;
      this.isLog = w.config.yaxis[0].logarithmic;
      this.logBase = w.config.yaxis[0].logBase;
      this.coreUtils = new CoreUtils(this.w);
      this.maxValue = this.isLog ? this.coreUtils.getLogVal(this.logBase, w.globals.maxY, 0) : w.globals.maxY;
      this.minValue = this.isLog ? this.coreUtils.getLogVal(this.logBase, this.w.globals.minY, 0) : w.globals.minY;
      this.polygons = w.config.plotOptions.radar.polygons;
      this.strokeWidth = w.config.stroke.show ? w.config.stroke.width : 0;
      this.size = this.defaultSize / 2.1 - this.strokeWidth - w.config.chart.dropShadow.blur;
      if (w.config.xaxis.labels.show) {
        this.size = this.size - w.layout.xAxisLabelsWidth / 1.75;
      }
      if (w.config.plotOptions.radar.size !== void 0) {
        this.size = w.config.plotOptions.radar.size;
      }
      this.dataRadiusOfPercent = /** @type {any} */
      [];
      this.dataRadius = /** @type {any} */
      [];
      this.angleArr = /** @type {any} */
      [];
      this.dataPointsLen = 0;
      this.disAngle = 0;
      this.yaxisLabelsTextsPos = [];
    }
    /**
     * @param {any[]} series
     */
    draw(series) {
      const w = this.w;
      const fill = new Fill(this.w);
      const allSeries = [];
      const dataLabels = new DataLabels(this.w, this.ctx);
      if (series.length) {
        this.dataPointsLen = series[w.globals.maxValsInArrayIndex].length;
      }
      this.disAngle = Math.PI * 2 / this.dataPointsLen;
      const halfW = w.layout.gridWidth / 2;
      const halfH = w.layout.gridHeight / 2;
      const translateX = halfW + w.config.plotOptions.radar.offsetX;
      const translateY = halfH + w.config.plotOptions.radar.offsetY;
      const ret = this.graphics.group({
        class: "apexcharts-radar-series apexcharts-plot-series",
        transform: `translate(${translateX || 0}, ${translateY || 0})`
      });
      let dataPointsPos = [];
      let elPointsMain = null;
      let elDataPointsMain = null;
      this.yaxisLabels = this.graphics.group({
        class: "apexcharts-yaxis"
      });
      series.forEach((s, i) => {
        const longestSeries = s.length === w.globals.dataPoints;
        const elSeries = this.graphics.group().attr({
          class: `apexcharts-series`,
          "data:longestSeries": longestSeries,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
          rel: i + 1,
          "data:realIndex": i
        });
        this.dataRadiusOfPercent[i] = [];
        this.dataRadius[i] = [];
        this.angleArr[i] = [];
        s.forEach((dv, j) => {
          const range = Math.abs(this.maxValue - this.minValue);
          dv = dv - this.minValue;
          if (this.isLog) {
            dv = this.coreUtils.getLogVal(this.logBase, dv, 0);
          }
          this.dataRadiusOfPercent[i][j] = dv / range;
          this.dataRadius[i][j] = this.dataRadiusOfPercent[i][j] * this.size;
          this.angleArr[i][j] = j * this.disAngle;
        });
        dataPointsPos = this.getDataPointsPos(
          this.dataRadius[i],
          this.angleArr[i]
        );
        const paths = this.createPaths(dataPointsPos, {
          x: 0,
          y: 0
        });
        elPointsMain = this.graphics.group({
          class: "apexcharts-series-markers-wrap apexcharts-element-hidden"
        });
        elDataPointsMain = this.graphics.group({
          class: `apexcharts-datalabels`,
          "data:realIndex": i
        });
        w.globals.delayedElements.push({
          el: elPointsMain.node,
          index: i
        });
        const defaultRenderedPathOptions = {
          i,
          realIndex: i,
          animationDelay: i,
          initialSpeed: w.config.chart.animations.speed,
          dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed,
          className: `apexcharts-radar`,
          shouldClipToGrid: false,
          bindEventsOnPaths: false,
          stroke: w.globals.stroke.colors[i],
          strokeLineCap: w.config.stroke.lineCap
        };
        let pathFrom = null;
        if (w.globals.previousPaths.length > 0) {
          pathFrom = this.getPreviousPath(i);
        }
        for (let p = 0; p < paths.linePathsTo.length; p++) {
          const renderedLinePath = this.graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
            pathFrom: pathFrom === null ? paths.linePathsFrom[p] : pathFrom,
            pathTo: paths.linePathsTo[p],
            strokeWidth: Array.isArray(this.strokeWidth) ? this.strokeWidth[i] : this.strokeWidth,
            fill: "none",
            drawShadow: false
          }));
          elSeries.add(renderedLinePath);
          const pathFill = fill.fillPath({
            seriesNumber: i
          });
          const renderedAreaPath = this.graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), {
            pathFrom: pathFrom === null ? paths.areaPathsFrom[p] : pathFrom,
            pathTo: paths.areaPathsTo[p],
            strokeWidth: 0,
            fill: pathFill,
            drawShadow: false
          }));
          if (w.config.chart.dropShadow.enabled) {
            const filters = new Filters(this.w);
            const shadow = w.config.chart.dropShadow;
            filters.dropShadow(
              renderedAreaPath,
              Object.assign({}, shadow, { noUserSpaceOnUse: true }),
              i
            );
          }
          elSeries.add(renderedAreaPath);
        }
        s.forEach((sj, j) => {
          const markers = new Markers(this.w, this.ctx);
          const opts = markers.getMarkerConfig({
            cssClass: "apexcharts-marker",
            seriesIndex: i,
            dataPointIndex: j
          });
          const point = this.graphics.drawMarker(
            dataPointsPos[j].x,
            dataPointsPos[j].y,
            opts
          );
          point.attr("rel", j);
          point.attr("j", j);
          point.attr("index", i);
          point.node.setAttribute("default-marker-size", opts.pSize);
          const elPointsWrap = this.graphics.group({
            class: "apexcharts-series-markers"
          });
          if (elPointsWrap) {
            elPointsWrap.add(point);
          }
          elPointsMain.add(elPointsWrap);
          elSeries.add(elPointsMain);
          const dataLabelsConfig = w.config.dataLabels;
          if (dataLabelsConfig.enabled) {
            const text = dataLabelsConfig.formatter(w.seriesData.series[i][j], {
              seriesIndex: i,
              dataPointIndex: j,
              w
            });
            dataLabels.plotDataLabelsText({
              x: dataPointsPos[j].x,
              y: dataPointsPos[j].y,
              text,
              textAnchor: "middle",
              i,
              j: i,
              parent: elDataPointsMain,
              offsetCorrection: false,
              dataLabelsConfig: __spreadValues({}, dataLabelsConfig)
            });
          }
          elSeries.add(elDataPointsMain);
        });
        allSeries.push(elSeries);
      });
      this.drawPolygons({
        parent: ret
      });
      if (w.config.xaxis.labels.show) {
        const xaxisTexts = this.drawXAxisTexts();
        ret.add(xaxisTexts);
      }
      allSeries.forEach((elS) => {
        ret.add(elS);
      });
      ret.add(this.yaxisLabels);
      return ret;
    }
    /**
     * @param {Record<string, any>} opts
     */
    drawPolygons(opts) {
      const w = this.w;
      const { parent } = opts;
      const helpers = new CircularChartsHelpers(this.w);
      const yaxisTexts = w.globals.yAxisScale[0].result.reverse();
      const layers = yaxisTexts.length;
      const radiusSizes = [];
      const layerDis = this.size / (layers - 1);
      for (let i = 0; i < layers; i++) {
        radiusSizes[i] = layerDis * i;
      }
      radiusSizes.reverse();
      const polygonStrings = [];
      const lines = [];
      radiusSizes.forEach((radiusSize, r) => {
        const polygon = Utils$1.getPolygonPos(radiusSize, this.dataPointsLen);
        let string = "";
        polygon.forEach((p, i) => {
          if (r === 0) {
            const line = this.graphics.drawLine(
              p.x,
              p.y,
              0,
              0,
              Array.isArray(this.polygons.connectorColors) ? this.polygons.connectorColors[i] : this.polygons.connectorColors
            );
            lines.push(line);
          }
          if (i === 0) {
            this.yaxisLabelsTextsPos.push({
              x: p.x,
              y: p.y
            });
          }
          string += p.x + "," + p.y + " ";
        });
        polygonStrings.push(string);
      });
      polygonStrings.forEach((p, i) => {
        const strokeColors = this.polygons.strokeColors;
        const strokeWidth = this.polygons.strokeWidth;
        const polygon = this.graphics.drawPolygon(
          p,
          Array.isArray(strokeColors) ? strokeColors[i] : strokeColors,
          Array.isArray(strokeWidth) ? strokeWidth[i] : strokeWidth,
          w.globals.radarPolygons.fill.colors[i]
        );
        parent.add(polygon);
      });
      lines.forEach((l) => {
        parent.add(l);
      });
      if (w.config.yaxis[0].show) {
        this.yaxisLabelsTextsPos.forEach(
          (p, i) => {
            const yText = helpers.drawYAxisTexts(p.x, p.y, i, yaxisTexts[i]);
            this.yaxisLabels.add(yText);
          }
        );
      }
    }
    drawXAxisTexts() {
      const w = this.w;
      const xaxisLabelsConfig = w.config.xaxis.labels;
      const elXAxisWrap = this.graphics.group({
        class: "apexcharts-xaxis"
      });
      const polygonPos = Utils$1.getPolygonPos(this.size, this.dataPointsLen);
      w.labelData.labels.forEach((label, i) => {
        const formatter = w.config.xaxis.labels.formatter;
        const dataLabels = new DataLabels(this.w, this.ctx);
        if (polygonPos[i]) {
          const textPos = this.getTextPos(polygonPos[i], this.size);
          const text = formatter(label, {
            seriesIndex: -1,
            dataPointIndex: i,
            w
          });
          const dataLabelText = dataLabels.plotDataLabelsText({
            x: textPos.newX,
            y: textPos.newY,
            text,
            textAnchor: textPos.textAnchor,
            i,
            j: i,
            parent: elXAxisWrap,
            className: "apexcharts-xaxis-label",
            color: Array.isArray(xaxisLabelsConfig.style.colors) && xaxisLabelsConfig.style.colors[i] ? xaxisLabelsConfig.style.colors[i] : "#a8a8a8",
            dataLabelsConfig: __spreadValues({
              textAnchor: textPos.textAnchor,
              dropShadow: { enabled: false }
            }, xaxisLabelsConfig),
            offsetCorrection: false
          });
          dataLabelText.on("click", (e) => {
            if (typeof w.config.chart.events.xAxisLabelClick === "function") {
              const opts = Object.assign({}, w, {
                labelIndex: i
              });
              w.config.chart.events.xAxisLabelClick(e, this.ctx, opts);
            }
          });
        }
      });
      return elXAxisWrap;
    }
    /**
     * @param {Array<Record<string, any>>} pos
     * @param {Record<string, any>} origin
     */
    createPaths(pos, origin) {
      const linePathsTo = [];
      let linePathsFrom = [];
      const areaPathsTo = [];
      let areaPathsFrom = [];
      if (pos.length) {
        linePathsFrom = [this.graphics.move(origin.x, origin.y)];
        areaPathsFrom = [this.graphics.move(origin.x, origin.y)];
        let linePathTo = this.graphics.move(pos[0].x, pos[0].y);
        let areaPathTo = this.graphics.move(pos[0].x, pos[0].y);
        pos.forEach((p, i) => {
          linePathTo += this.graphics.line(p.x, p.y);
          areaPathTo += this.graphics.line(p.x, p.y);
          if (i === pos.length - 1) {
            linePathTo += "Z";
            areaPathTo += "Z";
          }
        });
        linePathsTo.push(linePathTo);
        areaPathsTo.push(areaPathTo);
      }
      return {
        linePathsFrom,
        linePathsTo,
        areaPathsFrom,
        areaPathsTo
      };
    }
    /**
     * @param {Record<string, any>} pos
     * @param {number} polygonSize
     */
    getTextPos(pos, polygonSize) {
      const limit = 10;
      let textAnchor = "middle";
      let newX = pos.x;
      let newY = pos.y;
      if (Math.abs(pos.x) >= limit) {
        if (pos.x > 0) {
          textAnchor = "start";
          newX += 10;
        } else if (pos.x < 0) {
          textAnchor = "end";
          newX -= 10;
        }
      } else {
        textAnchor = "middle";
      }
      if (Math.abs(pos.y) >= polygonSize - limit) {
        if (pos.y < 0) {
          newY -= 10;
        } else if (pos.y > 0) {
          newY += 10;
        }
      }
      return {
        textAnchor,
        newX,
        newY
      };
    }
    /**
     * @param {number} realIndex
     */
    getPreviousPath(realIndex) {
      const w = this.w;
      let pathFrom = null;
      for (let pp = 0; pp < w.globals.previousPaths.length; pp++) {
        const gpp = w.globals.previousPaths[pp];
        if (gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(String(realIndex), 10)) {
          if (typeof w.globals.previousPaths[pp].paths[0] !== "undefined") {
            pathFrom = w.globals.previousPaths[pp].paths[0].d;
          }
        }
      }
      return pathFrom;
    }
    /**
     * @param {any[]} dataRadiusArr
     * @param {any[]} angleArr
     */
    getDataPointsPos(dataRadiusArr, angleArr, dataPointsLen = this.dataPointsLen) {
      dataRadiusArr = dataRadiusArr || [];
      angleArr = angleArr || [];
      const dataPointsPosArray = [];
      for (let j = 0; j < dataPointsLen; j++) {
        const curPointPos = {};
        curPointPos.x = dataRadiusArr[j] * Math.sin(angleArr[j]);
        curPointPos.y = -dataRadiusArr[j] * Math.cos(angleArr[j]);
        dataPointsPosArray.push(curPointPos);
      }
      return dataPointsPosArray;
    }
  }
  class Radial extends Pie {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      super(w, ctx);
      this.ctx = ctx;
      this.w = w;
      this.animBeginArr = [0];
      this.animDur = 0;
      this.startAngle = w.config.plotOptions.radialBar.startAngle;
      this.endAngle = w.config.plotOptions.radialBar.endAngle;
      this.totalAngle = Math.abs(
        w.config.plotOptions.radialBar.endAngle - w.config.plotOptions.radialBar.startAngle
      );
      this.trackStartAngle = w.config.plotOptions.radialBar.track.startAngle;
      this.trackEndAngle = w.config.plotOptions.radialBar.track.endAngle;
      this.barLabels = this.w.config.plotOptions.radialBar.barLabels;
      this.donutDataLabels = this.w.config.plotOptions.radialBar.dataLabels;
      this.radialDataLabels = this.donutDataLabels;
      if (!this.trackStartAngle) this.trackStartAngle = this.startAngle;
      if (!this.trackEndAngle) this.trackEndAngle = this.endAngle;
      if (this.endAngle === 360) this.endAngle = 359.99;
      this.margin = parseInt(w.config.plotOptions.radialBar.track.margin, 10);
      this.onBarLabelClick = this.onBarLabelClick.bind(this);
    }
    /**
     * @param {any[]} series
     */
    draw(series) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const ret = graphics.group({
        class: "apexcharts-radialbar"
      });
      if (w.globals.noData) return ret;
      const elSeries = graphics.group();
      const centerY = this.defaultSize / 2;
      const centerX = w.layout.gridWidth / 2;
      let size = this.defaultSize / 2.05;
      if (!w.config.chart.sparkline.enabled) {
        size = size - w.config.stroke.width - w.config.chart.dropShadow.blur;
      }
      const colorArr = w.globals.fill.colors;
      if (w.config.plotOptions.radialBar.track.show) {
        const elTracks = this.drawTracks({
          size,
          centerX,
          centerY,
          colorArr,
          series
        });
        elSeries.add(elTracks);
      }
      const elG = this.drawArcs({
        size,
        centerX,
        centerY,
        colorArr,
        series
      });
      let totalAngle = 360;
      if (w.config.plotOptions.radialBar.startAngle < 0) {
        totalAngle = this.totalAngle;
      }
      const angleRatio = (360 - totalAngle) / 360;
      w.globals.radialSize = size - size * angleRatio;
      if (this.radialDataLabels.value.show) {
        const offset = Math.max(
          this.radialDataLabels.value.offsetY,
          this.radialDataLabels.name.offsetY
        );
        w.globals.radialSize += offset * angleRatio;
      }
      elSeries.add(elG.g);
      if (w.config.plotOptions.radialBar.hollow.position === "front") {
        elG.g.add(elG.elHollow);
        if (elG.dataLabels) {
          elG.g.add(elG.dataLabels);
        }
      }
      ret.add(elSeries);
      return ret;
    }
    /**
     * @param {Record<string, any>} opts
     */
    drawTracks(opts) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const g = graphics.group({
        class: "apexcharts-tracks"
      });
      const filters = new Filters(this.w);
      const fill = new Fill(this.w);
      const strokeWidth = this.getStrokeWidth(opts);
      opts.size = opts.size - strokeWidth / 2;
      for (let i = 0; i < opts.series.length; i++) {
        const elRadialBarTrack = graphics.group({
          class: "apexcharts-radialbar-track apexcharts-track"
        });
        g.add(elRadialBarTrack);
        elRadialBarTrack.attr({
          rel: i + 1
        });
        opts.size = opts.size - strokeWidth - this.margin;
        const trackConfig = w.config.plotOptions.radialBar.track;
        const pathFill = fill.fillPath({
          seriesNumber: 0,
          size: opts.size,
          fillColors: Array.isArray(trackConfig.background) ? trackConfig.background[i] : trackConfig.background,
          solid: true
        });
        const startAngle = this.trackStartAngle;
        let endAngle = this.trackEndAngle;
        if (Math.abs(endAngle) + Math.abs(startAngle) >= 360)
          endAngle = 360 - Math.abs(this.startAngle) - 0.1;
        const elPath = graphics.drawPath({
          d: "",
          stroke: pathFill,
          strokeWidth: strokeWidth * parseInt(trackConfig.strokeWidth, 10) / 100,
          fill: "none",
          strokeOpacity: trackConfig.opacity,
          classes: "apexcharts-radialbar-area"
        });
        if (trackConfig.dropShadow.enabled) {
          const shadow = trackConfig.dropShadow;
          filters.dropShadow(elPath, shadow);
        }
        elRadialBarTrack.add(elPath);
        elPath.attr("id", "apexcharts-radialbarTrack-" + i);
        this.animatePaths(elPath, {
          centerX: opts.centerX,
          centerY: opts.centerY,
          endAngle,
          startAngle,
          size: opts.size,
          i,
          totalItems: 2,
          animBeginArr: 0,
          dur: 0,
          isTrack: true
        });
      }
      return g;
    }
    /**
     * @param {Record<string, any>} opts
     */
    drawArcs(opts) {
      const w = this.w;
      const graphics = new Graphics(this.w);
      const fill = new Fill(this.w);
      const filters = new Filters(this.w);
      const g = graphics.group();
      const strokeWidth = this.getStrokeWidth(opts);
      opts.size = opts.size - strokeWidth / 2;
      let hollowFillID = w.config.plotOptions.radialBar.hollow.background;
      const hollowSize = opts.size - strokeWidth * opts.series.length - this.margin * opts.series.length - strokeWidth * parseInt(w.config.plotOptions.radialBar.track.strokeWidth, 10) / 100 / 2;
      const hollowRadius = hollowSize - w.config.plotOptions.radialBar.hollow.margin;
      if (w.config.plotOptions.radialBar.hollow.image !== void 0) {
        hollowFillID = this.drawHollowImage(opts, g, hollowSize, hollowFillID);
      }
      const elHollow = this.drawHollow({
        size: hollowRadius,
        centerX: opts.centerX,
        centerY: opts.centerY,
        fill: hollowFillID ? hollowFillID : "transparent"
      });
      if (w.config.plotOptions.radialBar.hollow.dropShadow.enabled) {
        const shadow = w.config.plotOptions.radialBar.hollow.dropShadow;
        filters.dropShadow(elHollow, shadow);
      }
      let shown = 1;
      if (!this.radialDataLabels.total.show && w.seriesData.series.length > 1) {
        shown = 0;
      }
      let dataLabels = null;
      if (this.radialDataLabels.show) {
        const dataLabelsGroup = w.dom.Paper.findOne(
          `.apexcharts-datalabels-group`
        );
        dataLabels = this.renderInnerDataLabels(
          dataLabelsGroup,
          this.radialDataLabels,
          {
            hollowSize,
            centerX: opts.centerX,
            centerY: opts.centerY,
            opacity: shown
          }
        );
      }
      if (w.config.plotOptions.radialBar.hollow.position === "back") {
        g.add(elHollow);
        if (dataLabels) {
          g.add(dataLabels);
        }
      }
      let reverseLoop = false;
      if (w.config.plotOptions.radialBar.inverseOrder) {
        reverseLoop = true;
      }
      for (let i = reverseLoop ? opts.series.length - 1 : 0; reverseLoop ? i >= 0 : i < opts.series.length; reverseLoop ? i-- : i++) {
        const elRadialBarArc = graphics.group({
          class: `apexcharts-series apexcharts-radial-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i])
        });
        g.add(elRadialBarArc);
        elRadialBarArc.attr({
          rel: i + 1,
          "data:realIndex": i
        });
        Series.addCollapsedClassToSeries(this.w, elRadialBarArc, i);
        opts.size = opts.size - strokeWidth - this.margin;
        const pathFill = fill.fillPath({
          seriesNumber: i,
          size: opts.size,
          value: opts.series[i]
        });
        const startAngle = this.startAngle;
        let prevStartAngle;
        const dataValue = Utils$1.negToZero(opts.series[i] > 100 ? 100 : opts.series[i]) / 100;
        let endAngle = Math.round(this.totalAngle * dataValue) + this.startAngle;
        let prevEndAngle;
        if (w.globals.dataChanged) {
          prevStartAngle = this.startAngle;
          prevEndAngle = Math.round(
            this.totalAngle * Utils$1.negToZero(w.globals.previousPaths[i]) / 100
          ) + prevStartAngle;
        }
        const currFullAngle = Math.abs(endAngle) + Math.abs(startAngle);
        if (currFullAngle > 360) {
          endAngle = endAngle - 0.01;
        }
        const prevFullAngle = Math.abs(prevEndAngle) + Math.abs(prevStartAngle);
        if (prevFullAngle > 360) {
          prevEndAngle = prevEndAngle - 0.01;
        }
        const angle = endAngle - startAngle;
        const dashArray = Array.isArray(w.config.stroke.dashArray) ? w.config.stroke.dashArray[i] : w.config.stroke.dashArray;
        const elPath = graphics.drawPath({
          d: "",
          stroke: pathFill,
          strokeWidth,
          fill: "none",
          fillOpacity: w.config.fill.opacity,
          classes: "apexcharts-radialbar-area apexcharts-radialbar-slice-" + i,
          strokeDashArray: dashArray
        });
        const radialMidAngle = startAngle + angle / 2;
        const radialArcCenter = Utils$1.polarToCartesian(
          opts.centerX,
          opts.centerY,
          opts.size,
          radialMidAngle
        );
        Graphics.setAttrs(elPath.node, {
          "data:angle": angle,
          "data:value": opts.series[i],
          "data:cx": radialArcCenter.x,
          "data:cy": radialArcCenter.y
        });
        if (w.config.chart.dropShadow.enabled) {
          const shadow = w.config.chart.dropShadow;
          filters.dropShadow(elPath, shadow, i);
        }
        filters.setSelectionFilter(elPath, 0, i);
        this.addListeners(elPath, this.radialDataLabels);
        elRadialBarArc.add(elPath);
        elPath.attr({
          index: 0,
          j: i
        });
        if (this.barLabels.enabled) {
          const barStartCords = Utils$1.polarToCartesian(
            opts.centerX,
            opts.centerY,
            opts.size,
            startAngle
          );
          const text = this.barLabels.formatter(w.seriesData.seriesNames[i], {
            seriesIndex: i,
            w
          });
          const classes = ["apexcharts-radialbar-label"];
          if (!this.barLabels.onClick) {
            classes.push("apexcharts-no-click");
          }
          let textColor = this.barLabels.useSeriesColors ? w.globals.colors[i] : w.config.chart.foreColor;
          if (!textColor) {
            textColor = w.config.chart.foreColor;
          }
          const x = barStartCords.x + this.barLabels.offsetX;
          const y = barStartCords.y + this.barLabels.offsetY;
          const elText = graphics.drawText({
            x,
            y,
            text,
            textAnchor: "end",
            dominantBaseline: "middle",
            fontFamily: this.barLabels.fontFamily,
            fontWeight: this.barLabels.fontWeight,
            fontSize: this.barLabels.fontSize,
            foreColor: textColor,
            cssClass: classes.join(" ")
          });
          elText.on("click", this.onBarLabelClick);
          elText.attr({
            rel: i + 1
          });
          if (startAngle !== 0) {
            elText.attr({
              "transform-origin": `${x} ${y}`,
              transform: `rotate(${startAngle} 0 0)`
            });
          }
          elRadialBarArc.add(elText);
        }
        let dur = 0;
        if (this.initialAnim && !w.globals.resized && !w.globals.dataChanged) {
          dur = w.config.chart.animations.speed;
        }
        if (w.globals.dataChanged) {
          dur = w.config.chart.animations.dynamicAnimation.speed;
        }
        this.animDur = dur / (opts.series.length * 1.2) + this.animDur;
        this.animBeginArr.push(this.animDur);
        this.animatePaths(elPath, {
          centerX: opts.centerX,
          centerY: opts.centerY,
          endAngle,
          startAngle,
          prevEndAngle,
          prevStartAngle,
          size: opts.size,
          i,
          totalItems: 2,
          animBeginArr: this.animBeginArr,
          dur,
          shouldSetPrevPaths: true
        });
      }
      return {
        g,
        elHollow,
        dataLabels
      };
    }
    /**
     * @param {Record<string, any>} opts
     */
    drawHollow(opts) {
      const graphics = new Graphics(this.w);
      const circle = graphics.drawCircle(opts.size * 2);
      circle.attr({
        class: "apexcharts-radialbar-hollow",
        cx: opts.centerX,
        cy: opts.centerY,
        r: opts.size,
        fill: opts.fill
      });
      return circle;
    }
    /**
     * @param {Record<string, any>} opts
     * @param {any} g
     * @param {number} hollowSize
     * @param {string} hollowFillID
     */
    drawHollowImage(opts, g, hollowSize, hollowFillID) {
      const w = this.w;
      const fill = new Fill(this.w);
      const randID = Utils$1.randomId();
      const hollowFillImg = w.config.plotOptions.radialBar.hollow.image;
      if (w.config.plotOptions.radialBar.hollow.imageClipped) {
        fill.clippedImgArea({
          width: hollowSize,
          height: hollowSize,
          image: hollowFillImg,
          patternID: `pattern${w.globals.cuid}${randID}`
        });
        hollowFillID = `url(#pattern${w.globals.cuid}${randID})`;
      } else {
        const imgWidth = w.config.plotOptions.radialBar.hollow.imageWidth;
        const imgHeight = w.config.plotOptions.radialBar.hollow.imageHeight;
        if (imgWidth === void 0 && imgHeight === void 0) {
          const image = w.dom.Paper.image(
            hollowFillImg,
            /** @this {any} */
            function(loader) {
              this.move(
                opts.centerX - loader.width / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetX,
                opts.centerY - loader.height / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetY
              );
            }
          );
          g.add(image);
        } else {
          const image = w.dom.Paper.image(
            hollowFillImg,
            /** @this {any} */
            function() {
              this.move(
                opts.centerX - imgWidth / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetX,
                opts.centerY - imgHeight / 2 + w.config.plotOptions.radialBar.hollow.imageOffsetY
              );
              this.size(imgWidth, imgHeight);
            }
          );
          g.add(image);
        }
      }
      return hollowFillID;
    }
    /**
     * @param {Record<string, any>} opts
     */
    getStrokeWidth(opts) {
      const w = this.w;
      return opts.size * (100 - parseInt(w.config.plotOptions.radialBar.hollow.size, 10)) / 100 / (opts.series.length + 1) - this.margin;
    }
    /**
     * @param {Event} e
     */
    onBarLabelClick(e) {
      var _a;
      const target = (
        /** @type {Element} */
        e.target
      );
      const seriesIndex = parseInt((_a = target.getAttribute("rel")) != null ? _a : "", 10) - 1;
      const legendClick = this.barLabels.onClick;
      const w = this.w;
      if (legendClick) {
        legendClick(w.seriesData.seriesNames[seriesIndex], { w, seriesIndex });
      }
    }
  }
  class RangeBar extends Bar {
    /**
     * @param {any[]} series
     * @param {number} seriesIndex
     */
    draw(series, seriesIndex) {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i;
      const w = this.w;
      const graphics = new Graphics(this.w);
      this.rangeBarOptions = this.w.config.plotOptions.rangeBar;
      this.series = series;
      this.seriesRangeStart = w.rangeData.seriesRangeStart;
      this.seriesRangeEnd = w.rangeData.seriesRangeEnd;
      this.barHelpers.initVariables(series);
      const ret = graphics.group({
        class: "apexcharts-rangebar-series apexcharts-plot-series"
      });
      for (let i = 0; i < series.length; i++) {
        let x, y;
        const realIndex = w.globals.comboCharts ? (
          /** @type {any} */
          seriesIndex[i]
        ) : i;
        const { columnGroupIndex } = this.barHelpers.getGroupIndex(realIndex);
        const elSeries = graphics.group({
          class: `apexcharts-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[realIndex]),
          rel: i + 1,
          "data:realIndex": realIndex
        });
        Series.addCollapsedClassToSeries(this.w, elSeries, realIndex);
        if (series[i].length > 0) {
          this.visibleI = this.visibleI + 1;
        }
        let translationsIndex = 0;
        if (this.yRatio.length > 1) {
          this.yaxisIndex = /** @type {any} */
          w.globals.seriesYAxisReverseMap[realIndex][0];
          translationsIndex = realIndex;
        }
        const initPositions = this.barHelpers.initialPositions(realIndex);
        const {
          y: initY,
          zeroW,
          // zeroW is the baseline where 0 meets x axis
          x: initX,
          zeroH
          // zeroH is the baseline where 0 meets y axis
        } = initPositions;
        let barWidth = (_a = initPositions.barWidth) != null ? _a : 0;
        let barHeight = (_b = initPositions.barHeight) != null ? _b : 0;
        const yDivision = (_c = initPositions.yDivision) != null ? _c : 0;
        const xDivision = (_d = initPositions.xDivision) != null ? _d : 0;
        y = initY;
        x = initX;
        const elDataLabelsWrap = graphics.group({
          class: "apexcharts-datalabels",
          "data:realIndex": realIndex
        });
        const elGoalsMarkers = graphics.group({
          class: "apexcharts-rangebar-goals-markers"
        });
        for (let j = 0; j < w.globals.dataPoints; j++) {
          const strokeWidth = this.barHelpers.getStrokeWidth(i, j, realIndex);
          const y1 = this.seriesRangeStart[i][j];
          const y2 = this.seriesRangeEnd[i][j];
          let paths = (
            /** @type {any} */
            null
          );
          let barXPosition = null;
          let barYPosition = null;
          const params = { x, y, strokeWidth, elSeries };
          let seriesLen = this.seriesLen;
          if (w.config.plotOptions.bar.rangeBarGroupRows) {
            seriesLen = 1;
          }
          if (typeof /** @type {Record<string,any>} */
          ((_e = w.config.series[i].data) == null ? void 0 : _e[j]) === "undefined") {
            break;
          }
          if (this.isHorizontal) {
            barYPosition = y + barHeight * /** @type {any} */
            this.visibleI;
            const srty = (yDivision - barHeight * seriesLen) / 2;
            if (
              /** @type {Record<string,any>} */
              (_g = (_f = w.config.series[i].data) == null ? void 0 : _f[j]) == null ? void 0 : _g.x
            ) {
              const positions = this.detectOverlappingBars({
                i,
                j,
                barYPosition,
                srty,
                barHeight,
                yDivision,
                initPositions
              });
              barHeight = positions.barHeight;
              barYPosition = positions.barYPosition;
            }
            paths = this.drawRangeBarPaths(__spreadValues({
              indexes: { i, j, realIndex },
              barHeight,
              barYPosition,
              zeroW,
              yDivision,
              y1,
              y2
            }, params));
            barWidth = paths.barWidth;
          } else {
            if (w.axisFlags.isXNumeric) {
              x = (w.seriesData.seriesX[i][j] - w.globals.minX) / this.xRatio - barWidth / 2;
            }
            barXPosition = x + barWidth * /** @type {any} */
            this.visibleI;
            const srtx = (xDivision - barWidth * seriesLen) / 2;
            if (
              /** @type {Record<string,any>} */
              (_i = (_h = w.config.series[i].data) == null ? void 0 : _h[j]) == null ? void 0 : _i.x
            ) {
              const positions = this.detectOverlappingBars({
                i,
                j,
                barXPosition,
                srtx,
                barWidth,
                xDivision,
                initPositions
              });
              barWidth = positions.barWidth;
              barXPosition = positions.barXPosition;
            }
            paths = this.drawRangeColumnPaths(__spreadValues({
              indexes: { i, j, realIndex, translationsIndex },
              barWidth,
              barXPosition,
              zeroH,
              xDivision
            }, params));
            barHeight = paths.barHeight;
          }
          const barGoalLine = this.barHelpers.drawGoalLine({
            barXPosition: paths.barXPosition,
            barYPosition,
            goalX: paths.goalX,
            goalY: paths.goalY,
            barHeight,
            barWidth
          });
          if (barGoalLine) {
            elGoalsMarkers.add(barGoalLine);
          }
          y = paths.y;
          x = paths.x;
          const pathFill = this.barHelpers.getPathFillColor(
            series,
            i,
            j,
            realIndex
          );
          this.renderSeries({
            realIndex,
            pathFill: pathFill.color,
            lineFill: pathFill.useRangeColor ? pathFill.color : w.globals.stroke.colors[realIndex],
            j,
            i,
            x,
            y,
            y1,
            y2,
            pathFrom: paths.pathFrom,
            pathTo: paths.pathTo,
            strokeWidth,
            elSeries,
            series,
            barHeight,
            barWidth,
            barXPosition,
            barYPosition,
            columnGroupIndex,
            elDataLabelsWrap,
            elGoalsMarkers,
            visibleSeries: this.visibleI,
            type: "rangebar"
          });
        }
        ret.add(elSeries);
      }
      return ret;
    }
    /** @param {{ i?: any, j?: any, barYPosition?: any, barXPosition?: any, srty?: any, srtx?: any, barHeight?: any, barWidth?: any, yDivision?: any, xDivision?: any, initPositions?: any }} opts */
    detectOverlappingBars({
      i,
      j,
      barYPosition,
      barXPosition,
      srty,
      srtx,
      barHeight,
      barWidth,
      yDivision,
      xDivision,
      initPositions
    }) {
      var _a, _b, _c, _d;
      const w = this.w;
      let overlaps = [];
      const rangeName = (
        /** @type {Record<string,any>} */
        (_b = (_a = w.config.series[i].data) == null ? void 0 : _a[j]) == null ? void 0 : _b.rangeName
      );
      const x = (
        /** @type {Record<string,any>} */
        (_d = (_c = w.config.series[i].data) == null ? void 0 : _c[j]) == null ? void 0 : _d.x
      );
      const labelX = Array.isArray(x) ? x.join(" ") : x;
      const rowIndex = w.labelData.labels.map((_) => Array.isArray(_) ? _.join(" ") : _).indexOf(labelX);
      const overlappedIndex = w.rangeData.seriesRange[i].findIndex(
        (tx) => {
          var _a2;
          return tx.x === labelX && ((_a2 = tx.overlaps) == null ? void 0 : _a2.size) > 0;
        }
      );
      if (this.isHorizontal) {
        if (w.config.plotOptions.bar.rangeBarGroupRows) {
          barYPosition = srty + yDivision * rowIndex;
        } else {
          barYPosition = srty + barHeight * this.visibleI + yDivision * rowIndex;
        }
        if (overlappedIndex > -1 && !w.config.plotOptions.bar.rangeBarOverlap) {
          overlaps = Array.from(
            /** @type {any} */
            w.rangeData.seriesRange[i][overlappedIndex].overlaps
          );
          if (overlaps.indexOf(rangeName) > -1) {
            barHeight = initPositions.barHeight / overlaps.length;
            barYPosition = barHeight * this.visibleI + yDivision * (100 - parseInt(this.barOptions.barHeight, 10)) / 100 / 2 + barHeight * (this.visibleI + overlaps.indexOf(rangeName)) + yDivision * rowIndex;
          }
        }
      } else {
        if (rowIndex > -1 && !w.labelData.timescaleLabels.length) {
          if (w.config.plotOptions.bar.rangeBarGroupRows) {
            barXPosition = srtx + xDivision * rowIndex;
          } else {
            barXPosition = srtx + barWidth * this.visibleI + xDivision * rowIndex;
          }
        }
        if (overlappedIndex > -1 && !w.config.plotOptions.bar.rangeBarOverlap) {
          overlaps = Array.from(
            /** @type {any} */
            w.rangeData.seriesRange[i][overlappedIndex].overlaps
          );
          if (overlaps.indexOf(rangeName) > -1) {
            barWidth = initPositions.barWidth / overlaps.length;
            barXPosition = barWidth * this.visibleI + xDivision * (100 - parseInt(this.barOptions.barWidth, 10)) / 100 / 2 + barWidth * (this.visibleI + overlaps.indexOf(rangeName)) + xDivision * rowIndex;
          }
        }
      }
      return {
        barYPosition,
        barXPosition,
        barHeight,
        barWidth
      };
    }
    /** @param {{indexes: any, x: any, xDivision: any, barWidth: any, barXPosition: any, zeroH: any}} opts */
    drawRangeColumnPaths({
      indexes,
      x,
      xDivision,
      barWidth,
      barXPosition,
      zeroH
    }) {
      var _a, _b;
      const w = this.w;
      const { i, j, realIndex, translationsIndex } = indexes;
      const yRatio = this.yRatio[translationsIndex];
      const range = this.getRangeValue(realIndex, j);
      let y1 = Math.min(range.start, range.end);
      let y2 = Math.max(range.start, range.end);
      if (typeof /** @type {any} */
      ((_a = this.series[i]) == null ? void 0 : _a[j]) === "undefined" || /** @type {any} */
      ((_b = this.series[i]) == null ? void 0 : _b[j]) === null) {
        y1 = zeroH;
      } else {
        y1 = zeroH - y1 / yRatio;
        y2 = zeroH - y2 / yRatio;
      }
      const barHeight = Math.abs(y2 - y1);
      const paths = this.barHelpers.getColumnPaths({
        barXPosition,
        barWidth,
        y1,
        y2,
        strokeWidth: this.strokeWidth,
        series: this.seriesRangeEnd,
        realIndex,
        i: realIndex,
        j,
        w
      });
      if (!w.axisFlags.isXNumeric) {
        x = x + xDivision;
      } else {
        const xForNumericXAxis = this.getBarXForNumericXAxis({
          x,
          j,
          realIndex,
          barWidth
        });
        x = xForNumericXAxis.x;
        barXPosition = xForNumericXAxis.barXPosition;
      }
      return {
        pathTo: paths.pathTo,
        pathFrom: paths.pathFrom,
        barHeight,
        x,
        y: range.start < 0 && range.end < 0 ? y1 : y2,
        goalY: this.barHelpers.getGoalValues(
          "y",
          /** @type {any} */
          null,
          zeroH,
          i,
          j,
          translationsIndex
        ),
        barXPosition
      };
    }
    /**
     * @param {number} val
     */
    preventBarOverflow(val) {
      const w = this.w;
      if (val < 0) {
        val = 0;
      }
      if (val > w.layout.gridWidth) {
        val = w.layout.gridWidth;
      }
      return val;
    }
    /** @param {{indexes: any, y: any, y1: any, y2: any, yDivision: any, barHeight: any, barYPosition: any, zeroW: any}} opts */
    drawRangeBarPaths({
      indexes,
      y,
      y1,
      y2,
      yDivision,
      barHeight,
      barYPosition,
      zeroW
    }) {
      const w = this.w;
      const { realIndex, j } = indexes;
      const x1 = this.preventBarOverflow(zeroW + y1 / this.invertedYRatio);
      const x2 = this.preventBarOverflow(zeroW + y2 / this.invertedYRatio);
      const range = this.getRangeValue(realIndex, j);
      const barWidth = Math.abs(x2 - x1);
      const paths = this.barHelpers.getBarpaths({
        barYPosition,
        barHeight,
        x1,
        x2,
        strokeWidth: this.strokeWidth,
        series: this.seriesRangeEnd,
        i: realIndex,
        realIndex,
        j,
        w
      });
      if (!w.axisFlags.isXNumeric) {
        y = y + yDivision;
      }
      return {
        pathTo: paths.pathTo,
        pathFrom: paths.pathFrom,
        barWidth,
        x: range.start < 0 && range.end < 0 ? x1 : x2,
        goalX: this.barHelpers.getGoalValues(
          "x",
          zeroW,
          /** @type {any} */
          null,
          realIndex,
          j,
          0
        ),
        y
      };
    }
    /**
     * @param {number} i
     * @param {number} j
     */
    getRangeValue(i, j) {
      const w = this.w;
      return {
        start: w.rangeData.seriesRangeStart[i][j],
        end: w.rangeData.seriesRangeEnd[i][j]
      };
    }
  }
  function normalize(data, area) {
    let sum = 0;
    for (let i = 0; i < data.length; i++) {
      sum += data[i];
    }
    const multiplier = area / sum;
    const result = new Array(data.length);
    for (let i = 0; i < data.length; i++) {
      result[i] = data[i] * multiplier;
    }
    return result;
  }
  function calculateRatio(rowMin, rowMax, rowSum, length) {
    const lengthSq = length * length;
    const sumSq = rowSum * rowSum;
    return Math.max(
      lengthSq * rowMax / sumSq,
      sumSq / (lengthSq * rowMin)
    );
  }
  function improvesRatio(rowLen, rowMin, rowMax, rowSum, nextNode, length) {
    if (rowLen === 0) return true;
    const currentRatio = calculateRatio(rowMin, rowMax, rowSum, length);
    const newRatio = calculateRatio(
      Math.min(rowMin, nextNode),
      Math.max(rowMax, nextNode),
      rowSum + nextNode,
      length
    );
    return currentRatio >= newRatio;
  }
  function emitCoordinates(coords, row, rowLen, rowSum, xoffset, yoffset, width, height) {
    if (width >= height) {
      const areaWidth = rowSum / height;
      let subY = yoffset;
      for (let i = 0; i < rowLen; i++) {
        const h = row[i] / areaWidth;
        coords.push([xoffset, subY, xoffset + areaWidth, subY + h]);
        subY += h;
      }
    } else {
      const areaHeight = rowSum / width;
      let subX = xoffset;
      for (let i = 0; i < rowLen; i++) {
        const w = row[i] / areaHeight;
        coords.push([subX, yoffset, subX + w, yoffset + areaHeight]);
        subX += w;
      }
    }
  }
  function squarify(data, xoffset, yoffset, width, height) {
    const coords = [];
    const n = data.length;
    if (n === 0) return coords;
    const row = new Array(n);
    let rowLen = 0;
    let rowSum = 0;
    let rowMin = Infinity;
    let rowMax = -Infinity;
    let i = 0;
    while (i < n) {
      const length = Math.min(width, height);
      const val = data[i];
      if (improvesRatio(rowLen, rowMin, rowMax, rowSum, val, length)) {
        row[rowLen] = val;
        rowLen++;
        rowSum += val;
        if (val < rowMin) rowMin = val;
        if (val > rowMax) rowMax = val;
        i++;
      } else {
        emitCoordinates(coords, row, rowLen, rowSum, xoffset, yoffset, width, height);
        if (width >= height) {
          const areaWidth = rowSum / height;
          xoffset += areaWidth;
          width -= areaWidth;
        } else {
          const areaHeight = rowSum / width;
          yoffset += areaHeight;
          height -= areaHeight;
        }
        rowLen = 0;
        rowSum = 0;
        rowMin = Infinity;
        rowMax = -Infinity;
      }
    }
    if (rowLen > 0) {
      emitCoordinates(coords, row, rowLen, rowSum, xoffset, yoffset, width, height);
    }
    return coords;
  }
  function generate(data, width, height) {
    const n = data.length;
    const sums = new Array(n);
    for (let i = 0; i < n; i++) {
      let s = 0;
      const series = data[i];
      for (let j = 0; j < series.length; j++) {
        s += series[j];
      }
      sums[i] = s;
    }
    const seriesRects = squarify(
      normalize(sums, width * height),
      0,
      0,
      width,
      height
    );
    const results = new Array(n);
    for (let i = 0; i < n; i++) {
      const rect = seriesRects[i];
      const rx = rect[0];
      const ry = rect[1];
      const rw = rect[2] - rx;
      const rh = rect[3] - ry;
      results[i] = squarify(
        normalize(data[i], rw * rh),
        rx,
        ry,
        rw,
        rh
      );
    }
    return results;
  }
  const TreemapSquared = { generate };
  class TreemapChart {
    /**
     * @param {import('../types/internal').ChartStateW} w
     * @param {import('../types/internal').ChartContext} ctx
     */
    constructor(w, ctx) {
      this.ctx = ctx;
      this.w = w;
      this.strokeWidth = this.w.config.stroke.width;
      this.helpers = new TreemapHelpers(w, ctx);
      this.dynamicAnim = this.w.config.chart.animations.dynamicAnimation;
      this.labels = [];
    }
    /**
     * @param {any[]} series
     */
    draw(series) {
      const w = this.w;
      const graphics = new Graphics(this.w, this.ctx);
      const fill = new Fill(this.w);
      const ret = graphics.group({
        class: "apexcharts-treemap"
      });
      if (w.globals.noData) return ret;
      const ser = [];
      series.forEach((s) => {
        const d = s.map((v) => {
          return Math.abs(v);
        });
        ser.push(d);
      });
      this.negRange = this.helpers.checkColorRange();
      w.config.series.forEach((s, i) => {
        s.data.forEach((l) => {
          if (!Array.isArray(this.labels[i])) this.labels[i] = [];
          this.labels[i].push(l.x);
        });
      });
      const nodes = TreemapSquared.generate(
        ser,
        w.layout.gridWidth,
        w.layout.gridHeight
      );
      nodes.forEach((node, i) => {
        var _a;
        const elSeries = graphics.group({
          class: `apexcharts-series apexcharts-treemap-series`,
          seriesName: Utils$1.escapeString(w.seriesData.seriesNames[i]),
          rel: i + 1,
          "data:realIndex": i
        });
        graphics.setupEventDelegation(elSeries, ".apexcharts-treemap-rect");
        if (w.config.chart.dropShadow.enabled) {
          const shadow = w.config.chart.dropShadow;
          const filters = new Filters(this.w);
          filters.dropShadow(ret, shadow, i);
        }
        const elDataLabelWrap = graphics.group({
          class: "apexcharts-data-labels"
        });
        const bounds = {
          xMin: Infinity,
          yMin: Infinity,
          xMax: -Infinity,
          yMax: -Infinity
        };
        node.forEach((r, j) => {
          const x1 = r[0];
          const y1 = r[1];
          const x2 = r[2];
          const y2 = r[3];
          bounds.xMin = Math.min(bounds.xMin, x1);
          bounds.yMin = Math.min(bounds.yMin, y1);
          bounds.xMax = Math.max(bounds.xMax, x2);
          bounds.yMax = Math.max(bounds.yMax, y2);
          const colorProps = this.helpers.getShadeColor(
            w.config.chart.type,
            i,
            j,
            this.negRange
          );
          const color = colorProps.color;
          const pathFill = fill.fillPath({
            color,
            seriesNumber: i,
            dataPointIndex: j
          });
          const elRect = graphics.drawRect(
            x1,
            y1,
            x2 - x1,
            y2 - y1,
            w.config.plotOptions.treemap.borderRadius,
            "#fff",
            1,
            this.strokeWidth,
            w.config.plotOptions.treemap.useFillColorAsStroke ? color : w.globals.stroke.colors[i]
          );
          elRect.attr({
            cx: x1,
            cy: y1,
            index: i,
            i,
            j,
            width: x2 - x1,
            height: y2 - y1,
            fill: pathFill
          });
          elRect.node.classList.add("apexcharts-treemap-rect");
          let fromRect = {
            x: x1 + (x2 - x1) / 2,
            y: y1 + (y2 - y1) / 2,
            width: 0,
            height: 0
          };
          const toRect = {
            x: x1,
            y: y1,
            width: x2 - x1,
            height: y2 - y1
          };
          if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
            let speed = 1;
            if (!w.globals.resized) {
              speed = w.config.chart.animations.speed;
            }
            this.animateTreemap(elRect, fromRect, toRect, speed);
          }
          if (w.globals.dataChanged) {
            let speed = 1;
            if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
              speed = this.dynamicAnim.speed;
              if (w.globals.previousPaths[i] && /** @type {Record<string,any>} */
              w.globals.previousPaths[i][j] && /** @type {Record<string,any>} */
              w.globals.previousPaths[i][j].rect) {
                fromRect = /** @type {Record<string,any>} */
                w.globals.previousPaths[i][j].rect;
              }
              this.animateTreemap(elRect, fromRect, toRect, speed);
            }
          }
          let fontSize = this.getFontSize(r);
          let formattedText = w.config.dataLabels.formatter(this.labels[i][j], {
            value: w.seriesData.series[i][j],
            seriesIndex: i,
            dataPointIndex: j,
            w
          });
          if (w.config.plotOptions.treemap.dataLabels.format === "truncate") {
            fontSize = parseInt(String(w.config.dataLabels.style.fontSize), 10);
            formattedText = this.truncateLabels(
              String(formattedText),
              fontSize,
              x1,
              y1,
              x2,
              y2
            );
          }
          let dataLabels = null;
          if (w.seriesData.series[i][j]) {
            dataLabels = this.helpers.calculateDataLabels({
              text: formattedText,
              x: (x1 + x2) / 2,
              y: (y1 + y2) / 2 + this.strokeWidth / 2 + fontSize / 3,
              i,
              j,
              colorProps,
              fontSize,
              series
            });
          }
          if (w.config.dataLabels.enabled && dataLabels) {
            this.rotateToFitLabel(
              dataLabels,
              fontSize,
              formattedText,
              x1,
              y1,
              x2,
              y2
            );
          }
          elSeries.add(elRect);
          if (dataLabels !== null) {
            elSeries.add(dataLabels);
          }
        });
        const seriesTitle = w.config.plotOptions.treemap.seriesTitle;
        if (w.config.series.length > 1 && seriesTitle && seriesTitle.show) {
          const sName = (
            /** @type {Record<string,any>} */
            w.config.series[i].name || ""
          );
          if (sName && bounds.xMin < Infinity && bounds.yMin < Infinity) {
            const {
              offsetX,
              offsetY,
              borderColor,
              borderWidth,
              borderRadius,
              style
            } = seriesTitle;
            const textColor = style.color || w.config.chart.foreColor;
            const padding = {
              left: style.padding.left,
              right: style.padding.right,
              top: style.padding.top,
              bottom: style.padding.bottom
            };
            const textSize = graphics.getTextRects(
              sName,
              style.fontSize,
              style.fontFamily
            );
            const labelRectWidth = textSize.width + padding.left + padding.right;
            const labelRectHeight = textSize.height + padding.top + padding.bottom;
            const labelX = bounds.xMin + (offsetX || 0);
            const labelY = bounds.yMin + (offsetY || 0);
            const elLabelRect = graphics.drawRect(
              labelX,
              labelY,
              labelRectWidth,
              labelRectHeight,
              borderRadius,
              style.background,
              1,
              borderWidth,
              borderColor
            );
            const elLabelText = graphics.drawText({
              x: labelX + padding.left,
              y: labelY + padding.top + ((_a = textSize == null ? void 0 : textSize.height) != null ? _a : 0) * 0.75,
              text: sName,
              fontSize: style.fontSize,
              fontFamily: style.fontFamily,
              fontWeight: style.fontWeight,
              foreColor: textColor,
              cssClass: style.cssClass || ""
            });
            elSeries.add(elLabelRect);
            elSeries.add(elLabelText);
          }
        }
        elSeries.add(elDataLabelWrap);
        ret.add(elSeries);
      });
      return ret;
    }
    // This calculates a font-size based upon
    // average label length and the size of the box
    /**
     * @param {number[]} coordinates
     */
    getFontSize(coordinates) {
      const w = this.w;
      function totalLabelLength(arr) {
        let i, total = 0;
        if (Array.isArray(arr[0])) {
          for (i = 0; i < arr.length; i++) {
            total += totalLabelLength(arr[i]);
          }
        } else {
          for (i = 0; i < arr.length; i++) {
            total += arr[i].length;
          }
        }
        return total;
      }
      function countLabels(arr) {
        let i, total = 0;
        if (Array.isArray(arr[0])) {
          for (i = 0; i < arr.length; i++) {
            total += countLabels(arr[i]);
          }
        } else {
          for (i = 0; i < arr.length; i++) {
            total += 1;
          }
        }
        return total;
      }
      const averagelabelsize = totalLabelLength(this.labels) / countLabels(this.labels);
      function fontSize(width, height) {
        const area = width * height;
        const arearoot = Math.pow(area, 0.5);
        return Math.min(
          arearoot / averagelabelsize,
          parseInt(w.config.dataLabels.style.fontSize, 10)
        );
      }
      return fontSize(
        coordinates[2] - coordinates[0],
        coordinates[3] - coordinates[1]
      );
    }
    /**
     * @param {any} elText
     * @param {string | number} fontSize
     * @param {string} text
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     */
    rotateToFitLabel(elText, fontSize, text, x1, y1, x2, y2) {
      const graphics = new Graphics(this.w);
      const textRect = graphics.getTextRects(text, String(fontSize));
      if (textRect.width + this.w.config.stroke.width + 5 > x2 - x1 && textRect.width <= y2 - y1) {
        const labelRotatingCenter = graphics.rotateAroundCenter(elText.node);
        elText.node.setAttribute(
          "transform",
          `rotate(-90 ${labelRotatingCenter.x} ${labelRotatingCenter.y}) translate(${textRect.height / 3})`
        );
      }
    }
    // This is an alternative label formatting method that uses a
    // consistent font size, and trims the edge of long labels
    /**
     * @param {string} text
     * @param {number} fontSize
     * @param {number} x1
     * @param {number} y1
     * @param {number} x2
     * @param {number} y2
     */
    truncateLabels(text, fontSize, x1, y1, x2, y2) {
      const graphics = new Graphics(this.w);
      const textRect = graphics.getTextRects(text, String(fontSize));
      const labelMaxWidth = textRect.width + this.w.config.stroke.width + 5 > x2 - x1 && y2 - y1 > x2 - x1 ? y2 - y1 : x2 - x1;
      const truncatedText = graphics.getTextBasedOnMaxWidth({
        text,
        maxWidth: labelMaxWidth,
        fontSize
      });
      if (text.length !== truncatedText.length && labelMaxWidth / fontSize < 5) {
        return "";
      } else {
        return truncatedText;
      }
    }
    /**
     * @param {any} el
     * @param {Record<string, any>} fromRect
     * @param {Record<string, any>} toRect
     * @param {number} speed
     */
    animateTreemap(el, fromRect, toRect, speed) {
      const animations = new Animations(this.w);
      animations.animateRect(el, fromRect, toRect, speed, () => {
        animations.animationCompleted(el);
      });
    }
  }
  ApexCharts.use({
    line: Line,
    area: Line,
    scatter: Line,
    bubble: Line,
    rangeArea: Line,
    bar: Bar,
    column: Bar,
    barStacked: BarStacked,
    rangeBar: RangeBar,
    candlestick: BoxCandleStick,
    boxPlot: BoxCandleStick,
    pie: Pie,
    donut: Pie,
    polarArea: Pie,
    radialBar: Radial,
    radar: Radar,
    heatmap: HeatMap,
    treemap: TreemapChart
  });
  return ApexCharts;
}));
