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.4
 * (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 Utils {
  /**
   * @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(Utils.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 && Utils.is("ShadowRoot", rootNode);
  }
  /**
   * gets the shadow root host element
   * @param {any} el
   */
  static getShadowRootHost(el) {
    if (!Utils.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];
    }
    const rootNode = el.getRootNode && el.getRootNode();
    const inShadowDOM = rootNode && rootNode !== document;
    if (inShadowDOM && rootNode.host) {
      const hostRect = rootNode.host.getBoundingClientRect();
      return [hostRect.width, hostRect.height];
    }
    let computedStyle;
    try {
      computedStyle = getComputedStyle(el, null);
    } catch (e) {
      return [el.clientWidth || 0, el.clientHeight || 0];
    }
    let elementHeight = el.clientHeight;
    let elementWidth = el.clientWidth;
    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 (Utils.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 (!Utils.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) {
      if (x < -20 - /** @type {any} */
      correctedLabels.textRects.width || x > w.layout.gridWidth + /** @type {any} */
      correctedLabels.textRects.width + 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;
  }
  // 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) {
        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);
        newOptions = Utils$1.extend(w.config, newOptions);
        this.overrideResponsiveOptions(newOptions);
      } 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);
          }
        }
      }
    };
    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);
    }
  }
}
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(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)
   * @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.comboCharts) 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 Utils2 {
  /**
   * @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 Utils2(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 Utils2(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 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 self = 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,
          self.onSeriesHover.bind(self, 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
}

/* 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();
  }
}
export {
  Animations as __apex_Animations,
  Base as __apex_Base,
  BrowserAPIs as __apex_BrowserAPIs_BrowserAPIs,
  getChartClass as __apex_ChartFactory_getChartClass,
  register as __apex_ChartFactory_register,
  Config as __apex_Config,
  LINE_HEIGHT_RATIO as __apex_Constants_LINE_HEIGHT_RATIO,
  NICE_SCALE_ALLOWED_MAG_MSD as __apex_Constants_NICE_SCALE_ALLOWED_MAG_MSD,
  NICE_SCALE_DEFAULT_TICKS as __apex_Constants_NICE_SCALE_DEFAULT_TICKS,
  Core as __apex_Core,
  CoreUtils as __apex_CoreUtils,
  Crosshairs as __apex_Crosshairs,
  SSRClassList as __apex_DOMShim_SSRClassList,
  SSRDOMShim as __apex_DOMShim_SSRDOMShim,
  SSRElement as __apex_DOMShim_SSRElement,
  Data as __apex_Data,
  DataLabels as __apex_DataLabels,
  DateTime as __apex_DateTime,
  Defaults as __apex_Defaults,
  Environment as __apex_Environment_Environment,
  Events as __apex_Events,
  Fill as __apex_Fill,
  Filters as __apex_Filters,
  Formatters as __apex_Formatters,
  Globals as __apex_Globals,
  Graphics as __apex_Graphics,
  Markers as __apex_Markers,
  Options as __apex_Options,
  arrayToPath as __apex_PathMorphing_arrayToPath,
  morphPaths as __apex_PathMorphing_morphPaths,
  parsePath as __apex_PathMorphing_parsePath,
  pathBbox as __apex_PathMorphing_pathBbox,
  PerformanceCache as __apex_PerformanceCache,
  Range as __apex_Range,
  addResizeListener as __apex_Resize_addResizeListener,
  removeResizeListener as __apex_Resize_removeResizeListener,
  Responsive as __apex_Responsive,
  SVGAnimationRunner as __apex_SVGAnimation_SVGAnimationRunner,
  installAnimationMethods as __apex_SVGAnimation_installAnimationMethods,
  SVGContainer as __apex_SVGContainer,
  installDraggable as __apex_SVGDraggable_installDraggable,
  SVGElement as __apex_SVGElement,
  FilterBuilder as __apex_SVGFilter_FilterBuilder,
  SVGFilter as __apex_SVGFilter_SVGFilter,
  installFilterMethods as __apex_SVGFilter_installFilterMethods,
  SVGGradient as __apex_SVGGradient_SVGGradient,
  SVGPattern as __apex_SVGPattern_SVGPattern,
  installSelectable as __apex_SVGSelectable_installSelectable,
  Scales as __apex_Scales,
  Series as __apex_Series,
  Theme as __apex_Theme,
  getThemePalettes as __apex_ThemePalettes_getThemePalettes,
  TimeScale as __apex_TimeScale,
  TitleSubtitle as __apex_TitleSubtitle,
  Utils$1 as __apex_Utils,
  Axes as __apex_axes_Axes,
  AxesUtils as __apex_axes_AxesUtils,
  Grid as __apex_axes_Grid,
  XAxis as __apex_axes_XAxis,
  YAxis as __apex_axes_YAxis,
  Scatter as __apex_charts_Scatter,
  Dimensions as __apex_dimensions_Dimensions,
  DimGrid as __apex_dimensions_Grid,
  Helpers as __apex_dimensions_Helpers,
  DimXAxis as __apex_dimensions_XAxis,
  DimYAxis as __apex_dimensions_YAxis,
  Destroy as __apex_helpers_Destroy,
  InitCtxVariables as __apex_helpers_InitCtxVariables,
  Localization as __apex_helpers_Localization,
  UpdateHelpers as __apex_helpers_UpdateHelpers,
  Box as __apex_index_Box,
  SVG as __apex_index_SVG,
  Box as __apex_math_Box,
  Matrix as __apex_math_Matrix,
  Point as __apex_math_Point,
  SVGNS as __apex_math_SVGNS,
  AxesTooltip as __apex_tooltip_AxesTooltip,
  Intersect as __apex_tooltip_Intersect,
  Labels as __apex_tooltip_Labels,
  Marker as __apex_tooltip_Marker,
  Position as __apex_tooltip_Position,
  Tooltip as __apex_tooltip_Tooltip,
  Utils2 as __apex_tooltip_Utils,
  ApexCharts as default
};
