{"version":3,"sources":["../src/index.ts","../src/constants/index.ts","../src/services/coords.ts","../src/services/settings.ts","../src/services/draw.ts","../src/services/overrides.ts","../src/services/defaults.ts","../src/services/plot.ts"],"sourcesContent":["import { plot } from './services/plot';\n\nexport * from './types';\nexport * from './constants';\n\nexport default plot;\nexport { plot };\n","/**\n * Symbols for drawing the axes on the graph.\n */\nexport const AXIS = {\n  n: '▲', // Symbol for the top end of the Y-axis\n  ns: '│', // Vertical line for the Y-axis\n  y: '┤', // Right tick mark on the Y-axis\n  nse: '└', // Bottom corner for the Y-axis meeting the X-axis\n  x: '┬', // Top tick mark on the X-axis\n  we: '─', // Horizontal line for the X-axis\n  e: '▶', // Arrow symbol for the end of the X-axis\n  intersectionXY: '┼', // Intersection of the X and Y axes\n  intersectionX: '┴', // Bottom tick mark on the X-axis\n  intersectionY: '├', // Left tick mark on the Y-axis\n};\n\n/**\n * Symbols for rendering chart elements, including lines and areas.\n */\nexport const CHART = {\n  we: '━', // Bold horizontal line in the chart\n  wns: '┓', // Top-right corner for vertical-to-horizontal connection\n  ns: '┃', // Bold vertical line in the chart\n  nse: '┗', // Bottom-left corner for vertical-to-horizontal connection\n  wsn: '┛', // Bottom-right corner for vertical-to-horizontal connection\n  sne: '┏', // Top-left corner for vertical-to-horizontal connection\n  area: '█', // Filled area symbol for chart representation\n};\n\n/**\n * Symbol representing an empty space on the graph.\n */\nexport const EMPTY = ' ';\n\n/**\n * Symbols for drawing thresholds on the graph.\n */\nexport const THRESHOLDS = {\n  x: '━', // Symbol for horizontal threshold line\n  y: '┃', // Symbol for vertical threshold line\n};\n\n/**\n * Symbol for the point of the graph.\n */\nexport const POINT = '●';\n\n/**\n * Layout and formatting constants\n */\nexport const LAYOUT = {\n  MIN_PLOT_HEIGHT: 3,\n  DEFAULT_DECIMAL_PLACES: 3,\n  K_FORMAT_THRESHOLD: 1000,\n  DEFAULT_PADDING: 2,\n  DEFAULT_Y_SHIFT_OFFSET: 1,\n} as const;\n","import { SingleLine, Point, MultiLine } from '../types/index';\nimport { EMPTY } from '../constants/index';\n\n/**\n * Normalizes the input value to an array of strings.\n * @param value - The value to normalize, which can be a string, an array of strings, or undefined.\n * @returns {string[]} - An array of strings. If the input is undefined, an empty array is returned.\n */\nexport const normalize = (value?: string[] | string): string[] =>\n  value === undefined ? [] : Array.isArray(value) ? value : [value];\n\n/**\n * Pads or trims an array of labels to a specified target length.\n * @param {string[]} labels - The array of labels to pad or trim.\n * @param {number} targetLength - The target length for the array.\n * @returns {string[]} - The padded or trimmed array of labels.\n */\nexport const padOrTrim = (labels: string[], targetLength: number): string[] => {\n  if (labels.length > targetLength) return labels.slice(0, targetLength);\n  if (labels.length < targetLength)\n    return [...labels, ...Array(targetLength - labels.length).fill('')];\n  return labels;\n};\n\n/**\n * Creates an array filled with a specified string.\n * @param {number} size - The size of the array.\n * @param {string} empty - The value to fill the array with (default: EMPTY).\n * @returns {string[]} - An array filled with the specified string.\n */\nexport const toEmpty = (size: number, empty: string = EMPTY): string[] =>\n  Array(size >= 0 ? size : 0).fill(empty);\n\n/**\n * Converts a number or string to an array of its characters.\n * @param {number | string} input - The input to convert.\n * @returns {string[]} - An array of characters.\n */\nexport const toArray = (input: number | string): string[] => {\n  return input.toString().split('');\n};\n\n/**\n * Removes duplicate values from an array.\n * @param {number[]} array - The array of numbers.\n * @returns {number[]} - An array containing only unique values.\n */\nexport const toUnique = (array: number[]): number[] => [...new Set(array)];\n\n/**\n * Calculates the distance between two integer coordinates by rounding to the nearest integers.\n * @param {number} x - The x-coordinate of the first point.\n * @param {number} y - The y-coordinate of the second point.\n * @returns {number} - The absolute distance between the rounded points.\n */\nexport const distance = (x: number, y: number): number => Math.abs(Math.round(x) - Math.round(y));\n\n/**\n * Flattens a multi-line array of points into a single array of points.\n * @param {MultiLine} array - The multi-line array.\n * @returns {Point[]} - A flat array of points.\n */\nexport const toFlat = (array: MultiLine): Point[] => ([] as Point[]).concat(...array);\n\n/**\n * Converts a multi-line array into arrays of unique x and y values.\n * @param {MultiLine} array - The multi-line array.\n * @returns {[number[], number[]]} - Arrays of unique x and y values.\n */\nexport const toArrays = (array: MultiLine): [number[], number[]] => {\n  const rangeX: number[] = [];\n  const rangeY: number[] = [];\n\n  const flatArray = toFlat(array);\n  for (let i = 0; i < flatArray.length; i++) {\n    const [x, y] = flatArray[i];\n    rangeX.push(x);\n    rangeY.push(y);\n  }\n\n  return [toUnique(rangeX), toUnique(rangeY)];\n};\n\n/**\n * Sorts a single-line array of points in ascending order based on the x-coordinate.\n * @param {SingleLine} array - The single-line array to sort.\n * @returns {SingleLine} - The sorted array.\n */\nexport const toSorted = (array: SingleLine): SingleLine =>\n  [...array].sort(([x1], [x2]) => {\n    if (x1 < x2) return -1;\n    if (x1 > x2) return 1;\n    return 0;\n  });\n\n/**\n * Converts a number or undefined value to a point represented as an array.\n * @param {number} [x] - The x-coordinate (default: 0).\n * @param {number} [y] - The y-coordinate (default: 0).\n * @returns {Point} - The point represented as an array [x, y].\n */\nexport const toPoint = (x?: number, y?: number): Point => [x ?? 0, y ?? 0];\n\n/**\n * Returns a function that converts a coordinate (x, y) to scaled plot coordinates.\n * @param {number} plotWidth - The width of the plot.\n * @param {number} plotHeight - The height of the plot.\n * @returns {function} - A function that takes (x, y) and returns scaled plot coordinates [scaledX, scaledY].\n */\nexport const toPlot =\n  (plotWidth: number, plotHeight: number) =>\n  (x: number, y: number): Point => [\n    Math.round((x / plotWidth) * plotWidth),\n    plotHeight - 1 - Math.round((y / plotHeight) * plotHeight),\n  ];\n\n/**\n * Returns a function that converts scaled plot coordinates (scaledX, scaledY) back to the original coordinates.\n * @param {number} plotWidth - The width of the plot.\n * @param {number} plotHeight - The height of the plot.\n * @returns {function} - A function that takes (scaledX, scaledY) and returns original coordinates [x, y].\n */\nexport const fromPlot =\n  (plotWidth: number, plotHeight: number) =>\n  (scaledX: number, scaledY: number): [number, number] => {\n    const x = (scaledX / plotWidth) * plotWidth;\n    const y = plotHeight - 1 - (scaledY / plotHeight) * (plotHeight - 1);\n    return [Math.round(x), Math.round(y)];\n  };\n\n/**\n * Finds the maximum or minimum value in a single-line array of points.\n * @param {SingleLine} arr - The single-line array to search for extrema.\n * @param {'max' | 'min'} type - 'max' to find the maximum value, 'min' for minimum (default is 'max').\n * @param {number} position - The position of the value within each point (default is 1).\n * @returns {number} - The maximum or minimum value found in the array.\n */\nexport const getExtrema = (arr: SingleLine, type: 'max' | 'min' = 'max', position = 1) =>\n  arr.reduce(\n    (previous, curr) => Math[type](previous, curr[position]),\n    type === 'max' ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,\n  );\n\n/**\n * Finds the maximum value in an array of numbers.\n * @param {number[]} arr - The array of numbers.\n * @returns {number} - The maximum value in the array.\n */\nexport const getMax = (arr: number[]) =>\n  arr.reduce((previous, curr) => Math.max(previous, curr), Number.NEGATIVE_INFINITY);\n\n/**\n * Finds the minimum value in an array of numbers.\n * @param {number[]} arr - The array of numbers.\n * @returns {number} - The minimum value in the array.\n */\nexport const getMin = (arr: number[]) =>\n  arr.reduce((previous, curr) => Math.min(previous, curr), Number.POSITIVE_INFINITY);\n\n/**\n * Returns a function that scales coordinates to fit within a specified range.\n * @param {[number, number]} domain - The original value range (min and max).\n * @param {[number, number]} range - The range to scale the values into.\n * @returns {(value: number) => number} - A function for scaling coordinates.\n */\nexport const scaler = ([domainMin, domainMax]: number[], [rangeMin, rangeMax]: number[]) => {\n  const domainLength = Math.sqrt(Math.abs((domainMax - domainMin) ** 2)) || 1;\n  const rangeLength = Math.sqrt((rangeMax - rangeMin) ** 2);\n\n  return (domainValue: number) =>\n    rangeMin + (rangeLength * (domainValue - domainMin)) / domainLength;\n};\n\n/**\n * Scales a point's coordinates to fit within the specified plot dimensions.\n * @param {Point} point - The point to scale.\n * @param {number} plotWidth - The width of the plot.\n * @param {number} plotHeight - The height of the plot.\n * @param {number[]} rangeX - The range of x values.\n * @param {number[]} rangeY - The range of y values.\n * @returns {Point} - The scaled point.\n */\nexport const toCoordinates = (\n  point: Point,\n  plotWidth: number,\n  plotHeight: number,\n  rangeX: number[],\n  rangeY: number[],\n): Point => {\n  const getXCoord = scaler(rangeX, [0, plotWidth - 1]);\n  const getYCoord = scaler(rangeY, [0, plotHeight - 1]);\n\n  return [Math.round(getXCoord(point[0])), Math.round(getYCoord(point[1]))];\n};\n\n/**\n * Scales a list of coordinates to fit within the specified plot dimensions.\n * @param {SingleLine} coordinates - The list of coordinates to scale.\n * @param {number} plotWidth - The width of the plot.\n * @param {number} plotHeight - The height of the plot.\n * @param {number[]} [rangeX] - The range of x values (defaults to min and max from coordinates).\n * @param {number[]} [rangeY] - The range of y values (defaults to min and max from coordinates).\n * @returns {SingleLine} - The scaled list of coordinates.\n */\nexport const getPlotCoords = (\n  coordinates: SingleLine,\n  plotWidth: number,\n  plotHeight: number,\n  rangeX?: number[],\n  rangeY?: number[],\n): SingleLine => {\n  const getXCoord = scaler(\n    rangeX || [getExtrema(coordinates, 'min', 0), getExtrema(coordinates, 'max', 0)],\n    [0, plotWidth - 1],\n  );\n  const getYCoord = scaler(rangeY || [getExtrema(coordinates, 'min'), getExtrema(coordinates)], [\n    0,\n    plotHeight - 1,\n  ]);\n\n  return coordinates.map(([x, y]) => [getXCoord(x), getYCoord(y)]);\n};\n\n/**\n * Computes the axis center point based on specified plot dimensions and ranges.\n * @param {MaybePoint} axisCenter - The center point for the axis.\n * @param {number} plotWidth - The width of the plot.\n * @param {number} plotHeight - The height of the plot.\n * @param {number[]} rangeX - The range of x values.\n * @param {number[]} rangeY - The range of y values.\n * @param {number[]} initialValue - The initial axis values.\n * @returns {Point} - The center point of the axis.\n */\nexport const getAxisCenter = (\n  axisCenter: Point | [number | undefined, number | undefined] | undefined,\n  plotWidth: number,\n  plotHeight: number,\n  rangeX: number[],\n  rangeY: number[],\n  initialValue: [number, number],\n): { x: number; y: number } => {\n  const axis = { x: initialValue[0], y: initialValue[1] };\n\n  if (axisCenter) {\n    const [x, y] = axisCenter;\n\n    if (typeof x === 'number') {\n      const xScaler = scaler(rangeX, [0, plotWidth - 1]);\n      axis.x = Math.round(xScaler(x));\n    }\n\n    if (typeof y === 'number') {\n      const yScaler = scaler(rangeY, [0, plotHeight - 1]);\n      axis.y = plotHeight - Math.round(yScaler(y));\n    }\n  }\n\n  return axis;\n};\n","import { CHART } from '../constants';\nimport { LAYOUT } from '../constants';\nimport { Color, ColorGetter, Formatter, MultiLine } from '../types';\n\nconst colorMap: Record<Color, string> = {\n  ansiBlack: '\\u001b[30m',\n  ansiRed: '\\u001b[31m',\n  ansiGreen: '\\u001b[32m',\n  ansiYellow: '\\u001b[33m',\n  ansiBlue: '\\u001b[34m',\n  ansiMagenta: '\\u001b[35m',\n  ansiCyan: '\\u001b[36m',\n  ansiWhite: '\\u001b[37m',\n};\n\n/**\n * Maps a color name to its corresponding ANSI color code.\n * @param {Color} color - The color to map.\n * @returns {string} - The ANSI escape code for the specified color.\n */\nexport const getAnsiColor = (color: Color): string => colorMap[color] || colorMap.ansiWhite;\n\n/**\n * Configures and applies colors to chart symbols based on the specified color or series.\n * @param {Color | Color[] | ColorGetter | undefined} color - The color setting for the series.\n * @param {number} series - The index of the series.\n * @param {Partial<typeof CHART> | undefined} chartSymbols - Custom symbols for the chart, if any.\n * @param {MultiLine} input - The dataset used in the chart.\n * @param {boolean} [fillArea] - If true, fills the area under the plot with the chart's fill symbol.\n * @returns {object} - An object with chart symbols applied in the specified color(s).\n */\nexport const getChartSymbols = (\n  color: Color | Color[] | undefined | ColorGetter,\n  series: number,\n  chartSymbols: Partial<typeof CHART> | void,\n  input: MultiLine,\n  fillArea?: boolean,\n) => {\n  const chart = { ...CHART, ...chartSymbols };\n\n  // Apply the fill area symbol to all chart symbols if fillArea is true\n  if (fillArea) {\n    Object.entries(chart).forEach(([key]) => {\n      chart[key as keyof typeof chart] = chart.area;\n    });\n  }\n\n  // Determine the color for the current series and apply it to all chart symbols\n  if (color) {\n    let currentColor: Color = 'ansiWhite';\n\n    if (Array.isArray(color)) {\n      currentColor = color[series];\n    } else if (typeof color === 'function') {\n      currentColor = color(series, input);\n    } else {\n      currentColor = color;\n    }\n\n    Object.entries(chart).forEach(([key, symbol]) => {\n      chart[key as keyof typeof chart] = `${getAnsiColor(currentColor)}${symbol}\\u001b[0m`;\n    });\n  }\n\n  return chart;\n};\n\n/**\n * Formats a number for display, converting values >= 1000 to a \"k\" notation.\n * @param {number} value - The value to format.\n * @returns {string | number} - The formatted value as a string with \"k\" for thousands or as a rounded number.\n */\nexport const defaultFormatter: Formatter = (value) => {\n  if (Math.abs(value) >= LAYOUT.K_FORMAT_THRESHOLD) {\n    const rounded = value / LAYOUT.K_FORMAT_THRESHOLD;\n    return rounded % 1 === 0 ? `${rounded}k` : `${rounded.toFixed(LAYOUT.DEFAULT_DECIMAL_PLACES)}k`;\n  }\n  return Number(value.toFixed(LAYOUT.DEFAULT_DECIMAL_PLACES));\n};\n","import { AXIS, CHART, POINT } from '../constants';\nimport {\n  CustomSymbol,\n  Formatter,\n  Graph,\n  GraphMode,\n  LineFormatterArgs,\n  MaybePoint,\n  MultiLine,\n  Point,\n  Symbols,\n} from '../types';\nimport { distance, getPlotCoords, toArray, toEmpty, toPlot, toPoint } from './coords';\n\n/**\n * Places a symbol at a specific position on the graph.\n * @param {Object} params - Object containing parameters.\n * @param {Graph} params.graph - The graph matrix where the symbol will be drawn.\n * @param {number} params.scaledX - X-coordinate on the graph (scaled).\n * @param {number} params.scaledY - Y-coordinate on the graph (scaled).\n * @param {string} params.symbol - Symbol to draw on the graph.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const drawPosition = ({\n  graph,\n  scaledX,\n  scaledY,\n  symbol,\n  debugMode = false,\n}: {\n  graph: Graph;\n  scaledX: number;\n  scaledY: number;\n  symbol: string;\n  debugMode?: boolean;\n}) => {\n  if (debugMode) {\n    // Handle out-of-bounds for Y\n    if (scaledY >= graph.length || scaledY < 0) {\n      console.log(`Drawing at [${scaledX}, ${scaledY}]`, 'Error: out of bounds Y', {\n        graph,\n        scaledX,\n        scaledY,\n      });\n      return;\n    }\n    // Handle out-of-bounds for X\n    if (scaledX >= graph[scaledY].length || scaledX < 0) {\n      console.log(`Drawing at [${scaledX}, ${scaledY}]`, 'Error: out of bounds X', {\n        graph,\n        scaledX,\n        scaledY,\n      });\n      return;\n    }\n  }\n\n  // Draw the symbol if within bounds\n  try {\n    graph[scaledY][scaledX] = symbol;\n  } catch (error) {\n    // Fail silently without logging if debugMode is false\n  }\n};\n\n/**\n * Draws a tick mark at the end of the X-axis, handling bounds and axis center.\n * @param {Object} params - Configuration options for drawing the X-axis tick.\n * @param {boolean} params.hasPlaceToRender - True if there is enough space to render the tick.\n * @param {Point | [number | undefined, number | undefined]} [params.axisCenter] - Coordinates of the axis center (optional).\n * @param {number} params.yPos - The Y-position of the tick mark.\n * @param {Graph} params.graph - The graph matrix being drawn on.\n * @param {number} params.yShift - The Y-axis shift offset.\n * @param {number} params.i - The current iteration index.\n * @param {number} params.scaledX - The scaled X-position for rendering the tick.\n * @param {number} params.shift - X-axis offset to adjust tick positioning.\n * @param {boolean} [params.hideXAxisTicks] - If true, hides the X-axis ticks.\n * @param {number} params.signShift - Additional shift based on the sign of the axis.\n * @param {Symbols['axis']} params.axisSymbols - Symbols used for the axis rendering.\n * @param {string[]} params.pointXShift - Array of characters representing the X-axis labels.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const drawXAxisEnd = ({\n  hasPlaceToRender,\n  yPos,\n  graph,\n  yShift,\n  i,\n  scaledX,\n  hideXAxisTicks,\n  pointXShift,\n  debugMode,\n  axisCenter,\n}: {\n  hasPlaceToRender: boolean;\n  yPos: number;\n  graph: Graph;\n  hideXAxisTicks?: boolean;\n  yShift: number;\n  i: number;\n  scaledX: number;\n  axisCenter?: MaybePoint;\n  pointXShift: string[];\n  debugMode?: boolean;\n}) => {\n  if (hideXAxisTicks) {\n    return;\n  }\n\n  // Adjusts Y position based on render space and axis center presence\n  const yShiftWhenOccupied = hasPlaceToRender ? -1 : 0;\n  const yShiftWhenHasAxisCenter = 0;\n\n  let graphY = yPos + yShiftWhenOccupied + yShiftWhenHasAxisCenter;\n\n  // Ensure graphY stays within valid bounds\n  if (graphY < 0) graphY = 0;\n  else if (graphY >= graph.length) graphY = graph.length - 1;\n\n  // Adjust X position for rendering the tick\n  let graphX = scaledX + yShift - i + (axisCenter ? 1 : 2);\n  if (graphX < 0) graphX = 0;\n  else if (graphX >= graph[graphY].length) graphX = graph[graphY].length - 1;\n\n  // Draw the tick label\n  drawPosition({\n    debugMode,\n    graph,\n    scaledX: graphX,\n    scaledY: graphY,\n    symbol: pointXShift[pointXShift.length - 1 - i],\n  });\n};\n\nexport const drawXAxisTick = ({\n  graph,\n  xPosition,\n  hideXAxisTicks,\n  axisSymbols,\n  debugMode,\n  axis,\n}: {\n  axis: { x: number; y: number };\n  graph: Graph;\n  hideXAxisTicks?: boolean;\n  xPosition: number;\n  axisSymbols: Symbols['axis'];\n  debugMode?: boolean;\n}) => {\n  if (hideXAxisTicks) {\n    return;\n  }\n\n  if (\n    graph[axis.y][xPosition] === axisSymbols?.ns ||\n    graph[axis.y][xPosition] === axisSymbols?.we\n  ) {\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: xPosition,\n      scaledY: axis.y,\n      symbol: axisSymbols?.x || AXIS.x,\n    });\n  }\n};\n\n/**\n * Draws tick marks for the Y-axis based on axis configurations and scales.\n * @param {Object} params - Configuration options for drawing the Y-axis ticks.\n * @param {Graph} params.graph - The graph matrix.\n * @param {number} params.scaledY - Scaled Y-coordinate.\n * @param {number} params.yShift - Shift applied to the Y-axis.\n * @param {Object} params.axis - Object defining the axis position.\n * @param {number} params.pointY - The actual Y-coordinate of the point.\n * @param {Formatter} params.transformLabel - Function to format the label for the Y-axis.\n * @param {Symbols['axis']} params.axisSymbols - Symbols used for drawing the axis.\n * @param {number[]} params.expansionX - Array of X-axis expansion factors.\n * @param {number[]} params.expansionY - Array of Y-axis expansion factors.\n * @param {number} params.plotHeight - The height of the plot.\n * @param {boolean} [params.showTickLabel] - If true, displays tick labels for all points.\n * @param {number} params.axis.x - X-position of the Y-axis on the graph.\n * @param {number} params.axis.y - Y-position of the X-axis on the graph.\n * @param {boolean} [params.hideYAxisTicks] - If true, hides Y-axis ticks.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const drawYAxisEnd = ({\n  graph,\n  scaledY,\n  yShift,\n  axis,\n  pointY,\n  transformLabel,\n  axisSymbols,\n  expansionX,\n  expansionY,\n  plotHeight,\n  showTickLabel,\n  hideYAxisTicks,\n  debugMode,\n}: {\n  graph: Graph;\n  scaledY: number;\n  yShift: number;\n  plotHeight: number;\n  axis: { x: number; y: number };\n  pointY: number;\n  transformLabel: Formatter;\n  axisSymbols: Symbols['axis'];\n  expansionX: number[];\n  expansionY: number[];\n  hideYAxisTicks?: boolean;\n  showTickLabel?: boolean;\n  debugMode?: boolean;\n}) => {\n  if (showTickLabel) {\n    const yMax = Math.max(...expansionY);\n    const yMin = Math.min(...expansionY);\n    const numTicks = plotHeight;\n    const yStep = (yMax - yMin) / numTicks;\n\n    // Draw ticks for each label\n    for (let i = 0; i <= numTicks; i++) {\n      const yValue = Math.round(yMax - i * yStep); // Ensure whole numbers\n      const scaledYPos = ((yMax - yValue) / (yMax - yMin)) * (plotHeight - 1);\n      const graphYPos = Math.floor(scaledYPos) + 1;\n\n      // Ensure the Y position is within bounds\n      if (graphYPos >= 0 && graphYPos < graph.length) {\n        const pointYShift = toArray(\n          transformLabel(yValue, { axis: 'y', xRange: expansionX, yRange: expansionY }),\n        );\n        for (let j = 0; j < pointYShift.length; j++) {\n          const colIndex = axis.x + yShift - j;\n          if (colIndex >= 0 && colIndex < graph[graphYPos].length) {\n            drawPosition({\n              debugMode,\n              graph,\n              scaledX: colIndex,\n              scaledY: graphYPos,\n              symbol: pointYShift[pointYShift.length - 1 - j],\n            });\n          }\n        }\n\n        const tickMarkIndex = axis.x + yShift + 1;\n        if (tickMarkIndex >= 0 && tickMarkIndex < graph[graphYPos].length) {\n          if (\n            graph[graphYPos][tickMarkIndex] === axisSymbols?.ns ||\n            graph[graphYPos][tickMarkIndex] === axisSymbols?.we\n          ) {\n            drawPosition({\n              debugMode,\n              graph,\n              scaledX: tickMarkIndex,\n              scaledY: graphYPos,\n              symbol: axisSymbols?.y || AXIS.y,\n            });\n          }\n        }\n      }\n    }\n    return;\n  }\n\n  if (hideYAxisTicks) {\n    return;\n  }\n\n  // make sure that values are within bounds\n  const row = scaledY + 1;\n  const col = axis.x + yShift + 1;\n\n  // Render ticks for specific data values\n  if (\n    row >= 0 &&\n    row < graph.length &&\n    col >= 0 &&\n    graph[row] &&\n    col < graph[row].length &&\n    graph[row][col] !== axisSymbols?.y\n  ) {\n    const pointYShift = toArray(\n      transformLabel(pointY, { axis: 'y', xRange: expansionX, yRange: expansionY }),\n    );\n    for (let i = 0; i < pointYShift.length; i++) {\n      drawPosition({\n        debugMode,\n        graph,\n        scaledX: axis.x + yShift - i,\n        scaledY: scaledY + 1,\n        symbol: pointYShift[pointYShift.length - 1 - i],\n      });\n    }\n    if (\n      graph[scaledY + 1][axis.x + yShift + 1] === axisSymbols?.ns ||\n      graph[scaledY + 1][axis.x + yShift + 1] === axisSymbols?.we\n    ) {\n      drawPosition({\n        debugMode,\n        graph,\n        scaledX: axis.x + yShift + 1,\n        scaledY: scaledY + 1,\n        symbol: axisSymbols?.y || AXIS.y,\n      });\n    }\n  }\n};\n\n/**\n * Draws both X and Y axes on the graph according to visibility and center configurations.\n * @param {Object} params - Configuration options for drawing axes.\n * @param {Graph} params.graph - The graph matrix.\n * @param {boolean} [params.hideXAxis] - If true, hides the X-axis.\n * @param {boolean} [params.hideYAxis] - If true, hides the Y-axis.\n * @param {MaybePoint} [params.axisCenter] - Optional axis center coordinates.\n * @param {Symbols['axis']} params.axisSymbols - Symbols used for axis rendering.\n * @param {Object} params.axis - Object defining the axis position (x and y coordinates).\n * @param {number} params.axis.x - X-position of the Y-axis on the graph.\n * @param {number} params.axis.y - Y-position of the X-axis on the graph.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const drawAxis = ({\n  graph,\n  hideXAxis,\n  hideYAxis,\n  axisCenter,\n  axisSymbols,\n  axis,\n  debugMode,\n}: {\n  graph: Graph;\n  axis: { x: number; y: number };\n  hideXAxis?: boolean;\n  axisCenter?: MaybePoint;\n  hideYAxis?: boolean;\n  axisSymbols: Symbols['axis'];\n  debugMode?: boolean;\n}) => {\n  for (let index = 0; index < graph.length; index++) {\n    const line = graph[index];\n    for (let curr = 0; curr < line.length; curr++) {\n      let lineChar = '';\n\n      if (curr === axis.x && !hideYAxis) {\n        if (index === 0) {\n          lineChar = axisSymbols?.n || AXIS.n;\n        } else if (index === graph.length - 1 && !axisCenter && !(hideYAxis || hideXAxis)) {\n          lineChar = axisSymbols?.nse || AXIS.nse;\n        } else {\n          lineChar = axisSymbols?.ns || AXIS.ns;\n        }\n      } else if (index === axis.y && !hideXAxis) {\n        if (curr === line.length - 1) {\n          lineChar = axisSymbols?.e || AXIS.e;\n        } else {\n          lineChar = axisSymbols?.we || AXIS.we;\n        }\n      }\n\n      if (lineChar) {\n        drawPosition({ debugMode, graph, scaledX: curr, scaledY: index, symbol: lineChar });\n      }\n    }\n  }\n};\n\n/**\n * Initializes an empty graph based on plot dimensions and a given symbol.\n * @param {Object} params - Configuration options for the graph.\n * @param {number} params.plotWidth - Width of the plot area.\n * @param {number} params.plotHeight - Height of the plot area.\n * @param {string} params.emptySymbol - Symbol used to fill empty cells.\n * @returns {Graph} - An initialized empty graph matrix.\n */\nexport const drawGraph = ({\n  plotWidth,\n  plotHeight,\n  emptySymbol,\n}: {\n  plotWidth: number;\n  plotHeight: number;\n  emptySymbol: string;\n}) => {\n  const callback = () => toEmpty(plotWidth + 2, emptySymbol);\n  return Array.from({ length: plotHeight + 2 }, callback);\n};\n\n/**\n * Renders the graph into a string format for output.\n * @param {Object} params - Configuration options for rendering the graph.\n * @param {Graph} params.graph - The graph matrix to render.\n * @returns {string} - The rendered graph as a string.\n */\nexport const drawChart = ({ graph }: { graph: Graph }) =>\n  `\\n${graph.map((line) => line.join('')).join('\\n')}\\n`;\n\n/**\n * Renders a custom line on the graph based on formatter specifications.\n * @param {Object} params - Configuration options for rendering custom lines.\n * @param {Point[]} params.sortedCoords - Sorted list of coordinates.\n * @param {number} params.scaledX - X-axis scaling.\n * @param {number} params.scaledY - Y-axis scaling.\n * @param {number} params.minY - Minimum Y value.\n * @param {number} params.minX - Minimum X value.\n * @param {MultiLine} params.input - Input data points.\n * @param {number[]} params.expansionX - X-axis expansion range.\n * @param {number[]} params.expansionY - Y-axis expansion range.\n * @param {function} params.toPlotCoordinates - Function to convert coordinates to plot positions.\n * @param {number} params.index - Current index in the coordinate array.\n * @param {function} params.lineFormatter - Custom function for line formatting.\n * @param {Graph} params.graph - The graph matrix to modify.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const drawCustomLine = ({\n  sortedCoords,\n  scaledX,\n  scaledY,\n  input,\n  index,\n  lineFormatter,\n  graph,\n  toPlotCoordinates,\n  expansionX,\n  expansionY,\n  minY,\n  minX,\n  debugMode,\n}: {\n  sortedCoords: Point[];\n  scaledX: number;\n  scaledY: number;\n  input: MultiLine;\n  index: number;\n  minY: number;\n  minX: number;\n  expansionX: number[];\n  expansionY: number[];\n  toPlotCoordinates: (x: number, y: number) => Point;\n  lineFormatter: (args: LineFormatterArgs) => CustomSymbol | CustomSymbol[];\n  graph: Graph;\n  debugMode?: boolean;\n}) => {\n  const lineFormatterArgs = {\n    x: sortedCoords[index][0],\n    y: sortedCoords[index][1],\n    plotX: scaledX + 1,\n    plotY: scaledY + 1,\n    index,\n    input: input[0],\n    minY,\n    minX,\n    toPlotCoordinates,\n    expansionX,\n    expansionY,\n  };\n  const customSymbols = lineFormatter(lineFormatterArgs);\n  if (Array.isArray(customSymbols)) {\n    customSymbols.forEach(({ x: symbolX, y: symbolY, symbol }: CustomSymbol) => {\n      drawPosition({ debugMode, graph, scaledX: symbolX, scaledY: symbolY, symbol });\n    });\n  } else {\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: customSymbols.x,\n      scaledY: customSymbols.y,\n      symbol: customSymbols.symbol,\n    });\n  }\n};\n\n/**\n * Renders a line between two points on the graph using defined chart symbols.\n * @param {Object} params - Configuration options for drawing a line.\n * @param {number} params.index - Current index in the coordinate array.\n * @param {Point[]} params.arr - List of points for the line.\n * @param {Graph} params.graph - The graph matrix to modify.\n * @param {number} params.scaledX - X-axis scaling.\n * @param {number} params.scaledY - Y-axis scaling.\n * @param {number} params.plotHeight - Height of the plot area.\n * @param {string} params.emptySymbol - Symbol used to fill empty cells.\n * @param {Object} params.axis - Axis position.\n * @param {Symbols['chart']} params.chartSymbols - Symbols used for chart rendering.\n * @param {MaybePoint} params.axisCenter - Axis position selected by user.\n * @param {number} params.axis.x - X-position of the Y-axis on the graph.\n * @param {number} params.axis.y - Y-position of the X-axis on the graph.\n * @param {string} params.mode - Graph mode (e.g., 'line', 'point').\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const drawLine = ({\n  index,\n  arr,\n  graph,\n  scaledX,\n  scaledY,\n  plotHeight,\n  emptySymbol,\n  chartSymbols,\n  axisCenter,\n  debugMode,\n  axis,\n  mode,\n}: {\n  index: number;\n  arr: Point[];\n  graph: Graph;\n  scaledX: number;\n  scaledY: number;\n  plotHeight: number;\n  emptySymbol: string;\n  chartSymbols: Symbols['chart'];\n  axisCenter: MaybePoint;\n  axis: { x: number; y: number };\n  debugMode?: boolean;\n  mode: GraphMode;\n}) => {\n  const [currX, currY] = arr[index];\n  if (mode === 'bar' || mode === 'horizontalBar') {\n    const positions: [number, number][] = [];\n    const axisCenterShift = axisCenter ? 0 : 1;\n    // For vertical bar chart\n    if (mode === 'bar') {\n      let i;\n      // Check if the value is positive or negative\n      if (scaledY >= axis.y) {\n        // For positive values, draw from the value down to the axis\n        i = scaledY;\n        while (i >= axis.y) {\n          positions.push([i, scaledX + axisCenterShift]);\n          i -= 1;\n        }\n      } else {\n        // For negative values, draw from the value up to the axis\n        i = scaledY;\n        while (i <= axis.y) {\n          positions.push([i, scaledX + axisCenterShift]);\n          i += 1;\n        }\n      }\n    }\n\n    // For horizontal bar chart\n    if (mode === 'horizontalBar') {\n      let i;\n      if (scaledX >= axis.x) {\n        // For positive values, draw rightward from the value to the axis\n        i = scaledX;\n        while (i >= axis.x) {\n          positions.push([scaledY + 1, i]);\n          i -= 1;\n        }\n      } else {\n        // For negative values, draw leftward from the value to the axis\n        i = scaledX;\n        while (i <= axis.x) {\n          positions.push([scaledY + 1, i]);\n          i += 1;\n        }\n      }\n    }\n\n    // Draw all calculated positions\n    positions.forEach(([y, x]) => {\n      drawPosition({\n        debugMode,\n        graph,\n        scaledX: x,\n        scaledY: y,\n        symbol: chartSymbols?.area || CHART.area,\n      });\n    });\n\n    return;\n  }\n\n  if (mode === 'point') {\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: scaledX + 1,\n      scaledY: scaledY + 1,\n      symbol: POINT,\n    });\n    return;\n  }\n\n  if (index - 1 >= 0) {\n    const [prevX, prevY] = arr[index - 1];\n    Array(distance(currY, prevY))\n      .fill('')\n      .forEach((_, steps, array) => {\n        if (Math.round(prevY) > Math.round(currY)) {\n          drawPosition({\n            debugMode,\n            graph,\n            scaledX,\n            scaledY: scaledY + 1,\n            symbol: chartSymbols?.nse || CHART.nse,\n          });\n          if (steps === array.length - 1) {\n            drawPosition({\n              debugMode,\n              graph,\n              scaledX,\n              scaledY: scaledY - steps,\n              symbol: chartSymbols?.wns || CHART.wns,\n            });\n          } else {\n            drawPosition({\n              debugMode,\n              graph,\n              scaledX,\n              scaledY: scaledY - steps,\n              symbol: chartSymbols?.ns || CHART.ns,\n            });\n          }\n        } else {\n          drawPosition({\n            debugMode,\n            graph,\n            scaledX,\n            scaledY: scaledY + steps + 2,\n            symbol: chartSymbols?.wsn || CHART.wsn,\n          });\n\n          drawPosition({\n            debugMode,\n            graph,\n            scaledX,\n            scaledY: scaledY + steps + 1,\n            symbol: chartSymbols?.ns || CHART.ns,\n          });\n        }\n      });\n\n    if (Math.round(prevY) < Math.round(currY)) {\n      drawPosition({\n        debugMode,\n        graph,\n        scaledX,\n        scaledY: scaledY + 1,\n        symbol: chartSymbols?.sne || CHART.sne,\n      });\n    } else if (Math.round(prevY) === Math.round(currY)) {\n      if (graph[scaledY + 1][scaledX] === emptySymbol) {\n        drawPosition({\n          debugMode,\n          graph,\n          scaledX,\n          scaledY: scaledY + 1,\n          symbol: chartSymbols?.we || CHART.we,\n        });\n      }\n    }\n\n    const distanceX = distance(currX, prevX);\n    Array(distanceX ? distanceX - 1 : 0)\n      .fill('')\n      .forEach((_, steps) => {\n        const thisY = plotHeight - Math.round(prevY);\n        drawPosition({\n          debugMode,\n          graph,\n          scaledX: Math.round(prevX) + steps + 1,\n          scaledY: thisY,\n          symbol: chartSymbols?.we || CHART.we,\n        });\n      });\n  }\n\n  if (arr.length - 1 === index) {\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: scaledX + 1,\n      scaledY: scaledY + 1,\n      symbol: chartSymbols?.we || CHART.we,\n    });\n  }\n};\n\n/**\n * Applies shifts to the graph and adjusts empty symbols and scaling factors.\n * @param {Object} params - Configuration options for applying shifts.\n * @param {Graph} params.graph - The graph matrix.\n * @param {number} params.plotWidth - The width of the plot area.\n * @param {string} params.emptySymbol - The symbol used to fill empty cells.\n * @param {number[][]} params.scaledCoords - Scaled coordinates for shifting.\n * @param {number} params.xShift - X-axis shift offset.\n * @param {number} params.yShift - Y-axis shift offset.\n * @returns {Object} - An object indicating if the graph needs to be moved.\n */\nexport const drawShift = ({\n  graph,\n  plotWidth,\n  emptySymbol,\n  scaledCoords,\n  xShift,\n  yShift,\n}: {\n  graph: Graph;\n  plotWidth: number;\n  emptySymbol: string;\n  scaledCoords: number[][];\n  xShift: number;\n  yShift: number;\n}) => {\n  let realYShift = 0;\n  graph.push(toEmpty(plotWidth + 2, emptySymbol)); // bottom shift\n  realYShift += 1;\n\n  let step = plotWidth;\n  scaledCoords.forEach(([x], index) => {\n    if (scaledCoords[index - 1]) {\n      const current = x - scaledCoords[index - 1][0];\n      step = current <= step ? current : step;\n    }\n  });\n\n  const hasToBeMoved = step < xShift;\n  if (hasToBeMoved) {\n    realYShift += 1;\n    graph.push(toEmpty(plotWidth + 1, emptySymbol));\n  }\n\n  const realXShift = yShift + 1;\n\n  graph.forEach((line) => {\n    for (let i = 0; i <= yShift; i++) {\n      line.unshift(emptySymbol);\n    }\n  });\n\n  return { hasToBeMoved, realYShift, realXShift };\n};\n\n/**\n * Draws ticks on the Y-axis based on axis configurations and scaling.\n * @param {Object} params - Configuration options for drawing the Y-axis ticks.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n * @param {boolean} [params.showTickLabel] - If true, shows tick labels for all points.\n * @param {boolean} [params.hideYAxisTicks] - If true, hides the Y-axis ticks.\n * @param {number} params.plotHeight - The height of the plot area.\n * @param {Graph} params.graph - The graph matrix.\n * @param {number} params.plotWidth - The width of the plot area.\n * @param {number} params.yShift - Shift applied to the Y-axis.\n * @param {Object} params.axis - Object defining the axis position.\n * @param {number} params.axis.x - X-position of the Y-axis on the graph.\n * @param {number} params.axis.y - Y-position of the X-axis on the graph.\n * @param {function} params.transformLabel - Function to format the label for the ticks.\n * @param {Symbols['axis']} params.axisSymbols - Symbols used for axis rendering.\n * @param {number[]} params.expansionX - X-axis expansion range.\n * @param {number[]} params.expansionY - Y-axis expansion range.\n * @returns {Void} - Applies the drawing of Y-axis ticks.\n */\nexport const getDrawYAxisTicks =\n  ({\n    debugMode,\n    showTickLabel,\n    hideYAxisTicks,\n    plotHeight,\n    graph,\n    plotWidth,\n    yShift,\n    axis,\n    transformLabel,\n    axisSymbols,\n    expansionX,\n    expansionY,\n  }: {\n    debugMode?: boolean;\n    showTickLabel?: boolean;\n    hideYAxisTicks?: boolean;\n    plotHeight: number;\n    graph: Graph;\n    plotWidth: number;\n    yShift: number;\n    axis: { x: number; y: number };\n    transformLabel: Formatter;\n    axisSymbols: Symbols['axis'];\n    expansionX: number[];\n    expansionY: number[];\n  }) =>\n  (points: Point[]) => {\n    const coords = getPlotCoords(points, plotWidth, plotHeight, expansionX, expansionY);\n    points.forEach(([_, pointY], i) => {\n      const [x, y] = coords[i];\n      const [, scaledY] = toPlot(plotWidth, plotHeight)(x, y);\n      drawYAxisEnd({\n        debugMode,\n        showTickLabel,\n        hideYAxisTicks,\n        plotHeight,\n        graph,\n        scaledY,\n        yShift,\n        axis,\n        pointY,\n        transformLabel,\n        axisSymbols,\n        expansionX,\n        expansionY,\n      });\n    });\n  };\n\n/**\n * Draws ticks on the X-axis based on axis configurations and scaling.\n * @param {Object} params - Configuration options for drawing the X-axis ticks.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n * @param {boolean} [params.hideXAxisTicks] - If true, hides the X-axis ticks.\n * @param {number} params.plotWidth - The width of the plot area.\n * @param {number} params.plotHeight - The height of the plot area.\n * @param {number} params.yShift - Shift applied to the Y-axis.\n * @param {Graph} params.graph - The graph matrix.\n * @param {MaybePoint} [params.axisCenter] - Optional axis center coordinates.\n * @param {string} params.emptySymbol - Symbol used to fill empty cells.\n * @param {Point[]} params.points - List of points for the X-axis.\n * @param {Symbols['axis']} params.axisSymbols - Symbols used for axis rendering.\n * @param {boolean} [params.hasToBeMoved] - If true, indicates that the graph needs to be moved.\n * @param {Object} params.axis - Object defining the axis position.\n * @param {number} params.axis.x - X-position of the Y-axis on the graph.\n * @param {number} params.axis.y - Y-position of the X-axis on the graph.\n * @param {function} params.transformLabel - Function to format the label for the ticks.\n * @param {number[]} params.expansionX - X-axis expansion range.\n * @param {number[]} params.expansionY - Y-axis expansion range.\n * @param {boolean} [params.hideXAxis] - If true, hides the X-axis.\n * @returns {Void} - Applies the drawing of X-axis ticks.\n */\nexport const getDrawXAxisTicks =\n  ({\n    debugMode,\n    hideXAxisTicks,\n    plotWidth,\n    plotHeight,\n    yShift,\n    graph,\n    axisCenter,\n    emptySymbol,\n    axisSymbols,\n    axis,\n    transformLabel,\n    expansionX,\n    expansionY,\n  }: {\n    debugMode?: boolean;\n    hideXAxisTicks?: boolean;\n    plotWidth: number;\n    plotHeight: number;\n    emptySymbol: string;\n    yShift: number;\n    graph: Graph;\n    axisCenter?: MaybePoint;\n    axis: { x: number; y: number };\n    transformLabel: Formatter;\n    axisSymbols: typeof AXIS;\n    expansionX: number[];\n    expansionY: number[];\n  }) => {\n    const occupiedByRow = new Map<number, Set<number>>();\n\n    const getOccupiedRow = (row: number) => {\n      if (!occupiedByRow.has(row)) {\n        occupiedByRow.set(row, new Set<number>());\n      }\n      return occupiedByRow.get(row)!;\n    };\n\n    return (points: Point[]) => {\n      const coords = getPlotCoords(points, plotWidth, plotHeight, expansionX, expansionY);\n      points.forEach(([pointX], i) => {\n        const [x, y] = coords[i];\n        const [scaledX] = toPlot(plotWidth, plotHeight)(x, y);\n        const pointXShift = toArray(\n          transformLabel(pointX, { axis: 'x', xRange: expansionX, yRange: expansionY }),\n        );\n        const yPos = axisCenter ? axis.y + 1 : graph.length - 1;\n\n        const tickXPosition = scaledX + yShift + (axisCenter ? 1 : 2);\n\n        const hasPlaceToRender = pointXShift.every((_, j) =>\n          [emptySymbol, axisSymbols.ns].includes(graph[yPos - 1][scaledX + yShift - j + 2]),\n        );\n\n        const targetY = hasPlaceToRender ? yPos - 1 : yPos;\n        const occupied = getOccupiedRow(targetY);\n        const targetWidth = graph[targetY]?.length ?? 1;\n\n        const hasLabelCollision =\n          !axisCenter &&\n          pointXShift.some((_, j) => {\n            const rawX = scaledX + yShift - j + 2;\n            const graphX = Math.max(0, Math.min(targetWidth - 1, rawX));\n            return occupied.has(graphX);\n          });\n\n        if (!hasLabelCollision) {\n          for (let j = 0; j < pointXShift.length; j++) {\n            const isOccupied = graph[yPos - 2][tickXPosition] === axisSymbols.x;\n\n            if (isOccupied) break;\n\n            drawXAxisEnd({\n              debugMode,\n              hasPlaceToRender,\n              yPos,\n              graph,\n              axisCenter,\n              yShift,\n              i: j,\n              scaledX,\n              hideXAxisTicks,\n              pointXShift,\n            });\n          }\n\n          for (let j = 0; j < pointXShift.length; j++) {\n            if (axisCenter) {\n              break;\n            }\n            const rawX = scaledX + yShift - j + 2;\n            const graphX = Math.max(0, Math.min(targetWidth - 1, rawX));\n            occupied.add(graphX);\n          }\n        }\n\n        drawXAxisTick({\n          debugMode,\n          axis,\n          xPosition: tickXPosition,\n          graph,\n          hideXAxisTicks,\n          axisSymbols,\n        });\n      });\n    };\n  };\n\n/**\n * Draws ticks on the graph based on the provided configuration.\n * @param {Object} params - Configuration options for drawing ticks.\n * @param {MultiLine} params.input - Input data points.\n * @param {Graph} params.graph - The graph matrix.\n * @param {number} params.plotWidth - The width of the plot area.\n * @param {number} params.plotHeight - The height of the plot area.\n * @param {Object} params.axis - Object defining the axis position.\n * @param {number} params.axis.x - X-position of the Y-axis on the graph.\n * @param {number} params.axis.y - Y-position of the X-axis on the graph.\n * @param {MaybePoint} [params.axisCenter] - Optional axis center coordinates.\n * @param {number} params.yShift - Shift applied to the Y-axis.\n * @param {string} params.emptySymbol - Symbol used to fill empty cells.\n * @param {boolean} [params.debugMode=false] - If true, logs errors for out-of-bounds access.\n * @param {boolean} [params.hideXAxis] - If true, hides the X-axis.\n * @param {boolean} [params.hideYAxis] - If true, hides the Y-axis.\n * @param {number[]} params.expansionX - X-axis expansion range.\n * @param {number[]} params.expansionY - Y-axis expansion range.\n * @param {number[]} [params.customYAxisTicks] - Custom Y-axis ticks.\n * @param {number[]} [params.customXAxisTicks] - Custom X-axis ticks.\n * @param {boolean} [params.hideYAxisTicks] - If true, hides Y-axis ticks.\n * @param {boolean} [params.hideXAxisTicks] - If true, hides X-axis ticks.\n * @param {boolean} [params.showTickLabel] - If true, displays tick labels for all points.\n * @param {function} params.transformLabel - Function to format the label for the ticks.\n * @param {Symbols['axis']} params.axisSymbols - Symbols used for axis rendering.\n * @param {boolean} [params.hasToBeMoved] - If true, indicates that the graph needs to be moved.\n */\nexport const drawTicks = ({\n  input,\n  graph,\n  plotWidth,\n  plotHeight,\n  axis,\n  axisCenter,\n  yShift,\n  emptySymbol,\n  debugMode,\n  hideXAxis,\n  expansionX,\n  expansionY,\n  hideYAxis,\n  customYAxisTicks,\n  customXAxisTicks,\n  hideYAxisTicks,\n  hideXAxisTicks,\n  showTickLabel,\n  axisSymbols,\n  transformLabel,\n}: {\n  input: MultiLine;\n  graph: Graph;\n  plotWidth: number;\n  plotHeight: number;\n  axis: { x: number; y: number };\n  axisCenter?: MaybePoint;\n  yShift: number;\n  emptySymbol: string;\n  axisSymbols: typeof AXIS;\n  hideYAxis?: boolean;\n  hideXAxis?: boolean;\n  debugMode?: boolean;\n  expansionX: number[];\n  expansionY: number[];\n  customYAxisTicks?: number[];\n  customXAxisTicks?: number[];\n  hideYAxisTicks?: boolean;\n  hideXAxisTicks?: boolean;\n  showTickLabel?: boolean;\n  transformLabel: Formatter;\n}) => {\n  const [minY, maxY] = [Math.min(...expansionY), Math.max(...expansionY)];\n  const [minX, maxX] = [Math.min(...expansionX), Math.max(...expansionX)];\n\n  // draw ticks\n  const drawYAxisTicks = getDrawYAxisTicks({\n    axis,\n    axisSymbols,\n    debugMode,\n    expansionX,\n    expansionY,\n    graph,\n    hideYAxisTicks,\n    plotHeight,\n    plotWidth,\n    showTickLabel,\n    transformLabel,\n    yShift,\n  });\n\n  const drawXAxisTicks = getDrawXAxisTicks({\n    axis,\n    axisCenter,\n    axisSymbols,\n    debugMode,\n    emptySymbol,\n    expansionX,\n    expansionY,\n    graph,\n    hideXAxisTicks,\n    plotHeight,\n    plotWidth,\n    transformLabel,\n    yShift,\n  });\n\n  // Main ticks logic\n  input.forEach((line) => {\n    line.forEach(([pointX, pointY]) => {\n      if (!hideYAxis && !customYAxisTicks) {\n        drawYAxisTicks([[pointX, pointY]]);\n      }\n\n      if (!hideXAxis && !customXAxisTicks) {\n        drawXAxisTicks([[pointX, pointY]]);\n      }\n    });\n  });\n\n  // if outside the bounds, do not draw\n  const filteredCustomYAxisTicks = (customYAxisTicks || []).filter((y) => y >= minY && y <= maxY);\n  const filteredCustomXAxisTicks = (customXAxisTicks || []).filter((x) => x >= minX && x <= maxX);\n\n  if (filteredCustomYAxisTicks.length && !hideYAxis) {\n    drawYAxisTicks(filteredCustomYAxisTicks.map((y) => toPoint(undefined, y)));\n  }\n\n  if (filteredCustomXAxisTicks.length && !hideXAxis) {\n    drawXAxisTicks(filteredCustomXAxisTicks.map((x) => toPoint(x)));\n  }\n};\n\nexport const drawAxisCenter = ({\n  graph,\n  realXShift,\n  axis,\n  debugMode,\n  axisSymbols,\n  emptySymbol,\n  backgroundSymbol,\n}: {\n  graph: Graph;\n  axis: { x: number; y: number };\n  realXShift: number;\n  axisSymbols: typeof AXIS;\n  debugMode?: boolean;\n  emptySymbol: string;\n  backgroundSymbol: string;\n}) => {\n  const positionX = axis.x + realXShift;\n  const positionY = axis.y;\n\n  graph.forEach((line, indexY) => {\n    line.forEach((_, indexX) => {\n      if (indexX === positionX && indexY === positionY) {\n        let symbol = axisSymbols.nse;\n\n        const get = (x: number, y: number) => graph[y]?.[x];\n\n        const isEmpty = (value: string) =>\n          !Object.values(axisSymbols).includes(value) ||\n          value === backgroundSymbol ||\n          value === emptySymbol;\n\n        const emptyOnLeft = isEmpty(get(indexX - 1, indexY));\n        const emptyOnBottom = isEmpty(get(indexX, indexY + 1));\n        const emptyOnRight = isEmpty(get(indexX + 1, indexY));\n        const emptyOnTop = isEmpty(get(indexX, indexY - 1));\n\n        if (emptyOnLeft && emptyOnRight && !emptyOnBottom && !emptyOnTop) {\n          symbol = axisSymbols.ns;\n        } else if (emptyOnLeft && !emptyOnTop && !emptyOnBottom && !emptyOnRight) {\n          symbol = axisSymbols.intersectionY;\n        } else if (!emptyOnBottom && !emptyOnLeft && !emptyOnTop && !emptyOnRight) {\n          symbol = axisSymbols.intersectionXY;\n        } else if (emptyOnLeft && emptyOnTop && !emptyOnRight && emptyOnBottom) {\n          symbol = axisSymbols.we;\n        } else if (emptyOnLeft && emptyOnBottom && emptyOnRight && !emptyOnTop) {\n          symbol = axisSymbols.ns;\n        }\n\n        // empty on all sides, do not draw\n        if (emptyOnBottom && emptyOnLeft && emptyOnRight && emptyOnTop) {\n          return;\n        }\n\n        drawPosition({\n          graph,\n          scaledX: indexX,\n          scaledY: indexY,\n          symbol,\n          debugMode,\n        });\n      }\n    });\n  });\n};\n","import { CHART, THRESHOLDS } from '../constants';\nimport {\n  Colors,\n  Formatter,\n  Graph,\n  Legend,\n  MultiLine,\n  Point,\n  Symbols,\n  Threshold,\n  FormatterHelpers,\n  GraphPoint,\n} from '../types';\nimport { getPlotCoords, toArray, toEmpty, toPlot, normalize } from './coords';\nimport { drawPosition } from './draw';\nimport { defaultFormatter, getAnsiColor, getChartSymbols } from './settings';\n\n/**\n * Adds a title to the graph at the top.\n * @param {object} options - Object containing title options.\n * @param {string} options.title - The title text.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {string} options.backgroundSymbol - Background symbol for the graph.\n * @param {number} options.plotWidth - Width of the plot.\n * @param {number} options.yShift - Vertical shift for positioning.\n * @param {boolean} [options.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const setTitle = ({\n  title,\n  graph,\n  backgroundSymbol,\n  plotWidth,\n  yShift,\n  debugMode,\n}: {\n  title: string;\n  graph: Graph;\n  backgroundSymbol: string;\n  plotWidth: number;\n  yShift: number;\n  debugMode?: boolean;\n}) => {\n  graph.unshift(toEmpty(plotWidth + yShift + 2, backgroundSymbol));\n  for (let index = 0; index < title.length; index++) {\n    const letter = title[index];\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: index,\n      scaledY: 0,\n      symbol: letter,\n    });\n  }\n};\n\n/**\n * Adds an x-axis label centered at the bottom of the graph.\n * @param {object} options - Object containing x-label options.\n * @param {string} options.xLabel - The x-axis label text.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {string} options.backgroundSymbol - Background symbol for the graph.\n * @param {number} options.plotWidth - Width of the plot.\n * @param {number} options.yShift - Vertical shift for positioning.\n * @param {boolean} [options.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const addXLabel = ({\n  graph,\n  plotWidth,\n  yShift,\n  backgroundSymbol,\n  xLabel,\n  debugMode,\n}: {\n  xLabel: string;\n  graph: Graph;\n  backgroundSymbol: string;\n  plotWidth: number;\n  yShift: number;\n  debugMode?: boolean;\n}) => {\n  const totalWidth = graph[0].length;\n  const labelLength = toArray(xLabel).length;\n  const startingPosition = Math.round((totalWidth - labelLength) / 2);\n\n  graph.push(toEmpty(plotWidth + yShift + 2, backgroundSymbol));\n  for (let index = 0; index < xLabel.length; index++) {\n    const letter = xLabel[index];\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: startingPosition + index,\n      scaledY: graph.length - 1,\n      symbol: letter,\n    });\n  }\n};\n\n/**\n * Adds a y-axis label centered on the left side of the graph.\n * @param {object} options - Object containing y-label options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {string} options.backgroundSymbol - Background symbol for the graph.\n * @param {string} options.yLabel - The y-axis label text.\n * @param {boolean} [options.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const addYLabel = ({\n  graph,\n  backgroundSymbol,\n  yLabel,\n  debugMode,\n}: {\n  graph: Graph;\n  backgroundSymbol: string;\n  yLabel: string;\n  debugMode?: boolean;\n}) => {\n  const totalHeight = graph.length;\n  const labelLength = toArray(yLabel).length;\n  const startingPosition = Math.round((totalHeight - labelLength) / 2) - 1;\n\n  const label = Array.from(yLabel);\n  graph.forEach((line, position) => {\n    line.unshift(backgroundSymbol);\n    if (position > startingPosition && label[position - startingPosition - 1]) {\n      drawPosition({\n        debugMode,\n        graph,\n        scaledX: 0,\n        scaledY: position,\n        symbol: label[position - startingPosition - 1],\n      });\n    }\n  });\n};\n\n/**\n * Adds a legend to the specified position on the graph (top, bottom, left, or right).\n * @param {object} options - Object containing legend options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {Legend} options.legend - Configuration for the legend's position and series.\n * @param {string} options.backgroundSymbol - Background symbol for the graph.\n * @param {MultiLine} options.input - Input data series for the chart.\n * @param {string} options.pointSymbol - Symbol used to draw points.\n * @param {GraphPoint[]} [options.points] - Points to render, with optional colors.\n * @param {Threshold[]} [options.thresholds] - Thresholds for the plot.\n * @param {Colors} [options.color] - Color(s) for each series.\n * @param {Symbols} [options.symbols] - Custom symbols for the chart.\n * @param {boolean} [options.fillArea] - Whether to fill the area below the lines.\n * @param {boolean} [options.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const addLegend = ({\n  graph,\n  legend,\n  backgroundSymbol,\n  color,\n  symbols,\n  fillArea,\n  input,\n  pointSymbol,\n  debugMode,\n  points,\n  thresholds,\n}: {\n  graph: Graph;\n  legend: Legend;\n  backgroundSymbol: string;\n  input: MultiLine;\n  color?: Colors;\n  pointSymbol: string;\n  symbols?: Symbols;\n  fillArea?: boolean;\n  debugMode?: boolean;\n  points?: GraphPoint[];\n  thresholds?: Threshold[];\n}) => {\n  // Process legend data directly without using getLegendData to avoid trimming\n  // This preserves all legend items regardless of input data length\n  const legendSeries = legend.series ? normalize(legend.series) : [];\n  const legendPoints = legend.points ? normalize(legend.points) : [];\n  const legendThresholds = legend.thresholds ? normalize(legend.thresholds) : [];\n\n  const allLabels = [\n    ...legendSeries.map((label: string, i: number) => ({\n      type: 'series' as const,\n      label,\n      index: i,\n    })),\n    ...(legendThresholds.length > 0 ? [{ type: 'spacer' as const }] : []),\n    ...legendThresholds.map((label: string, i: number) => ({\n      type: 'threshold' as const,\n      label,\n      index: i,\n    })),\n    ...(legendPoints.length > 0 ? [{ type: 'spacer' as const }] : []),\n    ...legendPoints.map((label: string, i: number) => ({\n      type: 'point' as const,\n      label,\n      index: i,\n    })),\n  ];\n\n  const legendWidth =\n    2 +\n    Math.max(\n      ...allLabels.map((entry) => {\n        if (entry.type === 'spacer') return 0;\n        return toArray(entry.label).length;\n      }),\n    );\n\n  const makePointSymbol = (index: number) =>\n    points && points[index]?.color\n      ? `${getAnsiColor(points[index].color)}${pointSymbol}\\u001b[0m`\n      : pointSymbol;\n\n  const makeThresholdSymbol = (index: number) =>\n    thresholds && thresholds[index]?.color\n      ? `${getAnsiColor(thresholds[index].color)}┃\\u001b[0m`\n      : '┃';\n\n  const makeLabelRow = (entry: (typeof allLabels)[number]) => {\n    if (entry.type === 'spacer') return Array(legendWidth).fill(backgroundSymbol);\n\n    const { label } = entry;\n    const labelText = toArray(label);\n    const pad = legendWidth - labelText.length - 2;\n    const padArr = Array(pad).fill(backgroundSymbol);\n\n    let symbol: string;\n    if (entry.type === 'point') symbol = makePointSymbol(entry.index);\n    else if (entry.type === 'threshold') symbol = makeThresholdSymbol(entry.index);\n    else symbol = getChartSymbols(color, entry.index, symbols?.chart, input, fillArea).area;\n\n    return [symbol, backgroundSymbol, ...labelText, ...padArr];\n  };\n\n  if (legend.position === 'left') {\n    const newRows = allLabels.map(makeLabelRow);\n    for (let i = 0; i < graph.length; i++) {\n      const label = newRows[i];\n      if (label) {\n        for (let j = legendWidth - 1; j >= 0; j--) {\n          graph[i].unshift(label[j]);\n        }\n      } else {\n        for (let j = 0; j < legendWidth; j++) {\n          graph[i].unshift(backgroundSymbol);\n        }\n      }\n    }\n  }\n\n  if (legend.position === 'right') {\n    // Pre-pad each row with empty space on the right so chart rendering doesn't overwrite legend\n    for (let row of graph) {\n      for (let i = 0; i < legendWidth + 2; i++) {\n        row.push(backgroundSymbol);\n      }\n    }\n\n    const newRows = allLabels.map(makeLabelRow);\n    for (let i = 0; i < graph.length; i++) {\n      const label = newRows[i];\n      if (label) {\n        for (let j = 0; j < legendWidth; j++) {\n          const columnIndex = graph[i].length - legendWidth + j;\n          graph[i][columnIndex] = label[j];\n        }\n      }\n    }\n  }\n\n  if (legend.position === 'top') {\n    allLabels;\n    const reversedEntries = allLabels.slice().reverse();\n\n    for (let entryIndex = 0; entryIndex < reversedEntries.length; entryIndex++) {\n      const entry = reversedEntries[entryIndex];\n      const line = makeLabelRow(entry);\n      const row = toEmpty(graph[0].length, backgroundSymbol);\n      graph.unshift(row);\n\n      for (let i = 0; i < line.length; i++) {\n        const symbol = line[i];\n        drawPosition({\n          debugMode,\n          graph,\n          scaledX: i,\n          scaledY: 0,\n          symbol,\n        });\n      }\n    }\n  }\n\n  if (legend.position === 'bottom' || !legend.position) {\n    for (let entryIndex = 0; entryIndex < allLabels.length; entryIndex++) {\n      const entry = allLabels[entryIndex];\n      const line = makeLabelRow(entry);\n      graph.push(toEmpty(graph[0].length, backgroundSymbol));\n      const y = graph.length - 1;\n      for (let i = 0; i < line.length; i++) {\n        const symbol = line[i];\n        drawPosition({\n          debugMode,\n          graph,\n          scaledX: i,\n          scaledY: y,\n          symbol,\n        });\n      }\n    }\n  }\n};\n\n/**\n * Adds a border around the graph.\n * @param {object} options - Object containing border options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {string} options.backgroundSymbol - The symbol to use for the background.\n * @param {string} options.borderSymbol - The symbol to use for the border.\n */\nexport const addBorder = ({\n  graph,\n  borderSymbol,\n  backgroundSymbol,\n}: {\n  graph: Graph;\n  borderSymbol: string;\n  backgroundSymbol: string;\n}) => {\n  const maxLength = Math.max(...graph.map((line) => line.length));\n  graph.forEach((line) => {\n    while (line.length < maxLength) line.push(backgroundSymbol);\n    line.unshift(borderSymbol);\n    line.push(borderSymbol);\n  });\n  graph.unshift(toEmpty(graph[0].length, borderSymbol));\n  graph.push(toEmpty(graph[0].length, borderSymbol));\n};\n\n/**\n * Fills the background of empty cells in the graph with a specified symbol.\n * @param {object} options - Object containing background fill options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {string} options.backgroundSymbol - Symbol to fill empty cells with.\n * @param {string} options.emptySymbol - Symbol representing empty cells.\n * @param {boolean} [options.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const addBackgroundSymbol = ({\n  graph,\n  backgroundSymbol,\n  emptySymbol,\n  debugMode,\n}: {\n  graph: Graph;\n  backgroundSymbol: string;\n  emptySymbol: string;\n  debugMode?: boolean;\n}) => {\n  graph.forEach((line, curr) => {\n    for (let index = 0; index < line.length; index += 1) {\n      if (line[index] === emptySymbol) {\n        drawPosition({\n          debugMode,\n          graph,\n          scaledX: index,\n          scaledY: curr,\n          symbol: backgroundSymbol,\n        });\n      } else break;\n    }\n  });\n};\n\n/**\n * Adds points to the graph at specified (x, y) coordinates.\n *\n * @param {object} options - Configuration options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {GraphPoint[]} options.points - Points to render, with optional colors.\n * @param {number} options.plotWidth - Width of the plot.\n * @param {number} options.plotHeight - Height of the plot.\n * @param {number[]} options.expansionX - Range of x-values for scaling.\n * @param {number[]} options.expansionY - Range of y-values for scaling.\n * @param {string} options.pointSymbol - Symbol used to draw the point.\n * @param {boolean} [options.debugMode] - Enables debug logging.\n */\nexport const addPoints = ({\n  graph,\n  points,\n  plotWidth,\n  plotHeight,\n  expansionX,\n  expansionY,\n  pointSymbol,\n  debugMode,\n}: {\n  graph: Graph;\n  points: GraphPoint[];\n  plotWidth: number;\n  plotHeight: number;\n  expansionX: number[];\n  expansionY: number[];\n  pointSymbol: string;\n  debugMode?: boolean;\n}) => {\n  const mappedPoints = points.map(({ x, y }) => [x, y] as Point);\n\n  const plotCoords = getPlotCoords(mappedPoints, plotWidth, plotHeight, expansionX, expansionY);\n  for (let pointNumber = 0; pointNumber < plotCoords.length; pointNumber++) {\n    const [x, y] = plotCoords[pointNumber];\n    const [scaledX, scaledY] = toPlot(plotWidth, plotHeight)(x, y);\n    const pointColor = points[pointNumber]?.color;\n\n    drawPosition({\n      debugMode,\n      graph,\n      scaledX: scaledX + 1,\n      scaledY: scaledY + 1,\n      symbol: pointColor ? `${getAnsiColor(pointColor)}${pointSymbol}\\u001b[0m` : pointSymbol,\n    });\n  }\n};\n\n/**\n * Draws threshold lines on the graph at specified x and/or y coordinates.\n *\n * @param {object} options - Configuration object for threshold rendering.\n * @param {Graph} options.graph - The 2D graph matrix to modify.\n * @param {Threshold[]} options.thresholds - List of threshold definitions with x, y, and optional color.\n * @param {object} options.axis - Axis configuration defining origin point.\n * @param {number} options.axis.x - X-position of the Y-axis on the graph.\n * @param {number} options.axis.y - Y-position of the X-axis on the graph.\n * @param {number} options.plotWidth - Width of the plot area in characters.\n * @param {number} options.plotHeight - Height of the plot area in characters.\n * @param {number[]} options.expansionX - Original data range for the X-axis, used for scaling.\n * @param {number[]} options.expansionY - Original data range for the Y-axis, used for scaling.\n * @param {typeof THRESHOLDS} options.thresholdSymbols - Symbols used to draw horizontal and vertical threshold lines.\n * @param {boolean} [options.debugMode=false] - Enables debug logging for invalid coordinates or out-of-bounds access.\n */\nexport const addThresholds = ({\n  graph,\n  thresholds,\n  axis,\n  plotWidth,\n  plotHeight,\n  expansionX,\n  expansionY,\n  thresholdSymbols,\n  debugMode,\n}: {\n  graph: Graph;\n  thresholds: Threshold[];\n  axis: { x: number; y: number };\n  plotWidth: number;\n  plotHeight: number;\n  expansionX: number[];\n  expansionY: number[];\n  thresholdSymbols: typeof THRESHOLDS;\n  debugMode?: boolean;\n}) => {\n  const mappedThreshold = thresholds.map(({ x: thresholdX, y: thresholdY }) => {\n    let { x, y } = axis;\n\n    if (typeof thresholdX === 'number') {\n      x = thresholdX;\n    }\n    if (typeof thresholdY === 'number') {\n      y = thresholdY;\n    }\n    return [x, y] as Point;\n  });\n\n  const plotCoords = getPlotCoords(mappedThreshold, plotWidth, plotHeight, expansionX, expansionY);\n  for (let thresholdNumber = 0; thresholdNumber < plotCoords.length; thresholdNumber++) {\n    const [x, y] = plotCoords[thresholdNumber];\n    const [scaledX, scaledY] = toPlot(plotWidth, plotHeight)(x, y);\n\n    const hasThresholdX = typeof thresholds[thresholdNumber]?.x === 'number';\n    const hasThresholdY = typeof thresholds[thresholdNumber]?.y === 'number';\n    const thresholdColor = thresholds[thresholdNumber]?.color;\n\n    if (hasThresholdX && graph[0][scaledX]) {\n      for (let index = 0; index < graph.length; index++) {\n        if (graph[index][scaledX]) {\n          drawPosition({\n            debugMode,\n            graph,\n            scaledX: scaledX + 1,\n            scaledY: index,\n            symbol: thresholdColor\n              ? `${getAnsiColor(thresholdColor)}${thresholdSymbols.y}\\u001b[0m`\n              : thresholdSymbols.y,\n          });\n        }\n      }\n    }\n    if (hasThresholdY && graph[scaledY]) {\n      for (let index = 0; index < graph[scaledY].length; index++) {\n        if (graph[scaledY][index]) {\n          drawPosition({\n            debugMode,\n            graph,\n            scaledX: index,\n            scaledY: scaledY + 1,\n            symbol: thresholdColor\n              ? `${getAnsiColor(thresholdColor)}${thresholdSymbols.x}\\u001b[0m`\n              : thresholdSymbols.x,\n          });\n        }\n      }\n    }\n  }\n};\n\n/**\n * Fills the area below chart symbols with the specified area symbol.\n * @param {object} options - Object containing fill options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {Symbols['chart']} options.chartSymbols - Chart symbols to use for filling.\n * @param {boolean} [options.debugMode=false] - If true, logs errors for out-of-bounds access.\n */\nexport const setFillArea = ({\n  graph,\n  chartSymbols,\n  debugMode,\n}: {\n  graph: Graph;\n  chartSymbols: Symbols['chart'];\n  debugMode?: boolean;\n}) => {\n  for (let yIndex = 0; yIndex < graph.length; yIndex++) {\n    const xValues = graph[yIndex];\n    for (let xIndex = 0; xIndex < xValues.length; xIndex++) {\n      const xSymbol = xValues[xIndex];\n      let areaSymbol = chartSymbols?.area || CHART.area;\n      if (\n        xSymbol === chartSymbols?.nse ||\n        xSymbol === chartSymbols?.wsn ||\n        xSymbol === chartSymbols?.we ||\n        xSymbol === areaSymbol\n      ) {\n        if (graph[yIndex + 1]?.[xIndex]) {\n          drawPosition({\n            debugMode,\n            graph,\n            scaledX: xIndex,\n            scaledY: yIndex + 1,\n            symbol: areaSymbol,\n          });\n        }\n      }\n    }\n  }\n};\n\n/**\n * Removes any completely empty lines from the graph.\n * @param {object} options - Object containing empty line removal options.\n * @param {Graph} options.graph - The graph array to modify.\n * @param {string} options.backgroundSymbol - Background symbol for identifying empty lines.\n */\nexport const removeEmptyLines = ({\n  graph,\n  backgroundSymbol,\n}: {\n  graph: Graph;\n  backgroundSymbol: string;\n}) => {\n  const elementsToRemove: number[] = [];\n  graph.forEach((line, position) => {\n    if (line.every((symbol) => symbol === backgroundSymbol)) {\n      elementsToRemove.push(position);\n    }\n\n    if (graph.every((currentLine) => currentLine[0] === backgroundSymbol)) {\n      graph.forEach((currentLine) => currentLine.shift());\n    }\n  });\n\n  elementsToRemove.reverse().forEach((position) => {\n    graph.splice(position, 1);\n  });\n};\n\n/**\n * Returns a label transformation function using the specified formatter.\n * @param {object} options - Object containing formatter options.\n * @param {Formatter} [options.formatter] - Formatter function to apply to labels.\n * @returns {Formatter} - A formatter function for transforming labels.\n */\nexport const getTransformLabel =\n  ({ formatter }: { formatter?: Formatter }) =>\n  (value: number, helpers: FormatterHelpers) =>\n    formatter ? formatter(value, helpers) : defaultFormatter(value, helpers);\n","import { AXIS, EMPTY, POINT, THRESHOLDS, LAYOUT } from '../constants';\nimport {\n  Symbols,\n  MultiLine,\n  Formatter,\n  Coordinates,\n  GraphPoint,\n  Threshold,\n  MaybePoint,\n} from '../types';\nimport { toArrays, getMin, getMax, toArray, padOrTrim, normalize } from './coords';\n\n/**\n * Merges custom symbols with default axis symbols and defines plot symbols.\n * @param {object} options - An object containing optional custom symbols.\n * @param {Symbols} options.symbols - Custom symbols for the plot.\n * @returns {object} - Object containing the merged axis symbols, and defined symbols for empty, background, and border.\n */\nexport const getSymbols = ({ symbols }: { symbols?: Symbols }) => {\n  const emptySymbol = symbols?.empty || EMPTY;\n  return {\n    axisSymbols: { ...AXIS, ...symbols?.axis },\n    emptySymbol,\n    backgroundSymbol: symbols?.background || emptySymbol,\n    borderSymbol: symbols?.border,\n    thresholdSymbols: {\n      x: symbols?.thresholds?.x || THRESHOLDS.x,\n      y: symbols?.thresholds?.y || THRESHOLDS.y,\n    },\n    pointSymbol: symbols?.point || POINT,\n  };\n};\n\n/**\n * Determines plot size and range based on provided data and dimensions.\n * @param {object} options - An object containing input data and optional dimensions.\n * @param {MultiLine} options.input - The multiline array of points.\n * @param {number} [options.width] - Optional width of the plot.\n * @param {number} [options.height] - Optional height of the plot.\n * @param {MaybePoint} [options.axisCenter] - Optional axis center point.\n * @param {[number, number]} [options.yRange] - Optional range for the y-axis.\n * @returns {object} - Object containing min x value, plot width, plot height, and x and y expansions.\n */\nexport const getChartSize = ({\n  input,\n  width,\n  height,\n  yRange,\n  axisCenter,\n}: {\n  input: MultiLine;\n  width?: number;\n  height?: number;\n  axisCenter?: MaybePoint;\n  yRange?: [number, number];\n}) => {\n  const [inputRangeX, inputRangeY] = toArrays(input);\n\n  const rangeX = [...inputRangeX, axisCenter?.[0]].filter((v) => typeof v === 'number') as number[];\n  const rangeY = [...inputRangeY, axisCenter?.[1]].filter((v) => typeof v === 'number') as number[];\n\n  const minX = getMin(rangeX);\n  const maxX = getMax(rangeX);\n  const minY = getMin(rangeY);\n  const maxY = getMax(rangeY);\n\n  const expansionX = [minX, maxX];\n\n  const expansionY = yRange || [minY, maxY];\n\n  // Set default plot dimensions if not provided\n  const plotWidth = width || rangeX.length;\n\n  let plotHeight = Math.round(height || maxY - minY + 1);\n\n  // Adjust plot height for small value ranges if no height is provided\n  if (!height && plotHeight < LAYOUT.MIN_PLOT_HEIGHT) {\n    plotHeight = rangeY.length;\n  }\n\n  return {\n    minX,\n    minY,\n    plotWidth,\n    plotHeight,\n    expansionX,\n    expansionY,\n  };\n};\n\n/**\n * Calculates shifts for x and y labels, based on the longest label length.\n * @param {object} options - The input data and formatting options.\n * @param {MultiLine} options.input - The multiline array of points.\n * @param {Formatter} options.transformLabel - A function to transform label values.\n * @param {number[]} options.expansionX - The x-axis range.\n * @param {number[]} options.expansionY - The y-axis range.\n * @param {number} options.minX - The minimum x value for label calculation.\n * @param {boolean} [options.showTickLabel] - Flag to indicate if tick labels should be shown.\n * @returns {object} - Object containing the calculated xShift and yShift.\n */\nexport const getLabelShift = ({\n  input,\n  transformLabel,\n  expansionX,\n  expansionY,\n  minX,\n  showTickLabel,\n}: {\n  input: MultiLine;\n  transformLabel: Formatter;\n  expansionX: number[];\n  expansionY: number[];\n  minX: number;\n  showTickLabel?: boolean;\n}) => {\n  // Helper to compute the length of a formatted label\n  const getLength = (value: number, axis: 'x' | 'y'): number => {\n    const formatted = transformLabel(value, { axis, xRange: expansionX, yRange: expansionY });\n    return toArray(formatted).length;\n  };\n\n  // Combine all points into one array for iteration\n  const points = input.flat<MultiLine>();\n\n  // Determine the maximum label lengths for x and y\n  const { x: xShift, y: longestY } = points.reduce(\n    (acc, [x, y]) => ({\n      x: Math.max(acc.x, getLength(x, 'x')),\n      y: Math.max(acc.y, getLength(y, 'y')),\n    }),\n    { x: 0, y: 0 },\n  );\n\n  if (!showTickLabel) {\n    // For minimal mode, ensure space for the axis symbol and labels\n    const minXLength = getLength(minX, 'x');\n    const baseShift = Math.max(0, minXLength - LAYOUT.DEFAULT_PADDING);\n    return {\n      xShift,\n      yShift: Math.max(baseShift, longestY),\n    };\n  }\n\n  // Full mode: add extra padding for tick labels\n  return { xShift, yShift: longestY + LAYOUT.DEFAULT_Y_SHIFT_OFFSET };\n};\n\n/**\n * Normalizes raw input data into a consistent multi-line format.\n * @param {object} options - Contains the raw input data.\n * @param {Coordinates} options.rawInput - Input coordinates, either single or multi-line.\n * @returns {MultiLine} - The formatted data as a multi-line array of points.\n */\nexport const getInput = ({ rawInput }: { rawInput: Coordinates }) => {\n  let input = rawInput;\n\n  // Convert single-line data to a multi-line format if needed\n  if (typeof input[0]?.[0] === 'number') {\n    input = [rawInput] as MultiLine;\n  }\n\n  return input as MultiLine;\n};\n\n/**\n * Generates legend data based on the provided points, thresholds, and series.\n * @param {object} options - Contains points, thresholds, and series data.\n * @param {MultiLine} options.input - The input data for the plot.\n * @param {GraphPoint[]} options.points - The coordinates of the points.\n * @param {Threshold[]} options.thresholds - The thresholds for the plot.\n * @param {string[] | string} options.pointsSeries - The series names for the points.\n * @param {string[] | string} options.thresholdsSeries - The series names for the thresholds.\n * @param {string[] | string} options.dataSeries - The series names for the data.\n * @returns {object} - Object containing the series, points, and thresholds for the legend.\n */\nexport const getLegendData = ({\n  input,\n  thresholds,\n  points,\n  pointsSeries,\n  thresholdsSeries,\n  dataSeries,\n}: {\n  input: MultiLine;\n  points?: GraphPoint[];\n  thresholds?: Threshold[];\n  pointsSeries?: string[] | string;\n  thresholdsSeries?: string[] | string;\n  dataSeries?: string[] | string;\n}) => {\n  const legendSeries = dataSeries && input ? padOrTrim(normalize(dataSeries), input.length) : [];\n\n  const legendPoints =\n    pointsSeries && points ? padOrTrim(normalize(pointsSeries), points.length) : [];\n\n  const legendThresholds =\n    thresholdsSeries && thresholds ? padOrTrim(normalize(thresholdsSeries), thresholds.length) : [];\n\n  return {\n    series: legendSeries,\n    points: legendPoints,\n    thresholds: legendThresholds,\n  };\n};\n","import { getPlotCoords, toPlot, toSorted, getAxisCenter } from './coords';\nimport { getChartSymbols } from './settings';\nimport { Plot } from '../types/index';\nimport {\n  addBackgroundSymbol,\n  addBorder,\n  addLegend,\n  addThresholds,\n  addXLabel,\n  addYLabel,\n  setTitle,\n  setFillArea,\n  removeEmptyLines,\n  getTransformLabel,\n  addPoints,\n} from './overrides';\nimport { getSymbols, getChartSize, getLabelShift, getInput } from './defaults';\n\nimport {\n  drawAxis,\n  drawGraph,\n  drawChart,\n  drawCustomLine,\n  drawLine,\n  drawShift,\n  drawTicks,\n  drawAxisCenter,\n} from './draw';\n\nexport const plot: Plot = (\n  rawInput,\n  {\n    color,\n    width,\n    height,\n    yRange,\n    showTickLabel,\n    hideXAxisTicks,\n    hideYAxisTicks,\n    customXAxisTicks,\n    customYAxisTicks,\n    axisCenter,\n    formatter,\n    lineFormatter,\n    symbols,\n    title,\n    fillArea,\n    hideXAxis,\n    hideYAxis,\n    xLabel,\n    yLabel,\n    legend,\n    thresholds,\n    points,\n    debugMode,\n    mode = 'line',\n  } = {},\n) => {\n  // Multiline\n  let input = getInput({ rawInput });\n\n  // Filter out points that are outside of the yRange (if defined)\n  if (yRange) {\n    const [yMin, yMax] = yRange;\n    input = input.map((line) => line.filter(([, y]) => y >= yMin && y <= yMax));\n  }\n\n  // Empty input, return early\n  if (input.length === 0) {\n    return '';\n  }\n\n  // Proceed with the rest of your function as usual\n  const transformLabel = getTransformLabel({ formatter });\n\n  let scaledCoords = [[0, 0]];\n\n  const { minX, minY, plotWidth, plotHeight, expansionX, expansionY } = getChartSize({\n    width,\n    height,\n    input,\n    yRange,\n    axisCenter,\n  });\n  const {\n    axisSymbols,\n    emptySymbol,\n    backgroundSymbol,\n    borderSymbol,\n    thresholdSymbols,\n    pointSymbol,\n  } = getSymbols({ symbols });\n\n  // create placeholder\n  const graph = drawGraph({ plotWidth, plotHeight, emptySymbol });\n\n  const axis = getAxisCenter(axisCenter, plotWidth, plotHeight, expansionX, expansionY, [\n    0,\n    graph.length - 1,\n  ]);\n\n  // get default chart symbols\n  for (let series = 0; series < input.length; series++) {\n    const coords = input[series];\n    // override default chart symbols with colored ones\n    const chartSymbols = getChartSymbols(color, series, symbols?.chart, input, fillArea);\n\n    // sort input by the first value\n    const sortedCoords = toSorted(coords);\n\n    scaledCoords = getPlotCoords(sortedCoords, plotWidth, plotHeight, expansionX, expansionY).map(\n      ([x, y], index, arr) => {\n        const toPlotCoordinates = toPlot(plotWidth, plotHeight);\n        const [scaledX, scaledY] = toPlotCoordinates(x, y);\n        if (!lineFormatter) {\n          drawLine({\n            mode,\n            debugMode,\n            index,\n            arr,\n            graph,\n            scaledX,\n            scaledY,\n            plotHeight,\n            emptySymbol,\n            chartSymbols,\n            axis,\n            axisCenter,\n          });\n\n          // fill empty area under the line if fill area is true\n          if (fillArea) {\n            setFillArea({ graph, chartSymbols, debugMode });\n          }\n        } else {\n          drawCustomLine({\n            debugMode,\n            sortedCoords,\n            scaledX,\n            scaledY,\n            input,\n            index,\n            lineFormatter,\n            graph,\n            toPlotCoordinates,\n            expansionX,\n            expansionY,\n            minY,\n            minX,\n          });\n        }\n\n        return [scaledX, scaledY];\n      },\n    );\n  }\n\n  if (thresholds) {\n    addThresholds({\n      thresholdSymbols,\n      debugMode,\n      graph,\n      thresholds,\n      axis,\n      plotWidth,\n      plotHeight,\n      expansionX,\n      expansionY,\n    });\n  }\n\n  if (points) {\n    addPoints({\n      pointSymbol,\n      debugMode,\n      graph,\n      points,\n      plotWidth,\n      plotHeight,\n      expansionX,\n      expansionY,\n    });\n  }\n\n  // axis\n  drawAxis({\n    debugMode,\n    graph,\n    hideXAxis,\n    hideYAxis,\n    axisCenter,\n    axisSymbols,\n    axis,\n  });\n\n  // takes the longest label that needs to be rendered\n  // on the Y axis and returns it's length\n  const { xShift, yShift } = getLabelShift({\n    input,\n    transformLabel,\n    showTickLabel,\n    expansionX,\n    expansionY,\n    minX,\n  });\n\n  // shift graph\n  let { realXShift } = drawShift({\n    graph,\n    plotWidth,\n    emptySymbol,\n    scaledCoords,\n    xShift,\n    yShift,\n  });\n\n  // apply background symbol if override\n  if (backgroundSymbol) {\n    addBackgroundSymbol({ debugMode, graph, backgroundSymbol, emptySymbol });\n  }\n\n  // axis\n  drawAxisCenter({\n    realXShift,\n    debugMode,\n    emptySymbol,\n    backgroundSymbol,\n    graph,\n    axisSymbols,\n    axis,\n  });\n\n  // draw axis ends and ticks\n  drawTicks({\n    input,\n    graph,\n    plotWidth,\n    plotHeight,\n    axis,\n    axisCenter,\n    yShift,\n    emptySymbol,\n    debugMode,\n    hideXAxis,\n    expansionX,\n    expansionY,\n    hideYAxis,\n    customYAxisTicks,\n    customXAxisTicks,\n    hideYAxisTicks,\n    hideXAxisTicks,\n    showTickLabel,\n    axisSymbols,\n    transformLabel,\n  });\n\n  // Remove empty lines\n  removeEmptyLines({ graph, backgroundSymbol });\n\n  // Adds x axis label below the graph\n  if (xLabel) {\n    addXLabel({\n      debugMode,\n      xLabel,\n      graph,\n      backgroundSymbol,\n      plotWidth,\n      yShift,\n    });\n  }\n\n  // Adds x axis label below the graph\n  if (yLabel) {\n    addYLabel({\n      debugMode,\n      yLabel,\n      graph,\n      backgroundSymbol,\n    });\n  }\n\n  if (legend) {\n    addLegend({\n      points,\n      thresholds,\n      pointSymbol,\n      debugMode,\n      input,\n      graph,\n      legend,\n      backgroundSymbol,\n      color,\n      symbols,\n      fillArea,\n    });\n  }\n\n  // Adds title above the graph\n  if (title) {\n    setTitle({\n      debugMode,\n      title,\n      graph,\n      backgroundSymbol,\n      plotWidth,\n      yShift,\n    });\n  }\n\n  if (borderSymbol) {\n    addBorder({ graph, borderSymbol, backgroundSymbol });\n  }\n\n  return drawChart({ graph });\n};\n\nexport default plot;\n"],"mappings":"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","names":[]}